函数的调用过程(栈帧)

为什么要有函数


函数就是一系列C语句的集合,为了完成某个会重复使用的特定功能。

需要该功能的时候,直接调用该函数即可,不用每次都堆叠一大堆的代码;

需要修改该功能的时候,也只要修改和维护这一个函数即可。

总之,将语句集合成函数,好处就是方便代码重用。并且,一个好的函数名,

可以让人一眼就知道这个函数实现的是什么功能,方便维护。

##函数的调用过程

那我们深入的研究一下函数的调用过程

先看看下面这段代码,当我们进行调试的时候,查看【调用堆栈】
#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 = Add(a, b);
 printf("ret = %d\n", ret);
 return 0;
}

这里写图片描述
- 查看调用堆栈,我们可以发现其实 main 函数在_tmainCRTStartup 函数中 调用的,
而_tmainCRTStartup函数在 mainCRTStartup 被调用的

- 每一次函数调用都是一个过程,通常称为:【函数的调用过程】

- 函数要跑起来的话,它要向内存申请一段空间;而这段空间在栈上开辟,那么这块
栈空间我们称之为【函数栈帧】;记住栈的使用顺序是由高地址到低地址。

- 我们平时知道的寄存器有eax,ebx,ecx,edx;
 
- 还有两个ebp和esp,在函数调用的过程中这两个寄存器存放了维护这个栈的
栈底和栈顶指针。来维护开辟出这段地址的起始和结尾的内存地址。

######调用main函数,我们要为main函数分配栈帧空间,栈帧维护如下:
这里写图片描述
######ebp指向了函数栈帧栈底的地址;esp指向了函数栈帧栈顶的地址。
当我们要详细的研究函数调用过程,必须得对应汇编代码。

从main函数开始,要展开main函数的调用就得为main函数创建栈帧。
那我们先来看main函数栈帧的创建;

这里写图片描述

接下来是Add函数的调用。参数传递过程:

这里写图片描述

执行call指令的时候按F11,来到了这里

这里写图片描述

再按F11就进入Add函数的执行代码处

这里写图片描述

剩下的是函数返回部分

这里写图片描述

栈帧这部分内容在不同的编译器上实现存在差异,但是思想是一致的
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值