《链接器与加载器》——第一章 链接和加载

链接器负责的工作:

  地址绑定、重定位、库查询、代码分段

加载器负责的工作:

  重定位(先由于硬件重定位而省略)

地址绑定:

  将更抽象的名字与更底层的名字绑定(如getline名字绑定到iosys模块内可执行代码的612字节处,或这个模块静态数据开始的第405字节处)。

重定位:

  编译器和汇编器生成的目标代码地址从0开始。一个程序有多个子程序组成,子程序们的地址不能重叠。重定位就是为程序不同部分分配加载地址,调整程序中的数据和代码以反映所分配地址的过程。

  重定位一般不止一次,链接时,各子程序通过重定位在大程序中确定位置。当程序加载时,系统会选择一个加载地址,而链接好的程序会作为整体被重定位到加载地址。

符号解析:

扫描二维码关注公众号,回复: 4963936 查看本文章

  当多个子程序构建一个大程序时,子程序间互相作用是通过符号进行的,如主程序调用sqrt,sqrt定义在数学库中。链接器通过标明分配给sqrt的地址来解析这个符号,并修改目标代码使得call指令引用该地址。

程序加载:

  将程序从辅助存储器拷贝到内存中,准备运行。有些情况下,还包括分配存储空间,设置保护位,或通过虚拟内存将虚拟地址映射到磁盘内存页上。

  当允许一个程序的多个实例时,程序中的某些部分在所有的允许实例中都是相同的(尤其时可执行代码),而另一些部分是各实例独有的。

编译链接实例

m.c

m包含程序段16B,数据段16B(字符串)

符号表:_main(导出符号)、_a(导入符号)

程序先将字符串的地址压栈,用于传参。

在调用a函数时,由于a未知,所以用0x0代替地址,并做好标记。

a.c

a.c程序段0x1c字节

其中调用的库函数都是未知的所以用0x0代替入口地址

使用静态链接

链接后数据段变多,是由于使用静态链接库函数

程序增加了启动代码start-c,和调用的库函数例程

_c和_main符号都重新进行地址绑定。

可以看出静态链接会复制导入的符号相关的实例,这就造成了程序体积会很大

猜你喜欢

转载自www.cnblogs.com/yangxinrui/p/10285826.html
今日推荐