调用函数后堆栈

时间:2014-02-25 11:27:46

标签: assembly

在调用函数之前,调用者必须将参数推送到堆栈? 谁推下一条指令的地址? 如果被调用的函数将使用她自己的变量,它将把它们推送到堆栈 因此,当使用RET返回时,它会弹出值并将EIP设置为此弹出的值。但是它不存在,因为函数已分配变量,因此堆栈已更改? 怎么会这样?谁在call命令之前推送下一条指令的地址? 解决!

1 个答案:

答案 0 :(得分:1)

在调用指令期间,返回地址被压入堆栈。函数必须跟踪推入堆栈的变量数,从堆栈分配的任何空间使用alloca(),以及对esp进行的任何其他更改,并在函数退出时恢复esp,以便返回指令将返回到合适的地方。如果启用了堆栈帧选项,则该函数通常会以push ebp |开始mov ebp,esp和never修改ebp。退出代码然后执行mov esp,ebp | pop ebp,然后返回。

对于“C”调用约定,在从被调用函数返回之后,调用函数需要添加到esp以将其恢复到其先前状态,然后将任何参数推送到堆栈。对于“Pascal”调用约定,被调用函数将使用ret n指令,其中n是在调用之后添加到ESP的值,以补偿推送的参数。

根据调用约定,一些参数在寄存器而不是堆栈中传递。对于Visual Studio,这是32位模式下的选项,但在64位模式下,前4个参数始终在寄存器rcx,rdx,r8和r9中传递。