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

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

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

函数栈帧

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("%dn",c);
	return 0;
}

分析main函数的反汇编








到此为止,main函数开辟好了

Add函数调用前的准备

因此我们讲形参是实参的一份临时拷贝
存放call指令下一条指令的地址

调用Add函数
Add返回值
每pop一次esp往下方走一次


然后ebp和esp都回到了main函数开辟后的地方,再通过存着的地址找到了call的下一条语句再继续执行
然后把return的值赋值给c
打印出来就结束啦

4. 总结

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

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

欢迎分享,转载请注明来源:内存溢出

原文地址: http://outofmemory.cn/zaji/5714552.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2022-12-17
下一篇 2022-12-17

发表评论

登录后才能评论

评论列表(0条)

保存