读书-程序员的自我修养-链接、封装与库(5: 第二章:静态链接 预处理,编译,汇编,链接)

Hello World执行的四个步骤

#include <stdio.h>
int main()
{
	printf("Hello world\n"):
	return 0;
}

使用GCC编译器:
gcc hello.c
./a.out
上述过程可以分解为四个步骤:
1. 预处理(prepressing) gcc -E hello.c 生成 xx.i文件
2. 编译(compilation) gcc -S xx.i 生成 xx.s
3. 汇编(Assembly) gcc -c xx.s 生成 xx.o
4. 链接(Linking) gcc xx.o 生成 a.out
5.

1. 预处理的工作内容

1.1 预编译作用

gcc -E hello.c -o hello.i
预编译过程主要处理那些源文件中以“#”开始的预编译指令
比如:#include #define #if #ifdef

编译器就是将高级语言翻译成机器语言的一个工具。

1.2 预编译具体工作

1. 将所有的#define 删除,并且展开所有的宏定义
2. 处理所有条件编译指令,如#if #ifdef #elif #else #endif
3. 处理#include预编译指令,将包含的文件插入到该预编译指令的位置,这个过程是递归进行的。
4. 删除所有的注释 // 和 /**/ 
5. 添加行号和文件名标识,比如 #2 hello.c 2 ,以便调试信息,错误,告警等显示行号
6. 保留所有的#pragma等编译器指令,因为编译器需要他们

结果:经过预编译后的hello.i文件不包含任何宏定义,因为所有的宏已经被展开。

2. 编译的工作内容

gcc -S hello.i -o hello.s
编译过程:编译过程一般可以分为6步:扫描、词法分析,语法分析,语义分析、源代码优化、代码生成、目标代码优化。

1. 扫描:首先源代码被输入到扫描器(Scanner)
2. 词法分析:将源代码的字符序列分割成一系列的记号
	记号分为: 关键字,标识符,字面量(数字字符串),特殊符号
3. 语法分析:对记号进行语法分析,产生语法树(Syntax Tree),就是以表达式为节点的树
4. 语义分析:给语法树的表达式标识类型
5. 中间语言生成:简单的代码优化,如 4+5 直接计算结果
6. 目标代码生成与优化:选择合适的寻址方式、使用位移来代替乘法运算、删除多余的指令等

后面将图贴上来!

3. 汇编的工作内容

gcc -c hello.s -o hello.o
汇编:将汇编代码转变成机器可以执行的代码指令,每一个汇编语句几乎都对应一条机器指令。

4. 连接器的工作内容

4.1 重定位、符号

重定位(Relocation):重新计算各个目标的地址过程叫做重定位(Relocation)
符号(Symbol):表示一个地址,这个地址可以是一段子程序/函数,也可以是一个变量的起始地址。

4.2 模块调用

模块之间的调用归结为如何通信的问题,常见是模块间的函数调用和模块间的变量访问。

4.3 链接

  1. 模块的拼接的过程就是链接
  2. 链接(Linking):
    主要内容就是把各个模块之间的相互引用的部分都处理好,使得各个模块之间能够正确的衔接。
  3. 链接的主要过程:包括地址和空间分配,符号决议,重定位

4.4 运行时库

库:其实是一组目标文件的包,就是一些最常用的代码编译成的目标文件后打包存放。
运行时库(Running Library):它是支持程序运行的基本函数的集合

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值