在C / x86中,从函数返回时我们通常会:
pop ebp
恢复上一个函数的帧指针ret
(据我所知)包含一个隐式pop eip
,以便调用函数可以继续从返回地址执行此时,我可以期待esp包含哪些内容?它是指向返回地址正上方的指针,还是ret
隐含地改变了esp的值?
谢谢:)
答案 0 :(得分:9)
它是指向返回地址正上方的指针,还是esp的值也被ret隐式改变了?
ret
有两种形式:ret
和ret N
。第一种形式只是弹出eip(这通常意味着“从eip中添加ep,加上esp,4”)并继续执行,所以esp指向调用函数时推送的最后一个参数 - 这意味着调用者必须通过以下方式处理后来的add esp, N
。
ret N
表示在弹出eip之后,esp在同一指令中按值N添加,因此调用者不需要这样做。缺点是你不能使用可变数量的args,因为'N'只能是常数值。
答案 1 :(得分:2)
在ret
之后,如果之间没有发生恶作剧,则esp
应包含与相应call
之前相同的值。 call
指令推送堆栈上的返回值,ret
指令将其弹出。所以是的,你的直觉是正确的。
答案 2 :(得分:1)
在ret之后,sp应该与调用函数时的sp相同。
所以它会指向最后推送到堆栈的任何内容。