例如,如果我不应该使用printf(),putchar()之类的标准库函数,那么如何在屏幕上打印字符?
有没有简单的方法可以做到这一点。 我对系统调用了解不多,如果必须使用它们,该如何使用它们?
那么,有没有人可以在不使用库函数的情况下提出一种简便的打印方法呢?
为什么不能使用标准库函数? 它们是"标准"的,不是吗?
你为什么想这么做?
好吧,我想尝试一下在某种解析器中使用。如果您知道任何方式,请指教......
哇,出色的工作郝,您对我提出的第一个小程序帮助很大,我建议它运行良好,但是您错误地编写了src而不是scr,但是好了,现在我更改了它的工作方式。 所以我假设这个B8000000L是输出字符进入屏幕的地址,对吗?
@郝,如果您给出这个答案而不是评论,我会接受它作为答案。确定直到我们可以增加该scr(B8000000L)的次数。我认为会有一些限制。 请让我知道任何资源以进一步了解此地址。无论如何,gr8工作。谢谢
在标准C中,您不能这样做。在C中定义的唯一I / O是通过C标准库函数实现的。
在给定的平台上,可能有一些方法可以做到:
直接进行内核调用。您可能需要编写一些内联程序集才能执行此操作。您可以直接使用litb的write调用,而无需使用C库。抓住C库的源代码,看看它是如何完成的。
直接写入帧缓冲区。多用户操作系统通常不允许这样做(至少不进行任何库/内核调用)。
除非您正在编写自己的C库,否则我不确定为什么要这样做。
是的,谢谢你,我想做些类似的事情,谢谢你,如果你有更多的资源请给我,谢谢你
在linux中,可以使用write系统调用:
write(1,"hello\", 6); // write hello\
to stdout
如果不能完全满足要求,则可以降低一级,以一般方式调用syscall:
syscall(__NR_write, 1,"hello\", 6);
值得了解strace,您可以使用它来查看任何特定程序在运行时使用了哪些系统调用。但是请注意,对于"一些简单的解析器",几乎不需要使用原始系统调用。更好地使用c库的功能。
顺便说一句,如果您想在Windows中执行上述操作而不使用c标准库,请查找WriteFile和GetStdHandle函数。虽然不会像linux解决方案那样33t。
讨厌你,多数民众赞成在图书馆的功能。 最有可能在您的C库中。
确定,然后在Windows中,如果有人知道该怎么做,请帮忙。 请注意,这不是家庭作业问题。 我正在尝试为一些简单的解析器做
objdump -T liblibc.so.6 | grep syscall通知我syscall仍然是库函数:-D
好的,谢谢大家的回答。我在问题下方的郝先生的评论中找到了一个简单的答案。他的答案是这样的简单程序
Turbo C(DOS程序):
char far* src = (char far*) 0xB8000000L;
*src = 'M';
src += 2;
*src = 'D';
或尝试以下方法:http://en.wikipedia.org/wiki/Brainfuck :) – //郝(一个小时前)
我在Turbo C及其工作上尝试过。
我想要一个简单的解决方案,我想接受它作为正确答案,但他(郝)作为评论发表了意见,因此我将其粘贴在这里,以供其他用户代表他了解并接受。再次感谢你郝先生。
@Manoj Doubts:这个程序如何运作? 具体来说,什么是0xB8000000L?如何实现?
@Lazer:原始的IBM PC已将该地址硬编码为显示缓冲区。 显然Windows支持它以实现向后兼容。
C标准库(请参阅https://en.wikipedia.org/wiki/C_standard_library)具有一组输入和输出例程,这些例程用于读取和写入各种输入和输出资源。 C标准库通常建立在目标操作系统提供的系统服务和系统调用上,尽管在没有操作系统的嵌入式微控制器的情况下,也可以使用其他方法。
除C标准库外,还有其他常用的库,例如POSIX库(请参阅https://en.wikipedia.org/wiki/C_POSIX_library)。
我使用术语资源是因为输入请求或输出请求的目标可能是各种各样的东西。
磁盘上的文件
网络连接
好的。
控制台设备
串行通讯端口
好的。
一个传感器
打印机设备
屏幕上的一个窗口
好的。
C标准库采用的模型与Unix操作系统的模型相似,因为所有各种资源都被视为一种设备,您可以从中读取字符或字节流,并写入字符或字节流。 。
好的。
在某些情况下,这种抽象允许您忽略资源物理连接的详细信息。因此,您可以打开SATA硬盘,USB拇指驱动器或网络服务器上的文件。无论打印机是在串行通信端口,USB端口还是网络打印机上,都可以打印到打印机。
好的。
对于某些类型的资源,例如控制台设备或具有行和列且可以移动的光标的打印机,通常会在写入设备的字符中提供光标定位信息。因此,您既要输出要在控制台上打印的文本,又要输出将光标定位在要写入的位置的转义码或其他操作(例如突出显示文本)。
一种这样的控制台设备是DEC的VT100终端(请参阅https://en.wikipedia.org/wiki/VT100),该终端在输出中使用特殊的转义码来进行诸如将光标定位在屏幕上的操作。这非常方便,以至于Unix,Linux和Windows上的控制台窗口在控制台或命令窗口上使用类似的转义代码来执行类似的操作(请参阅如何使win32控制台识别ANSI / VT100转义序列?)。
C标准库为各种设备提供了标准接口,由编写该库的人员提供该库实际进行读写操作所需的基础功能。
但是,标准库确实存在字符流的限制,这是它使用或呈现给程序员的模型的一部分。这就是为什么存在其他一些库,它们不属于C标准库中用于图形用户界面和游戏的部分的原因,例如来自Microsoft,Qt以及各种其他组(例如OpenGL)的内容(请参阅https://en.wikipedia.org/wiki/ OpenGL,https://en.wikipedia.org/wiki/DirectX、https://en.wikipedia.org/wiki/Graphical_user_interface以及什么是Linux的本机GUI API?)。另请参见如何真正制作GUI?操作系统如何在屏幕上绘制窗口?
如果要绕过C标准库并直接使用操作系统I / O系统调用或服务,则可以这样做。但是,与C标准库不同,C标准库是满足C标准要求的所有编译器的标准库,操作系统的I / O服务因操作系统而异。而且某些操作系统可能有几种执行相同类型I / O的方式。例如,Windows有多种执行文件I / O的方法(请参阅https://en.wikipedia.org/wiki/Windows_API)。
在某些情况下,您可以绕过操作系统并直接与设备或资源对话。这通常是通过嵌入式应用程序完成的,并且在许多情况下是通过某些微控制器上的嵌入式应用程序完成的,没有可用的实际操作系统,因此您必须直接与设备进行交互。
微控制器上的嵌入式应用程序通常使用特定的存储器地址与传感器进行交互,以便为传感器做好准备以进行传感以及从传感器读取数据(例如温度)。传感器具有多种不同的连接方法,这要求程序员对电气设置和用于与传感器进行通信的协议(例如I2C)有所了解(请参阅https://en.wikipedia.org/wiki/I2C), 1线制(请参阅https://en.wikipedia.org/wiki/1-Wire)及其他。
在旧的MSDOS操作系统下,您可以调用BIOS例程直接与包括屏幕在内的设备进行交互。或者,如果您知道屏幕缓冲区的地址和存储区的正确格式,则可以通过直接写入屏幕帧缓冲区所在的存储区来修改屏幕上显示的内容。
现代的多线程和多处理操作系统在其系统调用中具有复杂的功能,以处理所有试图使用相同设备和资源的多个应用程序可能引起的各种同步和协调问题。由于C标准库是建立在这些操作系统服务之上的,因此,当您使用C标准库时,会获得诸如文件锁定之类的复杂功能。通过标准库使用操作系统服务,您将获得完成仅可以使用的工作的专家的专业知识和知识。
现代操作系统提供了多种服务,例如文件I / O,网络I / O,打印服务等。C标准库以及其他组(例如POSIX)的其他库提供了一种标准的可移植方式来访问这些服务 。
而且,当C标准库和POSIX库移植到微控制器时,您就可以访问相同的功能,而无需编写自己的库而需要大量的学习。
好。