函数栈帧详解

本文从汇编角度观察函数栈帧发生调用中的变化
本文使用vs2013来讲述,并不建议使用vs2019等新版本,越新的版本函数栈帧相关越复杂

什么是函数栈帧

首先来了解一下:什么是函数栈帧?

栈帧是指为一个函数调用单独分配的那部分栈空间。 比如,当运行中的程序调用另一个函数时,就要进入一个新的栈帧,原来函数的栈帧称为调用者的帧,新的栈帧称为当前帧。 被调用的函数运行结束后当前帧全部收缩,回到调用者的帧。

函数栈帧

直接讲解函数栈帧未免纸上谈兵,所以这里引用下面这一块代码

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;
}

首先要先了解一个知识点 : 函数在内存中调用和运行,是由“esp”和“ebp”两个寄存器来维护的
这两个寄存器存放的是地址,分别是当前运行函数的边界的地址。

我们先来进入调试,一步一步的分析栈帧的创建以及维护。

进入main函数后,我们在“调试”中打开一个“调用堆栈”窗口。
之后我们多次F11来直接走完整个函数,之后我们发现调用堆栈中出现了两个函数
函数栈帧详解_第1张图片
用一张图来解释
函数栈帧详解_第2张图片
我们退出调试,重新在进入调试,按一下F11,
之后我们右击鼠标,来查看汇编指令
函数栈帧详解_第3张图片
这都是啥啊,为什么在第一个语句之前还有这么多奇怪的指令
这些指令其实是用来为main函数开辟栈帧

函数栈帧详解_第4张图片
F11继续调试
函数栈帧详解_第5张图片
函数栈帧详解_第6张图片

之后我们为了方便观看,右击空白处将"显示符号名"勾选去掉,之后得到的是这样
函数栈帧详解_第7张图片
我们F10走过创建三个变量:a,b,c的语句,此时我们观看内存
函数栈帧详解_第8张图片

函数栈帧详解_第9张图片
之后就要进入我们的add函数了
大的药来了!!!
函数栈帧详解_第10张图片
函数栈帧详解_第11张图片
函数栈帧详解_第12张图片
之后进入了add函数
首先仍然是给add函数创建栈帧
函数栈帧详解_第13张图片
计算,然后返回
函数栈帧详解_第14张图片
注意,如果这时候我们查看传入的形参a和b,也就是eax和ecx,你会发现这两个并不在add函数的栈帧中
大概是这样的

函数栈帧详解_第15张图片

最后执行其他的语句
函数栈帧详解_第16张图片

你可能感兴趣的:(笔记,c语言,其他)