函数调用和栈帧

今天学习了函数的调用过程,下面对它做个总结。

储备知识:
1.C程序地址空间如图:

其中,堆、栈相向而生。

栈具有“先进后出”的特点,因为栈向低地址方向生长,所以先进栈的数据比后进去的数据地址高。

2.与栈有关的几个寄存器:
(1)eip:程序计数器,保存当前正在执行指令的下一条指令的地址。CPU通过eip来确定函数执行的位置。
(2)ebp:指向栈底
(3)esp:指向栈顶
(4)eax、ebx、ecx、edx等用于存储数据

3.函数的调用就是开辟栈帧的过程,返回函数即释放栈帧的过程。因此,在函数内部定义的变量具有临时性。

4.与栈有关的几个汇编指令:

(1)push:进栈     (2)pop:出栈  
(3)call:调用函数,主要有两个功能:保存当前正在执行指令的下一条指令的地址;跳转到另一个函数,通过jmp命令修改eip.  (4)ret:pop出返回值,修改eip.    (5)jmp:实现函数的跳转。
5.形参实例化:在被调用的函数中,形参是由右向左进栈的,所以离函数名越近的变量,地址越低。

扫描二维码关注公众号,回复: 3458899 查看本文章

具体分析:
如下面一段代码:
#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 c=fun(a,b);
 printf("you should run here!%d\n",c);
 return 0;
}
下面是它的汇编截图:
下图是我对函数调用的理解:

通过对函数调用的理解分析,我还知道了为什么说函数内部的变量具有临时性,这是因为调用一个函数就是形成栈帧的过程,返回一个函数就是释放栈帧的过程,而函数内部的变量都在该函数的栈帧结构里。但是函数的返回值也是函数内部的变量,它是通寄存器eax返回的,不受栈帧创建和释放的影响。



猜你喜欢

转载自blog.csdn.net/smell201611010513/article/details/79943198