1代码
点击查看代码【<三>从编译器角度理解C++代码编译和链接原理】1:编译**sum.cpp**int gdata=https://www.huyubaike.com/biancheng/10;int sum(int a,int b){return a+b;}**main.cpp**extern int gdata;int sum(int , int );int data=20;int main(){int a =gdata;int b=data;int ret=sum(a,b);return 0;}
文章插图
文章插图
需要关注的几个点1: .o 文件的格式组成是什么样子?2: .exe 文件的组成格式是什么样子?3: "所有.o文件段的合并 符号表合并后,进行符号解析"4: "符号的重定位(重定向)"5: "符号表的输出"=> "符号"6: 符号什么时候分配虚拟地址?
预编译以#开头的命令
除#pragma lib-> 链接阶段处理除#pragma link-> 链接阶段处理
编译语法分析,语义分析,代码优化 gccg++
编译后生成相应平台的 汇编代码X86 和 AT&T
链接链接所有 .o文件和 静态库文件
文章插图
文章插图
文章插图
文章插图
.o 文件 主要是由以下组成elf 文件头.text.data.bss.symbal.section table....
符号表中,在自己文件中定义的,那就是符号定义,如果是引用外部的就 是 "UND"符号引用符号表中的符号 都没有分配地址,如下图,所以编译过程中,符号是不分配虚拟地址的,是在链接的时候分配
文章插图
文章插图
经过了上面的 预编译-》编译-》汇编 各个阶段后 下面开始进入了 链接阶段
main.o 文件sum.o 文件上面我们看到 .o 文件是由各个段组成的,所以进入链接阶段的时候第一步 将各个.o 文件 的各个段合并
main.o 文件的 .text段与sum.o 文件的 .text 段合并main.o 文件的 .data段与sum.o 文件的 .data 段合并main.o 文件的 .bss段与sum.o 文件的 .bss段合并main.o 文件的符号表与sum.o文件的符号表 段合并
第二步 非常重要的一点是 在main.o文件的符号表与sum.o文件的符号表段合并的时候,需要进行符号解析 。什么是"符号解析"?所有对符号的引用,都要找到该符号定义的地方“符号的引用” 即符号为 UND形式, 要找到该符号定义的地方即要找到该符号是在.text 段中定义还是在.data段中定义,例如:链接器发现main.o文件的sum函数和gdata是UND形式的,那么链接器会去其他文件中找到sum和gdata的定义,如果没找到,那么链接器报错"符号未定义",如果链接器找到了多个,那么链接器也会报错 “符号重定义”,所以在整个工程中,全局的名字是不能重名的,否则会产生冲突.
符号解析成功以后 就开始回给所有的符号分配地址
第三步 "符号重定向"在符号解析成功以后并且给所有的符号分配地址后,需要继续做 "符号重定向"在我们指令编译汇编生成.O文件的时候,生成的指令中的符号的地址都是用0 代理,如下图
经验总结扩展阅读
- 吃三文鱼怎么避免寄生虫
- 2023年10月16日是入学吉日吗 2023年10月16日入学行吗
- 2023年10月16日是举办成人仪式的黄道吉日吗 2023年10月16日是举办成人仪式吉日吗
- 2023年10月16日拜师学艺行吗 2023年10月16日拜师学艺好不好
- 2023年10月16日清扫房屋好不好 2023年10月16日是清扫房屋的黄道吉日吗
- 2023年10月16日大扫除黄道吉日 2023年10月16日适合大扫除吗
- 2023年农历九月初二宜堵蚂蚁洞吗 2023年10月16日堵蚂蚁洞好吗
- 2023年10月16日堵蚁穴黄道吉日 2023年10月16日堵蚁穴好吗
- 2023年10月16日遇见贵人行吗 2023年10月16日适合遇见贵人吗
- 2023年10月16日理头黄道吉日 2023年农历九月初二宜理头吗