函数栈帧的概念:
每一次调用函数调用都是一个过程,这个过程通常称为函数的调用过程,这个过程要为函数开辟栈空间,用于本次函数的调用中临时变量的保存、现场保护,这块栈空间就称为函数栈帧。
寄存器:
esp:栈顶指针 ,存储的是栈顶的地址
ebp:栈底指针,存储的是栈底的地址
针对以下代码进行分析:
#include<stdio.h>
int Add(int x,int y)
{
int z = 0;
z = x + y;
return z;
}
int main()
{
int a = 10;
int b = 20;
int ret = 0;
ret = Add(a,b);
printf("ret = %d\n",ret);
return 0;
}
要点:
1.当还没有调用main()函数时,先调用的是mainCRTStartup()函数。
2.在这里,栈空间中,是由高地址走向低地址,所以,下面的是高地址,上面的是低地址。
3.每压栈一次,esp都进向上移动一次,每开辟一次空间ebp,esp都要向上移动一次
4.lea:加载有效地址
5.在内存中访问一个变量的时候往往采用的是首地址,然后往下加
6.在call指令处f11键才能进入所调用的函数
7.当每次要为一个函数新开辟一个空间时,就要挪动ebp,esp,但是也要上一个函数的具体ebp,esp的信息,而新的ebp是原来的esp,
这样就能知道之前函数的esp,但是ebp需要保存起来,也就是每次重新为一个函数开辟空间时,先要做的是要保存原来函数的ebp的地址,这样才能找到原来的函数。
8.形参和实参创建的并不在同一个空间,所以说形参是实参的一份临时拷贝。所调用的函数是不会创建形参的,是在main函数中创建形参的。
当使用形参的时候,是找回在main函数中所创建的形参的地址,然后进行计算,而函数中创建的临时变量的值最后是通过寄存器带回来的
所以说形参的改变根本不会影响实参,因为他们存在于不同的空间。
9.函数传参的时候,是从右向左传递的
图解如下: