C语言的编译过程
编译: 编译程序读取源程序(字符流),对之进行词法和语法的分析,将高级语言指令转换为功能等效的汇编代码,再由汇编程序转换为机器语言,并且按照操作系统对可执行文件格式的要求链接生成可执行程序。
流程:C源程序头文件 --> 预编译处理(cpp) --> 编译程序本身 --> 优化程序 --> 汇编程序 --> 链接程序 -–> 可执行文件
1. 编译预处理
读取C语言源程序,对其中的伪指令(以#开头的指令)和特殊符号进行处理。
伪指令主要包括以下四个方面:
(1)宏定义指令
(2)条件编译指令,如#ifdef, #ifndef, #else, #elif, #endif
(3)头文件包含指令,如#include “FileName” 或者 #include 等。
(4)特殊符号,预编译程序可以识别一些特殊的符号。
预编译程序所完成的基本上是对源程序的“替代”工作。经过此种替代,生成一个没有宏定义、没有条件编译指令、没有特殊符号的输出文件。这个文件的含义同没有经过预处理的源文件是相同的,但内容有所不同。下一步,此输出文件将作为编译程序的输出而被翻译成为机器指令。
2. 编译阶段
经过预编译得到的输出文件中,将只有常量,如数字、字符串、变量的定义,以及C语言的关键字,如main, if, else, for, while, {, }, +, -, *, \, 等等。预编译程序所要做的工作就是通过词法分析和语法分析,在确认所有的指令都符合语法规则之后,将其翻译成等价的中间代码表示或汇编代码。
3. 优化阶段
优化处理是编译系统中一项比较艰深的技术。它涉及到的问题不仅同编译技术本身有关,而且同机器的硬件环境也有很大的关系。优化一部分是对中间代码的优化。这种优化不依赖于具体的计算机。另一种优化则主要针对目标代码的生成而进行的。
经过优化得到的汇编代码必须经过汇编程序的汇编转换成相应的机器指令,方可能被机器执行。
4. 汇编过程
汇编过程实际上指把汇编语言代码翻译成目标机器指令的过程。对于被翻译系统处理的每一个C语言源程序,都将最终经过这一处理而得到相应的目标文件。目标文件中所存放的也就是与源程序等效的目标的机器语言代码。
5. 链接程序
由汇编程序生成的目标文件并不能立即就被执行,其中可能还有许多没有解决的问题。例如,某个源文件中的函数可能引用了另一个源文件中定义的某个符号(如变量或者函数调用等);在程序中可能调用了某个库文件中的函数,等等。所有的这些问题,都需要经链接程序的处理方能得以解决。
链接程序的主要工作就是将有关的目标文件彼此相连接,也即将在一个文件中引用的符号同该符号在另外一个文件中的定义连接起来。