函数栈帧-函数的调用过程

           在说栈帧之前,我们先谈谈C语言中的函数,我们在写C代码的时候会发现每一个程序都会有一个main函数,而在我们上C语言课的时候一般老师都会说:我们的C程序执行过程中,首先第一个执行的是main函数。而一个C程序在执行过程中是不是执行的第一个函数是main函数呢?来看一段简单的代码:

#include<stdio.h>
#include<Windows.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("%d\n", ret);
	system("pause");
	return 0;
}

我们进行调试,看看它的【调用堆栈】:

                                                      图-1



我们发现其实main函数在_tmainCRTStartup函数中被调用,而_tmainCRTStartup函数是在mainCRTStartup中被调用的。所以C程序运行的过程中main函数其实并不是第一个执行的函数,它只是我们C程序的入口函数(区别)。

然而我们知道,在执行C程序的时候CPU会为我们开辟一个地址空间(图-2),而函数的调用过程CPU要为函数开辟“栈”空间(用于本次函数的调用过程中临时变量的保存、现场保护)的,函数调完“栈”空间也随之释放,这块“栈”空间就是我们所说的“函数的栈帧”。


                                        图-2

接下来看看具体函数调用过程:

首先介绍过程中要用到的一些相关的寄存器和指令:

ebp (栈底寄存器)———指向当前的栈帧的底部(高地址)

esp(栈顶寄存器)————指向当前的栈帧的顶部(低地址)

eip(PC,程序计数器)——存储着cpu要读取指令的地址,没有它,cpu就无法执行

eax,ebx,ecx,edx(通用数据寄存器)————主要用来保存操作数和运算结果等信息,从而节省读取操作数所需占用总线

和访问存储器的时间

call:用于保存当前指令的下一条指令并跳转到目标函数。

push:入栈(push   寄存器    保护数据)。

pop:出栈。

ret:使得出栈一次,并将出栈的内容修改EIP。将程序执行跳转到该地址处。

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


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


3、进入Add函数:



4、剩下是函数返回部分:


以上就是函数调用的整个过程


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值