我正在阅读amd64手册,并在“呼叫近区”一节中写道:
对于64位模式下的近调用,操作数大小默认为64位.E8操作码导致RIP = RIP +32位符号移位,FF /2操作码导致RIP =64位偏移从寄存器或内存。没有前缀可用于在64位模式下编码32位操作数大小.
看起来,每次操作码是E8时,接下来的32位都用作偏移量,对吗?我拆解了一个程序然后我试着:
4003f0: e8 3b 00 00 00 callq 400430 <__gmon_start__@plt>根据手册,目标地址应该是0x4003f0 + 0x3b。如果您尝试,结果是0x40042b,但根据objdump,它应该是0x400430。我试过使用其他调用指令,而相同的4个字节丢失了,有人知道原因吗?
另外:它说操作数的大小默认是64位,然后说当操作码是e8时只考虑32位,这是一个例外吗?
发布于 2015-05-24 05:51:00
只是回答为什么是0x400430而不是0x40042b。当指令从0x4003f0开始时,EIP计算是基于它的下一个指令,所以您必须将5(当前指令的长度)添加到EIP中。
目标操作数指定代码段中的绝对偏移量(来自代码段底部的偏移量)或相对偏移量(相对于EIP寄存器中指令指针的当前值的有符号位移;该值指向调用指令之后的指令)。
(引用英特尔手册)
https://stackoverflow.com/questions/30420381
复制相似问题