函数调用堆栈过程
示例代码
int sum(int a ,int b)
{
int tmp = 0;
tmp = a+b;
return tmp;
}
int main()
{
int a = 10;
int b = 20;
int ret = sum(a,b);
cout<<"ret:"<<ret<<endl;
return 0;
}
调用过程
main函数栈帧
-
main函数开始后,先两条mov指令,将a和b入栈,然后将ret入栈。
-
然后将sum的形参变量进行压栈,压栈顺序时从右到左。
- 然后进行call sum指令,call sum指令做两件事情,第一件是将call sum的下一行指令的地址入栈,确保sum函数退出后程序知道在什么地方继续向下执行;第二件是将ebp的地址入栈,确保sum退出后知道在那个函数中继续执行。
- 接着就是sum开辟栈帧,然后执行sum中的指令。
- 最后tmp的值由寄存器带回来赋值给ret。
注意
- esp永远指向当前函数栈帧的起始地址,ebp指向当前函数栈帧的末尾地址。
- 函数退栈只是简单得将当前edp 的值mov给esp,并不对函数栈帧的内存进行清空处理。
- call 指令做两件事,入栈下一行指令的地址和调用函数的ebp的地址,确保被调用函数退栈后,程序知道该退回到那个函数以及该从哪里开始继续往下执行。
- 函数参数的压栈的顺序是从右到左压栈。