在 amd64 中调用附近

Call near in amd64

我正在阅读 amd64 手册,在 CALL near 部分它说:

For near calls in 64-bit mode, the operand size defaults to 64 bits. The E8 opcode results in RIP = RIP + 32-bit signed displacement and the FF /2 opcode results in RIP = 64-bit offset from register or memory. No prefix is available to encode a 32-bit operand size in 64-bit mode.

看起来每次操作码是E8时,接下来的32位都被用作偏移量,对吧?我反汇编了一个程序,我试过了:

  4003f0:       e8 3b 00 00 00          callq  400430 <__gmon_start__@plt>

根据手册目标地址应该是0x4003f0 + 0x3b。如果您尝试结果是 0x40042b,但根据 objdump 它应该是 0x400430。我尝试了其他调用指令,同样缺少 4 个字节,有没有人知道原因?

另外:它说操作数大小默认为 64 位,然后说当操作码为 e8 时只考虑 32 位,这是一个例外吗?

只是回答为什么是 0x400430 而不是 0x40042b。当指令从0x4003f0开始时,EIP的计算是基于它的下一条指令,所以你必须在EIP上加5(当前指令的长度)。

The target operand specifies either an absolute offset in the code segment (an offset from the base of the code segment) or a relative offset (a signed displacement relative to the current value of the instruction pointer in the EIP register; this value points to the instruction following the CALL instruction).

(引用自英特尔手册。)