为什么我不能保存rip的价值?

dbb*_*bbd 6 x86 assembly

#include <stdint.h>
uint64_t rip;
int main()
{
    asm(
        "movq %%rip, %0\n" : "=m" (rip)
        );

    sleep(10);
}
Run Code Online (Sandbox Code Playgroud)

当我编译我得到

cc -m64    rip.c   -o rip
/tmp/ccwNbZi1.s: Assembler messages:
/tmp/ccwNbZi1.s:12: Error: suffix or operands invalid for `movq'
make: *** [rip] Error 1
Run Code Online (Sandbox Code Playgroud)

Ale*_*nze 14

您无法读取,(E|R)IP因为没有x86(/ 64)指令可以直接读取它.

"读取"它的唯一方法是使用CALL指令进行调用.它将保存堆栈上的返回地址和您可以读取的地址.

更新:在64位模式下,您可以利用RIP-relative地址,因此LEA RAX, [RIP]将为您提供自己的地址EAX.另一个解决方法是MOV RAX, $组装.

  • `mov rax,$`将由链接器硬编码,删除位置独立性,或者在运行时需要重定位.我强烈建议使用`lea rax,[rip]`. (4认同)
  • 是的,这正是我的意思。装配经常用于那种事情。它更像是“加载一个常量,它恰好是重定位后当前执行地址的指针”,而不是“加载 rip”。 (3认同)
  • 这就是为什么我只是强烈建议。同样,位置独立性是现代程序中非常普遍的目标,主要是出于安全原因(ASLR)。至少苹果的编译器/汇编器需要64位程序。 (2认同)
  • @AlexeyFrunze当然,`mov rax,$`仍然可以重定位,但是它不再与位置无关。只需考虑一个汇编例程,该例程会将代码块移动几个字节:在移动“ lea rax,[rip]”之后仍然可以使用,但是在“ mov rax,$”之后不再可用。 (2认同)