【C++】符号——链接的粘合剂

本文深入探讨了链接器的工作原理,解释了符号决议和重定位的概念,以及静态链接和动态链接的区别。通过实例说明了如何在编译过程中确定全局变量的地址。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

链接器所做的主要工作跟前面提到的“人工调整地址”本质上没有什么两样,只不过现代的高级语言拥有诸多的特性,使得编译器和链接器更为复杂,功能更为强大,但从原理上来讲,无非是找到符号的地址,或者把指令中使用到的地址加以修正。这个过程称为符号决议(Symbol Resolution)或者重定位(Relocation)。

 

 

每个模块的源文件(.c 和 .h)先被编译成目标文件,再和系统库一起链接成可执行文件。库(Library)其实是一组目标文件的包,是将一些最常用的代码编译成目标文件后打包存放。

 

 

这种在程序运行之前确定符号地址的过程叫做静态链接(Static Linking);如果需要等到程序运行期间再确定符号地址,就叫做动态链接(Dynamic Linking)。

Windows 下的 .dll 或者 Linux 下的 .so 必须要嵌入到可执行程序、作为可执行程序的一部分运行,它们所包含的符号的地址就是在程序运行期间确定的,所以称为动态链接库(Dynamic Linking Library)。

 

 

例如在 a.c 中有一个 int 类型的全局变量 var,现在需要在 b.c 中对它赋值 42,对应的C语言代码是:

var = 100;

对应的汇编代码为:

mov 0x2a, var

mov 用来将一份数据移动到一个存储位置,这里表示将 0x2a 移动到 var 符号所代表的位置,也就是对 var 变量赋值。

当被编译成目标文件后,得到如下的机器指令(这里 0x2a 变成了 0000002a,而var 变成了 00000000):

c705  00000000  0000002a

 

 

数据区在程序运行期间一直存在,全局变量的位置不会改变,地址也是固定的,所以在链接时就能够计算出全局变量的地址。而栈区内存会随着函数的调用不断被分配和释放,局部变量的地址不能预先计算,必须等到发生函数调用时才能确定,所以链接过程会忽略局部变量

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值