以下面这段代码为例:
#include <stdio.h>
int fun(int x, int y)
{
int z = 0;
z = x + y;
return z;
}
int main()
{
int a = 0xAAAAAAAA;
int b = 0xBBBBBBBB;
int ret = fun(a, b);
printf("ret = %d\n", ret); return 0
}
我们知道每一次函数调用都是一个过程,这个过程称为:函数的调用过程。
这个过程要为函数开辟栈空间,用于本次函数的调用中临时变量的保存,现场保护,这块栈空间我们称为函数栈帧
栈的存储在内存中是由高地址到第地址
在栈结构中,esp存放了栈顶地址,ebp存放了栈底地址,eip目前存放的是maincode。然后要在栈结构中存放变量,按照形参实例化的特点(从右向左)把b的值放入eax寄存器,然后push压栈(往栈顶push),然后把a的值放入ecx寄存器然后push ecx。
接下来调用(call的作用:1, 将当前执行命令的下一条指令的地址压入栈中(保存返回值)2.跳转至指定函数(jmp))
跳转至fun函数,此时eip寄存器存放的是funcode,首先将ebp push入栈底,esp向下移动,此时形成了fun函数的栈帧
然后将ebp+8(a的值)放入eax中,将ebp+12(b的值)加到eax,eax移动到ebp
-4中(fun函数的栈帧),return z(z赋值给eax),将ebp的内容赋给esp将然后pop(出栈)ebp
接下来ret(1.弹出栈顶,将栈顶的值弹出2.弹出栈顶的值放入eip) esp上移至main函数栈顶,ebp向下移动,将eax的值放入c中,至此函数调用已经完成 ,函数调用完毕fun函数栈帧空间释放(每返回一个值意味着释放一个空间),临时变量都存在栈帧结构中