编译与静态链接

本文介绍了GCC编译C源文件的详细步骤,包括预编译、编译、汇编和链接。在链接阶段,重点讨论了静态链接的过程,包括地址与空间分配和符号解析与重定位。GCC实际上是对cpp、cc1、as、ld等后台程序的封装,静态链接用于生成不依赖链接库的可执行文件,而动态链接则更常见,但需要动态链接库支持。
摘要由CSDN通过智能技术生成

最近一段时间做了关于一些软件的交叉编译工作,由于觉得并没有学到许多东西,所以抽时间看了关于静态链接方面的内容,读了一部分《程序员的自我修养——链接、装载与库》,记录一些读书笔记及自己的总结。

一、GCC做了什么?

我们在Linux中经常使用

gcc  源文件名.c  -o  目标可执行文件名

对一个编写好的C文件进行编译生成可执行文件,那么这之间的细节呢? 
这里源文件名为 hello.c ,生成可执行文件名为 hello 为例子 
这里写图片描述
gcc一个C源文件时对过程进行了隐藏,实际为:预编译 cpp、编译 cc1、汇编 as、链接 ld,其中每一步后的英文名是所使用的工具的名称。

那么各自的步骤到底干了什么呢?

1、预编译:处理.c文件中以“#”开头的预编译指令。

这些预编译指令包括了宏定义、条件预编译指令等等,此步中也会进行删除掉所有的注释等操作。当无法判断一个宏定义是否正确或者头文件是否正确包含的话,可以直接打开此步生成的文件进行检查。

gcc  -E  hello.c  -o  hello.i
2、编译:进行词法分析、语法分析、语义分析等工作,此步所生成的文件是以汇编代码构成的。

这一步是由编译器cc1完成(gcc中),主要分为词法分析、语法分析、语义分析、中间语言生成、目标代码生成与优化几步。

a.词法分析:将所有的C语言源代码分割为一系列的记号,这些记号主要为关键字、标识符、常量及特殊符号,比如表达式 a+b 在这步中就会被拆分为 a 和 b 两个标识符及 + 这个特殊符号。

b.语法分析:产生语法树,关于这步需要有一些数理逻辑的知识,即生成以表达式为节点的树,对应上面 a+b 的情况是 + 为一个节点,而 a 和 b 分别为左右子树的节点。

c.语义分析:确定每个节点的类型,比如整型、字符型等。 
可以理解为在前一步的树的基础上在每个节点上都标示好类型,对于一些隐式转换及强制类型转换都会在这步中进行处理。

d.中间语言生成:进行两步操作,首先将语法树转化为中间代码,然后在中间代码中对已经能够确定值的表达式进行求值。 
其中中间代码一般为三地址码,即 x = y op z的形式,其中op代表特殊符号,然后如果有些表达式能够确定其值,比如 t1=5+6 这种两个常量相加的语句就直接进行计算。

e.目标代码生成与优化:如字面意思,进行目标代码的生成与优化。 
关于目标代码的生成与具体的硬件平台有关,而优化部分有部分操作,比如合适的寻址方式、对于乘法运算使用位移进行代替,这些如果有接触汇编代码会比较了解。

编译器流程图: 
这里写图片描述
此步中生成的文件如果懂得汇编代码的话仍然是可读的

gcc  -S  hello.c  -o  hello.s
3、汇编:将汇编代码转变成机器可以执行的指令。

此步中是根据汇编指令与机器指令的对照表进行一一翻译,基本上一个汇编语句对应一条机器指令。 
此步生成的文件已经没法读了,打开后全部是乱码,因为已经全部机制指令了。

gcc  -c  hello.s  -o  hello.o    
或
gcc  -c  hello.c  -o hello.o      
或
as  hello.s  -o  hello.o
4、链接:将几个输入的目标文件加工后合并为一个输出文件。
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值