一.3 链接与加载

链接器和加载器需要完成若干个密切关联但是在概念上有很大差异的操作。

1 程序加载,将程序从辅助存储设备(自1968年后这个存储设备就一直是磁盘)复制到主存 内存中准备运行。对于简单的情况而言,加载仅仅是将数据从磁盘考入内存,而对于复杂的情况而言,还有包括分配内存空间,设置权限保护位以及通过虚拟内存将虚拟地址映射到磁盘中的内存页上。

2 重定位 编译器和汇编器在创建目标的代码的时候,通常假设每个文件都是从地址0开始的,但是计算机很少会从地址0加载用户编写的程序,如果一个程序是由多个子程序组成的,那么每一个子程序都应该被加载到独立的地址上,而且保证不重叠。重定位工作就是为程序的各个部分分配加载地址,调整程序中的数据和代码,使之与所分配的地址相匹配的过程。在很多系统中,重定位工作会进行不止一次。对于连接器而言,一种常见的应用场景是由多个子程序来构建一个大程序。这些子程序在创建的时候都认为自己从地址0开始的,但是他们会被链接到一起并输出为一个大程序。这个大程序的起始地址为0,各个子程序会按照重定位技术倍链接在这个大程序中的某个位置上。当这个程序被加载时,系统会选择一个加载地址,而链接好的大程序会被当作一个整体加载到分配的地址上,并且完成相应的重定位工作。

3 符号解析 当通过多个子程序来构建一个大程序时,子程序之间的相互引用时通过符号进行的;主程序可能会调用一个名为sqrt的函数来计算平方根,而sqrt函数其实是在数学库中定义的。链接器解析sqrt这个符号,就是要找到库中的sqrt函数被分配的地址,并通过修改目标代码使得call指令引用该地址。

尽管链接器和加载的过程都有相当一部分工作是重叠的,但是我们还是要给它们一个明确的定义。我们把加载器定义为一个仅仅完成程序加载的程序,而链接器定义为一个仅完成符号解析的程序,这两个程序都可以进行重定位,而且还会出现同时支持这三种功能的链接加载器。

重定位和符号解析之间并没有清晰的界限,链接器其实已经解析了对符号的引用,为了更方便的处理重定位,一种方法就是为程序的每一部分分配一个符号用来表示其基地址base address,然后连接时把符号的链接地址表示为到该基地址的相对偏移量。这样在运行时候只需要修改基地址的值,程序就变成可重定位的了。

链接器和加载器共有一个重要的特性就是它们都会修改目标代码,操作目标代码的程序并不多,除了这两个之外,我们日常还用到的调试程序,这类程序设计独特并且功能强大,但是非常依赖于机器设计的细节,而且一旦出错引发的bug有时候会难以理解和想象。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值