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

连接器负责的工做:ios

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

加载器负责的工做:blog

  重定位(先因为硬件重定位而省略)内存

 

地址绑定:字符串

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

重定位:编译器

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

  重定位通常不止一次,连接时,各子程序经过重定位在大程序中肯定位置。当程序加载时,系统会选择一个加载地址,而连接好的程序会做为总体被重定位到加载地址。io

符号解析:编译

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

程序加载:

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

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

 

编译连接实例

 

m.c

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

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

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

在调用a函数时,因为a未知,因此用0x0代替地址,并作好标记。

 

a.c

a.c程序段0x1c字节

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

使用静态连接

连接后数据段变多,是因为使用静态连接库函数

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

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

能够看出静态连接会复制导入的符号相关的实例,这就形成了程序体积会很大

相关文章
相关标签/搜索