【问题标题】:What is the difference between position-dependent code and position-independent code? [closed]位置相关代码和位置无关代码有什么区别? [关闭]
【发布时间】:2013-02-04 05:27:04
【问题描述】:

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

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

【问题讨论】:

  • 很抱歉,您可以很容易地使用搜索引擎来查找这方面的信息。请做你自己的研究。如果您有一个特定问题无法自行找到答案,请返回并在此处发布。

标签: c


【解决方案1】:

位置无关的代码可以在代码加载到内存中的任何位置正确运行。这通常是通过对函数调用使用相对跳转来实现的,相对跳转,跳转地址是从代码流中的当前位置计算出来的,所以代码可能看起来像:“从当前位置跳转 585 字节”或“跳转 5745 字节”从这个模块的基地址”而不是“跳转到地址 0x46fae55”。同样,对于引用内存地址的任何其他指令,必须相对于当前代码位置或相对于在运行时确定的基地址写入。

内存管理单元 (MMU) 和虚拟内存地址的使用使得与位置无关的代码对于可执行文件来说几乎是过时的。但是,共享库必须编写为与位置无关的代码,因为它们可以映射到可执行文件地址空间中的任何位置。

【讨论】:

  • 还必须相对于代码的位置(例如相对于指令指针/程序计数器)访问数据。
  • @Lie Ryan,但是即使使用 MMU,共享库仍然需要位置无关代码,对吧?
  • @FUZxxl:我已经澄清了最后一段
  • @Lie «内存管理单元 (MMU) 和虚拟内存地址的使用使得位置无关代码对于可执行文件几乎已经过时» 我不同意。 PIE(位置无关的可执行文件)是一种增强代码安全性的方法,因为注入的 shell 代码可能对代码的下落做出更少的假设。
【解决方案2】:

在早期的计算机中,代码是依赖于位置的:每个程序都被构建为加载到特定地址并从其运行。为了同时使用不同的程序运行多个作业,操作员必须仔细安排作业,以免两个同时的作业运行需要相同加载地址的程序。

例如,如果工资单程序和应收帐款程序都被构建为在地址 32K 上运行,则操作员不能同时运行这两个程序。有时,操作员会保留多个版本的程序,每个版本都针对不同的加载地址构建,以扩展他的选择。

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

【讨论】:

  • 现在并不是每个 CPU 都直接支持位置无关代码。
【解决方案3】:

补充 Lie Ryan 的答案——这不是 c 编程语言的问题,而是系统架构的问题。

例如intel x86 分段架构支持半自动位置独立加载 .com 格式的小型可执行文件,其中操作系统可以将 cs=ds=es=ss 加载到 2^16 个不同的值。

OTOH 的 .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

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2023-03-27
    • 2023-02-15
    • 2011-07-19
    • 2012-10-10
    • 2010-09-14
    • 2013-05-13
    • 2017-08-19
    相关资源
    最近更新 更多