函数的调用(栈帧的创建和销毁)

以下面这段代码为例:

 #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函数栈帧空间释放(每返回一个值意味着释放一个空间),临时变量都存在栈帧结构中

猜你喜欢

转载自blog.csdn.net/weixin_40909099/article/details/78702786