函数的调用过程,栈帧的创建和销毁

本文详细解析了栈帧的概念及其在函数调用中的作用,包括如何通过寄存器ebp和esp来管理栈帧,以及具体的入栈和出栈操作。通过一个C语言示例程序的分析,展示了函数调用过程中栈帧的变化。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

栈帧就是一个函数执行的环境:函数参数、函数的 局部变量、函数执行完后返回到哪里等等. 栈是从高地址向低地址延伸的。每个函数的每次调用,都有它自己独立的一个栈帧,这个栈帧中维持着所需要的各种信息。寄存器ebp指向当前的栈帧的底部(高地址),寄存器esp指向当前的栈帧的顶部(低地址)。
下图为程序存储空间



入栈:push eax
出栈:pop eax
代码:
#include<stdio.h>
Add(int a,int b)
{
int z=a+b;
return z;
}

int main()
{
int x=10;
int y=20;
int ret=Add(a,b);
printf("%d",ret);
return 0;

}
在上代码中函数Add()执行时,栈的调用过程:
main的栈桢:

main函数的栈桢为从低地址esp到高地址ebp这块区域.在调用Add函数时过程大致为
push x;
push y.;将形参压入栈中
call Add;调用Add函数。将返回值地址填入栈。并跳转到Add函数.

跳转后,Add的汇编大致为
push ebp 因为Add为一个新的函数,需要自己的栈桢 ,则将main函数的栈底压栈操作.因为main栈顶为Add栈底则不操作.
mov ebp esp 上一个栈桢的顶部为此函数的底部


到这里,新的栈桢Add栈桢开始了

sub esp,8;int a,b;这里

这里声明了两个int,所以esp减小8个字节来为a,b分配空间

          mov dword ptr [esp+4], [ebp+12];  a=m

          mov dword ptr [esp], [ebp+8]; b=n     

   这样,栈的情况变为:



ret 8   ;  返回,然后8是什么意思呢,就是参数占用的字节数,当返回后,esp-8,释放参数m,n的空间

 

由此可见,通过ebp,能够很容易定位到上面的参数。当从func函数返回时,首先esp移动到栈帧底部(即释放局部变量),然后把上一个函数的栈帧底部指针弹出到ebp,再弹出返回地址到cs:ip上,esp继续移动划过参数,这样,ebp,esp就回到了调用函数前的状态,即现在恢复了原来的main的栈帧。







评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值