程序的执行过程
helloworld.c程序的生命周期是从一个ASCII码形式(文本文件)的源文件开始的,这种形式能被人读懂。
然后经过编译器驱动程序将它转换为一系列机器语言指令,按照一种称为可执行目标程序(可执行目标文件)的方式打包,以二进制磁盘文件的形式存放起来。
然后我们可以运行一个程序,即上面的二进制可执行程序,操作系统通过操作各种硬件资源执行该程序。
程序翻译过程
编译器驱动程序通过调用预处理器,编译器,汇编器和连接器,并进行其他各项需要的工作,将源程序文本文件,翻译成一个可执行文件。整个翻译过程可以分为四个阶段:
- 预处理阶段。预处理器cpp根据以字符
#开头的命令,修改原始程序,得到一个以.i为文件扩展名的另一个c程序。 - 编译阶段。编译器cc1将.i文件翻译成以.s为扩展名的文本文件,它是一个汇编语言程序。每条汇编语句都用一种文本格式描述了一条低级机器语言指令,汇编语言为不同高级语言的编译器提供了通用的输出语言。
- 汇编阶段。汇编器as将.s为扩展名的汇编程序翻译成机器语言指令,并且将他们打包成一种可重定位目标程序(relocatable object program)的格式,得到一个以.o为扩展名的二进制目标文件。
- 链接阶段。链接器ld将各种代码和数据片段(包括调用的库函数的目标文件,以及可重定位目标文件等)收集并组合成一个单一文件的过程,这个文件可以被加载到内存并执行。
在这个过程中编译器驱动调用的调用的四个程序,即预处理器,编译器,汇编器和链接器,构成一个编译系统。而编译器驱动程序负责的是整个流程,什么时候自动的调用某个程序,并完成相应资源等的调度。
操作系统和硬件
我们可以把操作系统看成应用程序和硬件之间的一层软件。所有应用程序对于硬件的操作尝试都必须通过操作系统。
操作系统可以防止硬件被失控的应用程序滥用,还可以向应用程序提供简单一致的机制来控制复杂而又通常大不相同的低级硬件设备。操作系统通过几个基本的抽象概念:进程,虚拟内存和文件等,实现了这两个功能。
- 进程是对处理器,主存和I/O设备的抽象表示。进程是操作系统对一个正在运行的程序的一种抽象。在一个系统上可以同时运行多个进程,并且每个进程看起来都在独占的使用硬件。并发运行指的是一个程序的指令和另一个进程的指令是交错执行的。在单核CPU上,同一时刻只能执行一个程序,而多核CPU在一个时刻可以同时执行多个程序。对于每个CPU(无论单核还是双核)来说,系统通过上文件切换可以实现多个进程的执行。
线程。 - 虚拟内存是对主存和I/O设备的抽象表示。它为进程提供了一个抽象,假设所有进程都在独占的使用内存,每个进程看到的内存都是一致的,称为虚拟地址空间。
- 文件是对I/O设备的抽象表示。文件就是字节序列。每个I/O设备,磁盘,键盘,显示器,网络,等等,都可以看成是文件。系统中所有的输入输出都是通过UNIX I/O系统调用函数,如
open,fopen等等实现的。它向应用程序提供了一个统一的视角看待系统中所有各式各样的I/O设备。
参考文献
1.《CSAPP》第五版