可能重复:
了解printf的硬件
我不是在寻找printf功能的实现,但我想知道,当printf用C 调用时会发生什么?所有活动都在软件和硬件级别进行.
这就是我认为PrintfCAll - > KernelModeOn - > SystemCallMade - >数据放在一些排序的输出缓冲区 - >输出被转储到某些控制器的缓冲区 - >控制器将其转储到监视器 - >中断CPU说工作已完成.
我有多正确?谢谢.
编辑:Unix可以作为一个平台.说ubuntu.有人可以告诉我,数据从何处流出,是否还有监视器的控制器?上面提到的时间表在多大程度上是正确的?
Eri*_*hil 21
以下是基于编程概念而非任何具体实现的一般描述和概述.
调用以printf普通子程序调用开始; 内核模式不涉及.在很大程度上,printf是普通代码,可以用C语言编写.printf代码本身的大部分涉及解释格式字符串,将参数转换为要写入的字符串,以及将这些字符串写入输出文件.这项工作大部分都是通过调用子程序来完成的printf,例如将数字(像intor 这样的对象float)转换为数字的子程序(表示数字的字符串).
printf也可能调用malloc或相关的例程来为缓冲区准备内存以准备字符串.我将不再malloc在这个答案中描述这个电话.
解释格式字符串,转换参数和准备要编写的字符串的所有工作都可以在C中完成,尽管高质量的库可以使用各种特定于目标的优化(包括汇编语言)来提高速度或效率.
在某些时候,当printf有一个要打印的字符串时,它将调用一个例程来写入字符串stdout.这可能是fwrite或某些类似的子程序.对于讨论,我认为是fwrite.
通常,流被缓冲.因此,当printf调用时fwrite,fwrite检查其缓冲区的填充程度.如果新的字符串printf适合缓冲区,fwrite只需将字符串添加到缓冲区并返回.如果缓冲区已满,则fwrite调用另一个例程以将缓冲区内容实际写入文件.(通常,这涉及使用部分传入字符串填充缓冲区,将缓冲区写入文件[并将缓冲区标记为空],然后将其余的传入字符串复制到新空缓冲区中.)某些其他内容也可能触发写入缓冲区,例如根据情况检测传入字符串中的换行符.
让我们说,编写缓冲区,fwrite调用系统例程write.面对write图书馆的例行公事; fwrite执行普通的子程序调用来调用write.系统例程将具有一些普通子例程,但是,当他们需要执行细节工作时,存在某种系统调用指令(有时称为陷阱).
执行系统调用指令时,处理器会执行多项操作.它将处理器寄存器保存在指定位置.这包括描述用户进程状态的通用寄存器和特殊寄存器.然后处理器切换到内核模式,这通常涉及设置位以指示新的执行状态是特权的(允许更改特殊处理器寄存器,执行特殊指令等)并从其他位置加载寄存器,或将它们设置为已知值.特别地,程序计数器(处理器读取要执行的指令的位置)被设置为指向特定位置,其中操作系统具有处理系统调用的代码.
现在处理器正在内核模式下执行.通常,此时处理器的工作是尽快退出内核模式,以便它可以恢复进程之间的时间共享并为其他工作做好准备.此外,现代操作系统有很多层,因此很难准确说明此时发生的情况.
一种情况是系统调用处理程序(发生系统调用时调用的软件)读取保存的用户进程的寄存器和内存,以确定进程要求的内容.在每个系统上,指定了一些将参数传递给系统调用的方法.例如,某个寄存器可能包含一个指示请求是什么的数字(0表示写入,1表示读取,2表示获取当前时间,3表示更改存储器映射,等等),并且每个请求都将传入某些参数其他寄存器或在内存中(一个寄存器可能包含内存中的地址,而另一个寄存器包含要写入的长度).
因此,系统调用处理程序会计算出正在进行的请求,并调度到代码来处理该请求.这可能涉及收集请求的参数并将它们形成对要完成的工作的描述,然后将该工作放在队列上并离开系统调用处理程序.
虽然还有工作要做,但操作系统可能不会返回用户进程.正如我之前提到的,现代操作系统中有许多层.有设备驱动程序,内核扩展,微内核,操作系统内的软件库等等.但是,操作系统是有组织的,在某个时候,它决定执行系统调用所请求的工作.
在写入标准输出的情况下,工作被发送到"设备驱动程序",该设备驱动程序是处理"设备"工作的软件的名称.最初,设备是连接到系统的硬件.设备驱动程序会将要写入的数据复制到内存中的特殊位置,并向设备发出命令(使用特殊指令)从内存中读取该数据并将其发送到设备发送的任何位置(终端,磁盘驱动器) , 随你).设备驱动程序的另一部分是在工作完成时调用的例程.(此调用类似于系统调用,但通常称为中断.)完成工作后,设备驱动程序会将消息传递回操作系统的其他部分,最终有关系统调用结果的信息将会写入用户进程的存储器或寄存器,并重新启动用户进程的执行.
今天,许多"设备"是实现虚拟设备的软件.用户进程的标准输出可能是某种伪终端.由于该伪终端没有实际的硬件终端,因此它必须通过要求其他软件提供帮助来处理写请求.
当伪终端是图形显示器上的终端窗口的一部分时,存在一些实现终端窗口的软件.该软件接受写入标准输出的文本,决定它应放置在窗口中的哪个位置,并调用其他软件将字符转换为窗口中像素的变化.也就是说,某些软件正在读取字符,在某些表中查找它们的描述以及其他数据(字体的描述等),并在图像缓冲区中绘制这些字符.
当图像缓冲区准备就绪时,调用更多软件将图像缓冲区写入显示器.同样,这涉及将数据传递给另一个设备驱动程序.最终,它到达一个实际的硬件设备,它获取数据并使其出现在显示器上.
总而言之,有一系列重大事件.数据通过多个层上下移动,可能涉及多个不同的用户进程和几个不同的设备驱动程序,以及许多软件库.很难全面了解整个过程.通常,人们不想一次尝试理解整个过程,而是要分别学习每个步骤.例如,在我的职业生涯中,我不得不处理系统调用指令的细节.但是,在考虑我的整个系统如何工作时,我会考虑更大级别的流程相互通信,而不考虑这些通信如何工作的细节.
| 归档时间: |
|
| 查看次数: |
9851 次 |
| 最近记录: |