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

函数栈帧

1. 全局观:

修炼内功——理解函数栈帧创建和销毁_第1张图片
今天我们讲的是栈区,以下的图上方是低地址,下方是高地址,跟上图相反,因此使用顺序是从下方到上方,跟上图本质上一致。

2. 函数的调用关系

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

每一个函数调用都要在栈区开辟空间。修炼内功——理解函数栈帧创建和销毁_第2张图片
在VS2013中,main函数也是被其他函数调用的,调用关系如下图修炼内功——理解函数栈帧创建和销毁_第3张图片
修炼内功——理解函数栈帧创建和销毁_第4张图片

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函数的反汇编修炼内功——理解函数栈帧创建和销毁_第5张图片

修炼内功——理解函数栈帧创建和销毁_第6张图片
修炼内功——理解函数栈帧创建和销毁_第7张图片
修炼内功——理解函数栈帧创建和销毁_第8张图片
修炼内功——理解函数栈帧创建和销毁_第9张图片
修炼内功——理解函数栈帧创建和销毁_第10张图片
修炼内功——理解函数栈帧创建和销毁_第11张图片
修炼内功——理解函数栈帧创建和销毁_第12张图片
到此为止,main函数开辟好了
修炼内功——理解函数栈帧创建和销毁_第13张图片

Add函数调用前的准备修炼内功——理解函数栈帧创建和销毁_第14张图片

因此我们讲形参是实参的一份临时拷贝
存放call指令下一条指令的地址修炼内功——理解函数栈帧创建和销毁_第15张图片

调用Add函数修炼内功——理解函数栈帧创建和销毁_第16张图片
Add返回值
每pop一次esp往下方走一次
修炼内功——理解函数栈帧创建和销毁_第17张图片
修炼内功——理解函数栈帧创建和销毁_第18张图片
然后ebp和esp都回到了main函数开辟后的地方,再通过存着的地址找到了call的下一条语句再继续执行
然后把return的值赋值给c
打印出来就结束啦

4. 总结

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

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

你可能感兴趣的:(c语言,修炼内功,c语言)