2程序编译与链接
程序编译与链接原理
- 预编译:处理#命令,但保留#pragma,删除注释。
- 编译:词法分析、语法分析、语义分析和优化,生成汇编代码。
- 汇编:将汇编代码翻译成机器码(AT&T,x86语法),打包为可重定位二进制目标文件,此文件不可执行。输出符号表。
- 链接:合并.o文件段,合并符号表,解析并符号重定向。
//以下为main文件
extern int gdata; //gdata *UND*代表需使用但未定义
int sum(int, int); //sum *UND*
int data = 20; //data .data
int main(){ //main .text
int a = gdata;
int b = data;
int ret = sum(a, b);
return 0;
}
//以下为sum文件
int gdata = 10; //gdata .data
int sum(int a, int b){ //sum_int_int .text
return a + b;
}
以上为.o文件中的部分符号注释
具体的.o文件的格式组成包括各种段
编译过程中不为符号分配地址,通过readelf可以观察到地址皆为0。虽然指令已经在编译阶段翻译好,但变量地址皆为0,需要在链接阶段补充,也因此.o文件无法执行。
链接
链接过程合并若干个.o文件的段合并:text段合并,data段合并...,以及符号表的合并。
-
符号表合并:检查符号表,所有对符号的引用(*UND*),都要找到该符号定义的地方,当然符号定义只能有一个,不可重定义,不可没有。最终符号解析成功。
-
符号解析成功后,在代码段中,为所有符号分配虚拟地址,并把这些地址写回指令中。这个过程叫做符号重定向。
可执行文件
链接产生可执行文件,可执行文件与二进制可重定向文件段格式几乎一致,但可执行文件中多了一个program headers段,这其中包含若干load项,比如.text,.data,这意味着这些load项要在代码执行时,加载如虚拟内存空间
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 终于写完轮子一部分:tcp代理 了,记录一下
· 震惊!C++程序真的从main开始吗?99%的程序员都答错了
· 别再用vector<bool>了!Google高级工程师:这可能是STL最大的设计失误
· 单元测试从入门到精通
· 【硬核科普】Trae如何「偷看」你的代码?零基础破解AI编程运行原理