Warning: file_get_contents(/data/phpspider/zhask/data//catemap/7/elixir/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Memory management 运行时内存地址绑定的需要_Memory Management_Operating System_Cpu Architecture - Fatal编程技术网

Memory management 运行时内存地址绑定的需要

Memory management 运行时内存地址绑定的需要,memory-management,operating-system,cpu-architecture,Memory Management,Operating System,Cpu Architecture,我读到,在现代操作系统中,内存地址绑定是“动态”的,发生在运行时。但既然我们使用虚拟内存方案,并且每个进程都有自己的虚拟用户内存空间,为什么我们仍然延迟运行时绑定?我们不能进行编译时地址绑定吗,因为虚拟页面地址将映射到物理页面?我们在大多数操作系统上对可执行文件使用链接时绑定,其中可执行文件本身可以映射到固定的虚拟地址。它可以将绝对地址嵌入到所有位置,而无需在运行时重新定位。是的,这是因为不同的进程可以使用相同的虚拟地址。没有虚拟内存的系统需要每个进程使用不同的地址 库的情况并非如此:库无法知道

我读到,在现代操作系统中,内存地址绑定是“动态”的,发生在运行时。但既然我们使用虚拟内存方案,并且每个进程都有自己的虚拟用户内存空间,为什么我们仍然延迟运行时绑定?我们不能进行编译时地址绑定吗,因为虚拟页面地址将映射到物理页面?

我们在大多数操作系统上对可执行文件使用链接时绑定,其中可执行文件本身可以映射到固定的虚拟地址。它可以将绝对地址嵌入到所有位置,而无需在运行时重新定位。是的,这是因为不同的进程可以使用相同的虚拟地址。没有虚拟内存的系统需要每个进程使用不同的地址

库的情况并非如此:库无法知道在任何给定的进程中,要加载它的地址范围是多少,所以它必须使用

OSX还要求可执行文件使用PIC。我从来没有查过为什么;也许他们希望能够做到


我可能完全错了,但我想我记得读到Win9x不需要位置独立的代码,安装DLL需要与系统上其他已安装的DLL协调,以找到可以使用的绝对地址范围。

虚拟内存和动态绑定是两个独立的概念。动态绑定是在没有虚拟内存的系统中完成的

在大多数情况下,应用程序尝试使用位置无关的代码。这是可以在内存中的任何位置加载并仍然正确执行的代码。编译器使用偏移量生成位置无关的代码。许多处理器允许从程序计数器/指令指针寄存器进行相对寻址,以访问内存位置

您可以有一个全局变量,如:

int x ;
并引用它

main ()
{ 
   int y = x + 1 ;
}
编译器和链接器可以对用户进行相对寻址,使程序可以放在内存中的任何位置

这样会导致链接时的相对寻址出现问题:

static int *x = &y ;
您的链接器在这里有两种选择。以太它可以强制y位于一个固定位置(意味着代码不是位置独立的),或者它可以包括一个在运行时解析的地址修正(通常是这样做的)。在后一种情况下,程序加载器从可执行文件中读取fixup,并在加载变量时将其初始化为地址

发生的另一个修复是当您拥有共享库(又称DLL)时。可以更新共享库,而无需重新链接链接到该库的所有程序。共享库有一个通用符号表(即可以在库外部看到的符号,例如库函数的名称)。如果将代码添加到库中,事情就会发生变化


当您链接到共享库时,可执行文件将定义到它所使用的共享库(通常是函数)中全局变量的动态映射。在运行时,加载程序将在可执行文件中使用此信息来查找所引用函数的地址,并修复地址以匹配加载共享库的地址

(更正,我认为MacOS不需要PIC可执行文件,但它总是在低4GiB之外加载它们,因此您永远无法利用32位绝对地址,例如对于
mov eax,[table+rax*4]