函数栈帧(简易理解篇)

要理解函数栈帧,就必须要明白两个寄存器esp和ebp

首先先贴一段百度百科关于寄存器的定义,但对于理解函数栈帧来说,我们只要大概明白两个寄存器esp和ebp。寄存器是在cpu上的一个相对其他存储空间较小的存储器,它能快速的读取和存储数据,而我们所需要的两个寄存器就是通过存储地址来维护函数

每一个函数的创建都需要在栈区开辟一个空间

而我们的两个寄存器,esp存储函数的在栈区的栈顶地址,ebp存储栈底的地址,这样通过两个地址我们就可以对其中的栈区进去维护在其中存放变量,从而达到我们函数的功能。

 于是我们通过开辟一个栈空间,为一个函数就留好了属于它自己的舞台,每一个函数都要属于它们自己的栈空间,而寄存器却只有两个所以当我们调用不同的函数时,我们就可以很好的解释为什么其他函数的地址就找不见了(因为寄存器只能对同时一个函数进行维护)函数的独立性就可以解释了。

下面,我们就来探讨传值调用和传址调用本质吧

int main()
{
int a=3,b=4;
int ret=Add(a,b);//以调用函数Add实现求加法来举例
return 0;
}

当编译器读到这一步时,此时,寄存器还在维护主函数中并已经对a,b两个变量在栈区开辟一个地址空间存储它们的值(中间的其他过程为了陈述方便进行省略,请谅解)

 

当编译器将要读取Add函数这一步时,先会用其他寄存器将a,b的值暂时存储起来,就像这样

 

 当我们进入add函数中时寄存器也开始维护Add函数,在执行这个之前要将主函数的位置存下,以便调用结束时返回主函数

 让我们先忘记主函数吧,现在寄存器眼里只有Add函数了。

注意函数中的形参是不会存进Add函数的栈区的,而是在栈区中创建一个空间来保存返回值的值,新建的变量空间由高到低创建(所有函数都是按照这个顺序存放变量的,包括主函数)

 进行完存值后,我们所需的新参便从原来的寄存器中读取值返回到返回值的空间中,最后将返回值压栈到eax中存储。然后将Add函数回收再将ebp的地址给esp,让头返回,然后将尾ebp弹出,到呢个地址处,ebp就返回到函数中了,调用Add函数结束,最后ret的值等于eax中存储的值。

上述仅代表本人浅显的见解,如有错误欢迎大家的指正!

 

 

评论 4
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Caking—coding

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值