程序员自我修养第二章编译和链接

来源:互联网 发布:sql获得系统时间 编辑:程序博客网 时间:2024/05/21 10:35

编译系统的组成:预处理器、编译器、汇编器和链接器。程序编译运行过程:预处理(prepressing)、预编译(Compilation)、汇编(Assembly)、链接(Linking)。

         预编译过程主要处理那些源代码文件中的以“#”开始的预编译指令(还包括删除所有注释,展开所有宏定义)。

         编译过程就是把预处理完的文件进行一系列词法分析、语法分析、语义分析及优化后产生相应的汇编代码文件。

         汇编器是将汇编代码转变成机器可以执行的指令,每一个汇编语句几乎都对应一条机器指令(它只是根据汇编指令和机器指令的对照表一一翻译即可,比较简单)。

         链接涉及到编译、链接和库,正是本书要讲的。

2.2、编译器做了什么

2.2.1、词法分析

         源代码程序被输入到扫描器,扫描器进行简单语法分析,运用一种类似于有限状态机(Finite State Machine)算法很容易将字符序列分割成一系列记号(Token)。

         词法分析产生的记号一般可以分为如下几类:关键字、标识符、字面量(数字、字符串等)和特殊符号(+,=等)。(C语言宏替换和文件包含等工作一般交给独立的预处理器)。

         lex程序可以实现语法扫描。

2.2.2、语法分析

         对扫描器产生的记号进行语法分析,产生语法树(Syntax Tree)(以表达式为节点的树)。采用了上下文无关语法(Context-free Grammar)的分析手段。

         yacc(Yet AnotherCompiler Compiler)工具可以根据用户给定的语法规则对输入的记号序列进行解析,从而构建出一棵语法树。

2.2.3、语义分析

         编译器所能分析的语义是静态语义,动态语义只有在运行期才能确定。

2.2.4、中间语言生成

         源码级优化器(SourceCode Optimizer),它往往将整个语法树转换成中间代码,中间代码类型比较常见的有三地址码(如,x=y op z)和P-代码。

         中间代码生成后,由编译器后端将中间代码转换成目标机器代码。后端主要包括代码生成器和目标代码优化器。

         而定义其他模块的全局变量和函数在最终运行时的绝对地址都要在最终链接时确定。

2.4、模块拼装——静态链接

         链接过程主要包括地址和空间分配、符号决议(也有称绑定的)和重定位这些步骤。

         链接没想象中那么复杂,其实就是像在编译A文件时,A中调用的函数地址不知道,那么编译器先把这个地址搁置,等待最后链接的时候有链接器去将这些指令的目标地址修正。变量值也是一样的道理。地址修改的过程被称为重定位。
原创粉丝点击