目录标题

  • 词法分析
  • 语法分析
  • 从语法树到中间代码再到目标代码
  • 链接与载入
  • 总结


源程序是给人看的,本质上就是文本文件,可以用Linux中的vi或Windows中的记事本之类的文本编辑程序打开、编写,但计算机无法直接执行源程序,需要通过一个专门的程序将源程序编译为计算机可执行程序,这个专门的程序就是编译器。

编译过程主要分为词法分析、语法分析、中间代码生成、目标代码生成(忽略预处理、语义分析、优化等)。

词法分析

词法分析的作用是从连续的字符中识别出标识符、关键字、数字、运算符并存储为符号(token)流(分割读取各个文本符号)

语法分析

语法分析的作用就是从词法分析识别出的符号流中识别出符合C语言语法的语句(识别文本符号进行语法匹配)

以案例中“int fun(int a,int b);”这条函数声明语句为例描述这个过程,它与语句模板的匹配情景如图

编译ImageMagick_编译ImageMagick


这段token流最终与函数声明模板相匹配,在匹配成功后,计算机就认为此语句为函数声明语句,并以语法树的形式在内存中记录下来,情景如图

编译ImageMagick_中间代码_02

从语法树到中间代码再到目标代码

如果希望一步到位,从语法树转换为目标代码,理论上和实际上都是可行的。但计算机存在多种CPU硬件平台,考虑到程序在不同CPU之间的可移植性,先转换成一个通用的、抽象的“CPU指令”,这就是中间代码最初的设计思想。然后根据具体选定的CPU,将中间代码落实到具体CPU的目标代码。

语法树是个二维结构,中间代码是准一维结构,语法树到中间代码的转换过程,本质上是将二维结构转换为准一维结构的过程。中间代码特别是RTL已经可以和运行时结构一一对应了。如图

编译ImageMagick_中间代码_03


选定具体的CPU、操作系统后,中间代码就可以转换为目标代码——汇编代码(我们配置的是AT&T汇编),这时操作系统的影响还比较小。然后由汇编器依照选定操作系统的目标文件格式,将.s文件转换为具体的目标文件,对于Linux而言是.o文件,对于Windows而言是.obj文件。目标文件中已经是选定的CPU的机器指令了。

链接与载入

最后链接器把一个或多个目标文件(库文件本质上也是目标文件)链接成符合选定操作系统指定格式的可执行文件。

通过操作系统,可执行程序就可以被载入内存执行

总结

编译ImageMagick_linux_04