gpt4 book ai didi

c - X86 汇编指令指针寻址

转载 作者:太空狗 更新时间:2023-10-29 16:48:01 25 4
gpt4 key购买 nike

我通常不会花太多时间阅读汇编,所以下面的编译器输出让我有点困惑。

假设我在运行 OSX 10.6 的 Intel Core 2 Duo 上编译这段 C 代码:

while (var != 69) // var is a global variable
{
printf("Looping!\n");
}

“var != 69”比较的程序集如下所示:

cmpl    $69, _var(%rip)

我知道它实际上意味着将值“69”与全局变量“var”的内容进行比较,但我很难理解“_var(%rip)”部分。通常,我希望有一个偏移值,比如引用堆栈中的局部变量(例如:-4($ebp))。但是,我不太了解如何使用“_var”声明偏移指令指针会给我全局变量“var”的内容。

那一行到底是什么意思?

谢谢。

最佳答案

这与使用 offset(%ebp) 寻址堆栈中的局部变量几乎相同。在这种情况下,链接器将该指令的偏移字段设置为 var 的地址与 %rip 的值之间的差异当该指令执行时会有。 (如果我没记错的话,那个值是下一条指令的地址,因为%rip总是指向当前正在执行的指令之后 .) 因此,加法给出了 var 的地址。

为什么要这样做?这是 position-independent code 的标志.如果编译器生成了

cmpl $69, _var

并且链接器填入了var的绝对地址,然后当您运行程序时,可执行镜像总是必须在一个特定的位置加载到内存中地址,以便所有变量都具有代码期望的绝对地址。通过这种方式,唯一需要固定的是代码和数据之间的距离;代码和数据(即完整的可执行镜像)可以加载到任何地址并且仍然可以工作。

... 何苦呢?为什么必须在一个特定地址加载可执行文件是不好的?不一定。共享库必须是位置无关的,否则你可能有两个库想要加载到重叠的地址,你不能在同一个程序中同时使用它们。 (一些系统通过保留所有库及其所需空间的全局注册表来处理这个问题,但显然这不能扩展。)使可执行文件位置无关主要是作为一种安全措施完成的:它是如果您不知道程序代码在内存中的位置(这称为 address space layout randomization),那么利用缓冲区溢出会有些困难。

关于c - X86 汇编指令指针寻址,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/6488226/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com