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++)中找到了以下汇编代码。
我知道当进程 rip 总是 842 并且这个 0x21a(%rip) 将是 const 时。使用这个寄存器似乎有点奇怪。
我想知道使用 rip 相对地址而不是其他寻址有什么好处。
因此,
在您的反汇编中,常量是偏移量 (
他是在 Windows 的上下文中发言,但概念上类似的东西也适用于其他操作系统。
您拥有的代码正在将一个常量值(存储在二进制图像的某个位置)加载到
(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 + 0x21A
。RIP
-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