修炼内功——理解函数栈帧创建和销毁

函数栈帧

1. 全局观:

在这里插入图片描述
今天我们讲的是栈区,以下的图上方是低地址,下方是高地址,跟上图相反,因此使用顺序是从下方到上方,跟上图本质上一致。

2. 函数的调用关系

ebp,esp这两个寄存器中存放的是地址,这两个地址是用来维护函数栈帧的。调用哪个函数就维护哪个函数栈帧

每一个函数调用都要在栈区开辟空间。请添加图片描述
在VS2013中,main函数也是被其他函数调用的,调用关系如下图请添加图片描述
请添加图片描述

3. 分析一段代码


int Add(int x, int y)
{
	int z = 0;
	z = x + y;
	return z;
}

int main()
{
	int a = 10;
	int b = 20;
	int c = 0;

	c = Add(a, b);

	printf("%d\n",c);
	return 0;
}

分析main函数的反汇编请添加图片描述

请添加图片描述
请添加图片描述
请添加图片描述
请添加图片描述
请添加图片描述
请添加图片描述
请添加图片描述
到此为止,main函数开辟好了
请添加图片描述

Add函数调用前的准备请添加图片描述

因此我们讲形参是实参的一份临时拷贝
存放call指令下一条指令的地址请添加图片描述

调用Add函数请添加图片描述
Add返回值
每pop一次esp往下方走一次
请添加图片描述
请添加图片描述
然后ebp和esp都回到了main函数开辟后的地方,再通过存着的地址找到了call的下一条语句再继续执行
然后把return的值赋值给c
打印出来就结束啦

4. 总结

这里我们可以了解到除了蹦出去还要留下地址供自己找回来
以及为什么不初始化的变量会打印出“烫烫烫”(因为开辟时会把空间初始化成cccccccc)
还有传值调用时形参是实参的一份拷贝,因此会比传指调用占用更多空间

希望大家能更深层理解函数栈帧创建和销毁

  • 31
    点赞
  • 10
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 26
    评论
评论 26
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

天影云光

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值