【发布时间】:2011-01-28 07:07:33
【问题描述】:
我想知道是否有任何可用的在线资源来解释发生了什么,例如 C 的 printf,它解释了在非常低级别(BIOS/内核调用)发生了什么
【问题讨论】:
我想知道是否有任何可用的在线资源来解释发生了什么,例如 C 的 printf,它解释了在非常低级别(BIOS/内核调用)发生了什么
【问题讨论】:
Linux:
printf() ---> C 库中的 printf() ---> C 库中的 write() ---> 内核中的 write() 系统调用。
要了解用户空间和内核空间之间的接口,您需要了解system calls 的工作原理。
要了解最低级别发生了什么,您需要分析kernel 中的源代码。
Linux system call quick reference(pdf 链接)可能很有用,因为它标识了您可能开始查找内核源代码的哪个位置。
【讨论】:
这是非常特定于平台的。从硬件的角度来看,printf() 的后端实现可以定向到串行端口、非串行 LCD 等。您实际上是在问两个问题:
printf() 如何解释参数和格式字符串以生成正确的输出?
输出如何从 printf() 到您的目标设备?
您必须记住,应用程序运行不需要操作系统、内核和 BIOS。嵌入式应用程序通常具有 printf() 和其他 IO 例程写入字符环缓冲区。然后,中断可能会轮询该缓冲区并操纵输出硬件(LCD、串行端口、激光表演等)以将缓冲的输出发送到正确的目的地。
【讨论】:
根据定义,BIOS 和内核调用是特定于平台的。你对什么平台感兴趣?已经发布了几个指向 Linux 相关信息的链接。
另请注意,printf 甚至可能不会导致任何 BIOS 或内核调用,因为您的平台可能没有内核或 BIOS(嵌入式系统就是一个很好的例子)。
【讨论】:
类似 printf 或 printf 的东西?这有点模糊。
printf 输出到 stdout FILE* 流;与之相关的是系统相关的,而且可以重定向到操作系统为其提供合适的设备驱动程序的任何其他流设备。我在嵌入式系统中工作,并且大多数情况下,stdout 默认被定向到用于串行 I/O 的 UART - 通常这是唯一支持的流 I/O 设备,并且无法重定向。在控制台模式应用程序的 GUI 操作系统中,输出以系统定义的终端字体以图形方式“绘制”到窗口,例如在 Windows 中,这可能涉及 GDI 或 DirectDraw 调用,这些调用反过来访问视频硬件的设备驱动程序。在现代桌面操作系统上,控制台字符输出根本不涉及 BIOS,可能只是初始引导。
因此,简而言之,通常在 printf() 调用和输出它的硬件之间存在大量软件。
【讨论】:
printf() 接受多个参数(可变长度参数函数)。用户提供一个字符串和输入参数。
printf() 函数创建一个内部缓冲区用于构造输出字符串。 现在, printf() 遍历用户字符串的每个字符并将该字符复制到输出字符串。 Printf() 只在“%”处停止。
“%”表示有参数转换(参数形式为char、int、long、float、double或string)。它将其转换为字符串并附加到输出缓冲区。如果参数是字符串,那么它会进行字符串复制。
最后,printf() 可能会到达用户字符串的末尾,并将整个缓冲区复制到标准输出文件。
【讨论】: