什么是位置相关代码和位置无关代码的区别?

11

什么是位置相关代码和位置无关代码之间的区别?

还有,我们如何使用示例实现 / 调用自己的静态和动态库?


很抱歉,但你可以很容易地使用搜索引擎查找相关信息。请自行进行研究。如果你有一个特定的问题在自己的研究中无法找到答案,那么再回来在这里发帖提问。 - Jonathon Reinhart
3个回答

11
在早期计算机中,代码是位置相关的:每个程序都被构建为加载到特定地址并从该地址运行。为了同时使用多个独立程序运行多个作业,操作员必须仔细安排这些作业,以确保没有两个同时运行的作业需要相同的加载地址来运行程序。

例如,如果工资单程序和应收账款程序都被构建为在32K地址运行,则操作员无法同时运行两者。有时,操作员会保留多个程序版本,每个版本针对不同的加载地址进行构建,以扩大可选项。

为了使事情更加灵活,发明了位置无关代码。位置无关代码可以从操作员选择加载代码的任何地址运行。位置无关代码不仅被用于协调用户级应用程序的工作,而且也被用于操作系统内部。

1
现在的CPU并不是所有都直接支持位置无关代码。 - Alexey Frunze

11

位置独立代码可以在内存加载代码的任何位置正确运行。通常使用相对跳转调用函数来实现,相对跳转时,跳转地址是从代码流中的当前位置计算得出的,因此代码可能看起来像:"从当前位置向后跳585个字节"或者"从该模块的基地址开始向后跳5745个字节",而不是"跳转到0x46fae55地址"。同样,对于任何其他引用存储器地址的指令,必须相对于当前代码位置或在运行时相对于确定的基地址写入。

由于内存管理单元(MMU)和虚拟内存地址的使用,使得位置独立代码对可执行文件几乎已经过时了。然而,共享库必须编写为位置独立代码,因为它们可以映射到可执行文件的地址空间中的任何位置。


同时,数据必须相对于代码位置进行访问(例如,相对于指令指针/程序计数器)。 - Alexey Frunze
@Lie Ryan,但即使有MMU,共享库仍需要位置无关代码,对吗? - Lunar Mushrooms
@FUZxxl:我已经澄清了最后一段。 - Lie Ryan
1
@Lie:“使用内存管理单元(MMU)和虚拟内存地址使得可执行文件的位置无关代码几乎过时了。”我不同意。位置无关可执行文件(PIE)是增强代码安全性的一种方式,因为注入的shell代码可能对代码的位置知之甚少。 - fuz

3
为了补充Lie Ryan的回答——这不是C编程语言的问题,而是系统架构的问题。
例如,Intel x86分段式架构支持半自动位置无关加载小型.com格式可执行文件,其中操作系统可以将cs=ds=es=ss加载到2^16个不同的值。
另一方面,.exe格式引入了“重定位”,这意味着在可执行文件中有一个偏移量数组(相对于二进制加载地址),必须加上加载地址:例如。
  relocation_table:  // list of values to be modified
          0022, 0100, ...
  .text 
  0020:   xx yy 12 00      mov ax,[0x0012]   <-- the "absolute address" 0012 is
  // located at address 0022 in the binary -- that has to be added with the real 
  // location of the the "position-independent" code

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接