ASM函数调用返回地址

返回地址( EIP寄存器返回时保存在堆栈中的那个地址)是在call后的下一条指令的地址,还是它是call的指令地址?

编辑:

p call x
q mov y

调用x() pq时,返回地址是堆栈中的吗?


在调用之后 - 这将是子例程终止时执行的下一条指令。


处理器将EIP寄存器的值(包含CALL指令之后指令的偏移量)压入堆栈(稍后用作返回指令指针)。

正如@Jester发布的,RTFM。


call指令将返回地址-在路上你“编号为”你行那将会q -在堆栈上执行转移到被调用函数之前。

ret指令将其弹出 - 你可以说它pop EIP
但是这也意味着...在ret之前, [ ESP ] == EIP 。 由于ret对堆栈没有其他任何东西,但是调整堆栈指针(即ESP - > ESP + 4 ),到您返回时,您仍然应该拥有EIP == [ ESP - 4 ]

你可以这样做:

call func
mov EAX, [ ESP - 4 ]

并且很可能获得该MOV指令的第一个字节的代码位置。

为什么只有很可能? 答案是堆栈未分配部分内的堆栈内容不能保证; 有异步事件(UN * X信号和其他操作系统中的类似机制)可能会在执行堆栈指针调整/ EIP更改之后但在该指令实际执行前的ret之间中断执行。 如果发生这种情况,信号帧可能会覆盖未分配的堆栈部分,从而破坏存储在那里的返回地址。

如果您想要可靠地检索当前的EIP ,请执行只是“跳过call指令”的PC相关呼叫。 然后弹出堆栈上的值。 即喜欢:

call +5   ;; the size of a call is 5 bytes, so ... "skip yourself"
pop EAX   ;; EAX now contains the "return address" - its own EIP

请参阅先前在SO上回答的,直接阅读程序计数器。

链接地址: http://www.djcxy.com/p/80365.html

上一篇: ASM Function call return address

下一篇: What is a stack pointer used for in microprocessors?