栈帧调用

发布于:2021-10-21 17:18:53

首先要了解


1.函数调用就要开辟栈空间,是用于本次函数调用中的临时变量的保存、现场保护。
这块栈空间我们称之为函数栈帧。
2.栈空间是向低地址生长。堆区与栈区相对生长的。

利用一个例子来解释函数调用、栈帧的创建和销毁。


#include
int fun(int a, int b)
{
int z = a+b;
return z;
}
int main()
{
int a = 2;
int b = 3;
int c = fun(2,3);
pritnf("%d", c);
return 0;
}

我们发现其实main函数也是被调用的,所以也会形成栈帧。


栈帧有栈底(ebp)、栈顶(esp)。栈顶是入栈和出栈的唯一地方。

main函数为临时变量a、b开辟空间,如图

下一步,调用fun函数。调用fun函数需要传参。所以,先为参数开辟空间


此时看汇编代码:
push:参数压榨,先压b(函数传参从右往左)
call:1.将当条指令的下一条指令的地址保存至栈中。
???? 2.将函数入口地址放至eip(寄存器,存放的是当前指令的下一条指令的地址)

此时栈空间如图:


1. 储存下一条指令的地址是为了,再调完fun函数时候可以返回至main函数中,继续执行之后
的代码。
2. 储存main(esp)同样是为了在调完fun函数之后,esp、ebp可以指向main函数的栈空间。

再所用东西都准备好之后,为fun函数开辟栈空间。
(此时寄存器espebp存放的是(fun espebp))
创建变量z,如图:

将a+b的值存z中,return z(返回值先存放入eax中)
函数fun调用结束,出栈释放栈帧。(这里要注意的是,释放空间并不是使栈空间清零)


此时汇编指令
pop:出栈。
ret:出栈一次,并将出栈的内容当作地址,将程序跳至该地址处。

(寄存器espebp存放的是(main esp ebp))
创建c变量如图:

继续执行之后的程序,至程序结束。

相关推荐

最新更新

猜你喜欢