问题:我们为什么要了解函数栈帧的创建与销毁?
走进代码逻辑的底层,了解更深层次的知识,增长见识
导入:
注意:接下来的讲解中使用的是VS2013,原因是编译器越低级,越容易观察到函数栈帧创建与销毁的过程,编译器越高级,越不容易观察
首先介绍一下寄存器,有eax, ebx, ecx, edx, esp, ebp
esp, ebp接下来会提及,这两个寄存器存储的是地址,存储的地址是用来维护函数栈帧的
1.在内存中地址的从高到低使用的
2.这里的esp(栈顶指针), ebp(栈底指针)维护的就是main函数的栈帧(为main函数所开辟的一块空间)
3.函数的每一次调用,都要在栈区上开辟一块空间
main函数被__tmainCRTStartup调用
__tmainCRTStartup被mainCRTStartup调用
这是底层的逻辑,所以理解main函数也是被其他函数调用的
这三步的意思就是为main创建栈帧
push--->压栈
mov--->将esp的地址赋给ebp
sub--->将esp的地址减去0E4h(一个16进制的数字,其实就是main函数的栈帧大小)
这四步的意思是将main函数的内容全部赋给CCCCCCCC,不同编译器下赋予的值不一样,这也就是为什么创建变量未初始化的时候编译器给的是随机值,就是CCCCCCCC的结果,所以在创建好一个变量的时候要初始化,养成一个好习惯
到这里为止才只是为main函数创建好栈帧,其他变量还没有开始创建
这三步是为a, b, c变量分配空间
a, b, c所占的空间是在main函数里开辟的,注意,为每个局部变量开辟空间时,每个变量中间隔着2个字节的空间
函数传参的过程,先传 b , 再传 a
这里的 call ,与上文相呼应,即函数值返回的过程
00C21450为函数返回埋下伏笔
完成加法运算的过程 ,通过地址找到 a' , b'
如何2返回值的呢?局部变量在出函数之后不是会被销毁吗?
加好的值z是存储在寄存器eax里面的,由寄存器返回给main函数,这就是函数的返回过程
函数调用完之后栈帧的销毁过程,将ebp的地址赋给esp,Add函数的栈帧归还,空间释放
pop--->将ebp弹出,形参 a , b 的空间也释放
这就是 函数栈帧创建与销毁的全过程,感谢观看