读《程序员的自我修养》——2

  • IDE环境下的 Build其实是预编译、编译、汇编和链接四个过程的合并。
    Linux下针对C语言的预编译编译程序为cc1,针对C++的是cc1plus,针对JAVA的是jc1,或gcc -c
    ——gcc实际上是针对不同高级语言的多个预编译编译器的包装,根据不同的gcc参数,调用cc1、cc1plus、cc1obj、jc1、汇编器as、链接器ld
  • 编译器的基本工作流程如下:
    1. 词法扫描分析——将源代码字符分割成一系列的记号(Token),其中记号分为关键字、标识符、字面量(常数、字符串等)和特殊符号(运算符号等)这几类。进行词法分析的工具为lex
    2. 语法分析——生成以表达式为节点,以常数和标识符最基层叶子的语法树,完成高级语言的语法分析。进行语法分析的现成工具为yacc,根据用户给定的语法规则对输入的记号序列进行解析,因此使用yacc可以针对不同的编程语言,只需改变规则就可以得到相应的语法分析器。
    3. 语义分析——语法分析仅仅完成了源代码的语法层面的分析,但是对于表达式是否有意义,是否合法并不清楚,这就需要进行表达式的语义分析,并完成一些潜在的类型转换、匹配等。完成语义分析后,语法树的每一个表达式都被标识了相应的类型。
    4. 源代码优化——将整个语法树转换为与硬件无关的中间代码。常见的中间代码类型为“三地址码”,形如 x = y op z 。中间代码的存在使得整个编译器软件被分为了与硬件无关的前端和与硬件相关的后端,这就使得编译器可以支持多种编程语言的编译工作,使用相同的前端,需要改变的仅仅只是后端而已。
    5. 生成目标代码——根据特定硬件的字长、寄存器、指令集等特性,将中间代码生成相应的汇编语言代码
    6. 优化目标代码
  • 现代软件规模非常庞大,因此软件的分模块成为了必然的趋势,各个模块代码被单独编译得到目标文件,然后将这些模块组装到一起成为一个可执行文件,就是链接器的工作,其主要内容其实就是将各个模块之间的相互引用处理好,将一些指令对在其他模块定义的符号的引用进行地址的修正。
          仅仅通过编译得到的目标文件中存在着很多的重定位入口,即不能确定物理地址的符号,在未经链接的目标文件中这些符号的物理地址往往都被置为0,需要由链接器来对其进行修正——即重定位(Relocation)
  • 所谓的库文件可以理解为一组常用代码编译得到的目标文件的打包,最常见的库就是运行时库,是支持程序运行的基本函数的集合。静态链接的过程就是将多个目标文件与库文件进行链接得到可执行文件的过程。  
posted @ 2009-12-07 22:19  TryKnowWhy  阅读(255)  评论(0)    收藏  举报