《程序员的自我修养---链接、装载与库》读书笔记(二)编译与链接


第二章 编译和链接

1. 构建
  1. 构建(Build):将编译和链接合并到一起执行。例如使用GCC构建出一个程序时可分解为四个步骤:预处理(Preprocessing),编译(Compilation),汇编(Assembly)和链接(Linking)。
    $ gcc hello.c
    在这里插入图片描述

  2. 预处理(Preprocessing):主要处理代码文件中的预处理指令。例如删除所有#define,展开所有的宏定义;删除所有的注释;添加行号和文件名标识;将#include的文件内容展开到该预处理指令的位置等。
    $ gcc -E hello.c -o hello.i

  3. 编译(Compilation):将预处理生成的文件进行此词法分析,语法分析,语义分析以及优化后生成对应的汇编代码文件。
    $ gcc -S hello.i -o hello.s

  4. 汇编(Assembly):将汇编代码文件转变成机器码,机器可以执行的指令。输出目标文件(Object File)。
    $ gcc -c hello.s -o hello.o

  5. 链接(Linking):将所有的目标文件链接起来,生成可执行文件。
    $ gcc hello.o -o hello -L /usr/include/c++/7.3.0

  6. gcc命令实际上是一系列编译工具的封装,它会根据参数去调用预编译编译程序cc1(cc1plus),汇编器as,链接器ld。

2. 编译器
  1. 编译器就是一个将高级语言翻译成机器语言的一个工具。编译过程可分为六步:词法分析,语法分析,语义分析,源代码优化,代码生成和目标代码生成。
    在这里插入图片描述

  2. 词法分析:将代码文件输入扫描器(Scanner),扫描器把代码分割成一系列记号(Token)。
    在这里插入图片描述

  3. 语法分析:语法分析器(Grammer Parser)将对由扫描器产生的记号进行词法分析,从而产生语法树(Syntax Tree)。语法分析只是语法层面,不去分析这个语句是否有意义。
    在这里插入图片描述

  4. 语义分析:语义分析器(Semantic Analyzer)对语义进行分析,例如声明和类型的匹配,类型的转换等。语义分析后,语法树的表达式都会被标识了类型。
    在这里插入图片描述

  5. 中间语言生成:源码优化器(Source Code Optimizer)将整个语法树转换为中间代码(Intermediate Code)。

  6. 目标代码生成与优化:代码生成器(Code Generator)将中间代码转换为机器代码。然后经过目标代码优化器(Target Code Optimizer)进行优化。

3. 链接
  1. 链接(Linking): 每个源码模块独立地编译,然后将它们组装起来,这个组装模块的过程就是链接。链接的主要工作就是把各个模块之间互相引用的部分处理好,使得各个模块之间能够正确衔接。

  2. 运行时库(Runtime Library):支持程序运行的基本函数的集合。

  3. 链接过程主要包含了:地址和空间分配(Address and Storage Allocation),符号决议(Symbol Resolution)和重定位(Relocation)等。

  4. 重定位(Relocation):重新计算各个目标地址的过程。

  5. 最基本的静态链接过程,将目标文件和库一起链接生成可执行文件。
    在这里插入图片描述

  6. 链接过程和作用举例:main.c中调用了func.c中的foo()函数。编译器在编译main.c的时候并不知道foo()这个函数的地址,暂时将这个地址搁置。链接器在链接的时候,会根据引用的符号foo来找到func.c中的foo()的地址,然后将main.c中所有引用到foo的指令重新修正,让它们的目标地址成为真正foo函数的地址。这个地址修正的过程就是重定位。

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值