编译过程
- 预处理:处理#开头的指令
- 编译:将.cpp翻译成.s的汇编代码
- 汇编:输出符号表,将.s翻译成.o的机器代码,二进制可重定位的目标文件(.*o)
- 链接:编译完成所有的.o文件,以及静态库文件(*.a,.*lib)链接
链接详细过程
- 将所有.o文件的代码段合并,符号表合并后,进行符号解析(所有对符号的引用/UND/都要找到符号定义的地方)
- 符号的重定向(给所有符号分配虚拟地址)
- 生成xxx.exe/a.out可执行文件
举例
int gdata = 10;
int sum(int a,int b){
return a+b;
}
sum.o的符号表
参数 | 所在位置 |
---|---|
gdata | .data |
sum_int_int | .text |
extern int gdata; // 在main中未定义,对其符号引用
int sum(int, int); // 在main中未定义,对其符号引用
int data = 20; //符号的定义
int main(){//符号的定义
int a = gdata;
int b = data;
int ret = sum(a,b);
return 0;
}
main.o的符号表
参数 | 所在位置 |
---|---|
gdata | UND |
sum | UND |
data | .data |
main | .text |
所有对符号的引用/UND/(undefine)都要找到符号定义的地方,在main.o中的gdata是UND需要找到符号定义的位置,也就是在sum.o中。
在链接时,各个段都要合并。
如:
.text<=>.text
.data<=>.data
.bss<=>.bss