This question already has answers here:
Why is the address of static variables relative to the Instruction Pointer?

(1 个回答)



Why are global variables in x86-64 accessed relative to the instruction pointer?

(2 个回答)


3年前关闭。




我在反汇编程序(浮点逻辑 C++)中找到了以下汇编代码。
  842: movss  0x21a(%rip),%xmm0

我知道当进程 rip 总是 842 并且这个 0x21a(%rip) 将是 const 时。使用这个寄存器似乎有点奇怪。

我想知道使用 rip 相对地址而不是其他寻址有什么好处。

最佳答案

RIP 是指令指针寄存器,表示它包含紧跟在当前指令之后的指令地址。
例如,考虑以下代码:

mov  rax, [rip]
nop
在第一行代码中, RIP 指向下一条指令,所以它指向 NOP 。因此,此代码将 NOP 指令的地址加载到 RAX 寄存器中。
因此,RIP 并不是一个简单的常量。您认为此过程中的 RIP “将始终为 842”是不正确的。 RIP 的值将根据代码加载到内存的位置而变化。 842 只是从调试符号中提取的行号;一旦代码被编译成二进制文件,它就不再有行号了。 :-)
在您的反汇编中,常量是偏移量 ( 0x21A )。这是 RIP 中当前值的偏移量。另一种写法是: %rip + 0x21ARIP -relative 寻址是 64 位长模式引入的一种新形式的有效寻址。关键是它可以更容易地编写与位置无关的代码,因为您可以使任何内存引用 RIP -relative。实际上,RIP -relative 寻址是 64 位应用程序中的默认寻址模式。几乎所有在 64 位模式下寻址内存的指令都是 RIP 相关的。我将引用 Ken Johnson (aka Skywing)'s blog 的内容,因为我自己说得再好不过了:

他是在 Windows 的上下文中发言,但概念上类似的东西也适用于其他操作系统。
您拥有的代码正在将一个常量值(存储在二进制图像的某个位置)加载到 XMM0 寄存器中,并且它使用 RIP 相对寻址来执行此操作,因为它具有许多优点。

关于assembly - 为什么这个 MOVSS 指令使用 RIP 相对寻址?,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/44967075/

10-15 12:53