依赖于位置的代码和与位置无关的代码有什么区别?
还有我们如何使用示例实现/调用我们自己的静态和动态库?
答案 0 :(得分:8)
位置无关代码可以在内存中加载代码的任何地方正确运行。这通常通过使用函数调用的相对跳转来实现,通过相对跳转,跳转地址从代码流中的当前位置计算,因此代码可能如下所示:“从当前位置跳转585个字节”或“跳转5745个字节从该模块的基地址“而不是”跳转到地址0x46fae55“。同样,对于任何其他指令,必须相对于当前代码位置或相对于在运行时确定的基址来写入引用内存地址。
内存管理单元(MMU)和虚拟内存地址的使用使得与位置无关的代码几乎可以用于可执行文件。但是,共享库必须编写为与位置无关的代码,因为它们可以映射到可执行文件的地址空间中的任何位置。
答案 1 :(得分:4)
在早期的计算机中,代码与位置有关:每个程序都是为了加载到特定地址并从中运行而构建的。为了同时使用单独的程序运行多个作业,操作员必须仔细调度作业,这样任何两个同时作业都不会运行需要相同加载地址的程序。
例如,如果工资核算程序和应收帐款程序都构建为在地址32K运行,则操作员无法同时运行这两个程序。有时候,操作员会保留一个程序的多个版本,每个版本都是为不同的加载地址构建的,以扩展他的选项。
为了使事情更加灵活,发明了与位置无关的代码。与位置无关的代码可以从运营商选择加载它的任何地址运行。与位置无关的代码不仅用于协调用户级应用程序的工作,还用于协调操作系统。
答案 2 :(得分:2)
添加到Lie Ryan的答案 - 这不是c编程语言的问题,而是系统架构的问题。
E.g。 intel x86分段体系结构支持.com格式的小型可执行文件的半自动位置独立加载,其中操作系统可以将cs = ds = es = ss加载到2 ^ 16个不同的值。
.exe格式OTOH引入了“重定位”,这意味着在可执行文件中有一个偏移数组(相对于二进制文件的加载地址),必须添加加载地址:例如。
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