栈帧–函数的调用过程
每一次函数调用都是一个过程,这个过程称为函数的调用过程,这个过程要为函数开辟栈空间,用于本次调用中存放临时变量和保护现场,这块栈空间称之为函数栈帧。
所以调用函数的成本要花时间和空间。
函数中的局部变量–需要时开辟,运行完毕时释放,在栈区。
static修饰的变量----程序运行完毕时,变量也一直在,静态区 。
- 函数可以传参,也可以不传参,一旦传参,就会形成临时变量,临时变量具有临时性,即调用完毕就会释放
- main函数被tmainstarup函数调用,main函数也会开辟栈帧。
- 调用函数形参实例化 是从右往左的。
int fun(intx ,int y)
{
return x+y;
}
int main()
{
int x = 0;
int y = 0;
int c = fun(x,y); //形参实参的地址不同,那么形参的地址在哪里?
}
比如以上的代码,先调用main函数,进入main函数后跳转到fun函数,即先保存EIP的内容,然后修改为fun函数的入口地址,所以函数调用的本质就是修改EIP的值。main函数的临时变量在main函数的栈帧中,调用完毕函数后,栈帧释放 ,所以临时变量具有临时性。
EIP—程序计数器,存放下一条指令的地址,函数跳转的本质就是将目标函数的入口地址写入EIP中,但在这步之前,应该要先保存EIP之的内容,目的是能够在调用完目标函数后可以恢复。
call命令的作用:
将当前正在执行的指令进行入栈保存;覆盖EIP内容然后跳转到目标函数
三个寄存器
EIP–程序计数器
EBP–栈底寄存器
ESP–栈顶寄存器