我正在阅读amd64手册,并在CALL near部分中说:
对于64位模式下的近程调用,操作数大小默认为64位。 E8操作码 导致RIP = RIP + 32位有符号位移,并导致FF / 2操作码 RIP =寄存器或存储器的64位偏移量。没有前缀可用于编码32位 64位模式下的操作数大小。
看起来每次操作码都是E8时,接下来的32位用作偏移,对吗?我拆开了一个程序,然后我试了一下:
4003f0: e8 3b 00 00 00 callq 400430 <__gmon_start__@plt>
根据手册,目标地址应为0x4003f0 + 0x3b。如果你尝试的结果是0x40042b,但根据objdump它应该是0x400430。我尝试了其他的调用指令,缺少相同的4个字节,没有人知道原因吗?
另外:它表示操作数大小默认是64位,然后表示当操作码是e8时只考虑32位,这是一个例外吗?
答案 0 :(得分:4)
只是回答原因0x400430
而不是0x40042b
。当指令从0x4003f0
开始时,EIP计算基于其下一条指令,因此您必须向EIP添加5(当前指令的长度)。
目标操作数指定代码段中的绝对偏移量(距代码段基址的偏移量)或相对偏移量(相对于EIP寄存器中指令指针的当前值的有符号位移;此值指向CALL指令后面的指令。)
(引自英特尔手册。)