欢迎来到尧图网

客户服务 关于我们

您的位置:首页 > 房产 > 建筑 > C++编译链接原理

C++编译链接原理

2024/10/25 15:25:14 来源:https://blog.csdn.net/Anterior_condyle/article/details/140276134  浏览:    关键词:C++编译链接原理

从底层剖析程序从编译到运行的整个过程

三个阶段

    • 一、编译阶段
    • 二、链接阶段
    • 三、运行阶段

为了方便解释,给出两端示例代码,下面围绕代码进行实验:

//sum.cpp
int gdata = 10;
int sum(int a,int b)
{return a+b;
}
//main.cpp
extern int gdata;
int sum(int ,int);static int stat;int data = 20;int main()
{int a = gdata;int b = data;int ret = sum(a,b);return 0;
}

前两个阶段:
在这里插入图片描述

一、编译阶段

在这里插入图片描述
三件重要的事情:
编译阶段只关注自己模块内的事情
编译阶段不分配虚拟空间地址,无法运行
目标文件由各个段组成

编译阶段的产物是可重定位的二进制目标文件,由各个段组成
在这里插入图片描述
一、符号表(.symtab段)
查看符号表命令:objdump -t main.o
在这里插入图片描述
1.符号表中存储程序产生的符号,如
静态全局变量stat的符号为_ZL4stat ,定义在.bss区域
全局变量data的符号为data,定义在.data区域
主函数main()的符号为main,定义在.text区域
外部变量gdata的符号为gdata,定义为UND,表示符号的引用,不知道在哪里定义
外部函数sum(int,int)的符号为_Z3sumii,定义为UND,表示符号的引用,不知道在哪里定义

2.符号表中可以看到变量的链接属性
l:表示lcoal,符号只能在当前文件可见,内部链接属性
g:表示global,符号可以在所有文件可见,外部链接属性

所以链接的时候链接器只能看见gloal的符号 看不到lcoal的符号
这就解释了静态全局变量/函数 和普通全局变量/函数同名的问题
在多个文件中可以定义名字相同的静态全局变量/函数,因为local属性链接器不可见,但若多个文件中普通的全局变量/函数重名,因为具有global属性,链接的时候符号解析就会冲突

3.编译过程中变量不分配虚拟空间地址
我们查看以下.text段,注意需要带有-g输出调试信息
g++ -c main.cpp -g
objdump -S main.o
在这里插入图片描述观察,编译阶段产生了二进制机器码,但是不分配虚拟空间地址,所以地址先用0替代,即编译阶段指令没法用,需要等链接阶段分配虚拟地址补上地址才有用,这就是目标文件无法运行的原因之一
4.查看目标文件的各个段
命令:readelf -S main.o
在这里插入图片描述

二、链接阶段

在这里插入图片描述

链接所有的编译完成的目标文件(.o)和静态库文件(.a)
链接步骤:
步骤一:
将所有的目标文件的各个段进行合并
main.o的.text段和sum.o的.text段合并
main.o的.data段和sum.o的.data段合并
main.o的.bss和sum.o的.bss段合并
合并后进行符号解析
如链接阶段符号为UND(符号引用)的,都需要找到该符号定义的地方,如果没有找到=符号未定义,找到多个定义=符号重定义
UND 找到定义解析成具体 .text .data ..

步骤二:
符号的重定位(重定向)
符号解析之后,给所有的符号分配虚拟地址空间,成为了可执行文件

验证
使用链接器自己链接::ld -e main sum.o main.o
查看符号表:objdump -t a.out
在这里插入图片描述
可以看到所有符号均有定义的段,无UND符号引用的情况
所有符号均分配了地址(看第一列)

再看看代码段.text
在这里插入图片描述
之前机器码缺少地址的,现在也都补充上了,所以变成了可以运行的二进制机器码(指令)

补充1:
看一下可执行文件的文件头信息
在这里插入图片描述

.text段的信息
在这里插入图片描述
可以发现,可执行文件头记录了程序入口指令地址,所以CPU知道从哪个指令开始执行(这里是main函数作为入口)

补充2:
可执行文件所有的段都和二进制目标文件相同,多了一个programa headers段,用来告诉操作系统,运行这个程序的时候,把哪些内容加载进内存(数据段 指令段),注意:不是所有的段都需要加载进内存的
查看programa headers段:readelf -l a.out
在这里插入图片描述

三、运行阶段

在这里插入图片描述

版权声明:

本网仅为发布的内容提供存储空间,不对发表、转载的内容提供任何形式的保证。凡本网注明“来源:XXX网络”的作品,均转载自其它媒体,著作权归作者所有,商业转载请联系作者获得授权,非商业转载请注明出处。

我们尊重并感谢每一位作者,均已注明文章来源和作者。如因作品内容、版权或其它问题,请及时与我们联系,联系邮箱:809451989@qq.com,投稿邮箱:809451989@qq.com