【函数栈帧的创建和销毁】(超详细图解)(上)

简介: 【函数栈帧的创建和销毁】(超详细图解)

想必大家在学完C语言函数章节之后,是否有这样的困惑:

  • 局部变量是怎么创建的 ?
  • 为什么局部变量的值是随机值 ?
  • 函数是怎么传参的?传参的顺序又是什么样的 ?
  • 形参和实参是什么关系 ?
  • 函数调用是怎么做的 ?
  • 函数调用结束后是怎么返回的 ?

今天我们来学习函数栈帧的创建与销毁,让我们一起了解更多的底层原理,看完之后这些问题都迎刃而解了!!!

注:在不同编译器下,函数调用过程中栈帧的创建是略有差异的,具体细节诎诘语编译器的实现

演示环境:Win10+x86+Vs2013


一 .函数栈帧的创建与销毁过程


在介绍函数栈帧的创建之前,我们首先要了解一个东西--------------------寄存器


寄存器的种类有很多种,今天主要介绍两种:


ebp和esp  这两个寄存器存放的是地址,用来维护函数栈帧的,简单来说就是维护函数开辟的那一块空间

每一个函数的调用,都要在栈区开辟一块空间,而ebp和esp就是维护这块空间的,如下图:

e269a5d8dbe24514baffb731cfe3f6d3.png

为了方便演示,我们编写一个加法程序:

intAdd(intx, inty) {
intz=0;
z=x+y;
returnz;
}
intmain() {
inta=10;
intb=20;
intc=0;
c=Add(a, b);
printf("%d", c);
return0;
}

接下来就是函数栈帧的创建和销毁,这里我们需要打开反汇编代码,逐条分析:

68a033c8dff14dff9b52408ec2912fc1.png

操作步骤:F10----->光标停留在代码块处右击鼠标----->转到反汇编

main函数汇编代码:

1.intmain() {
002718A0pushebp002718A1movebp,esp002718A3subesp,0E4h002718A9pushebx002718AApushesi002718ABpushedi002718ACleaedi,[ebp-24h]  
002718AFmovecx,9002718B4moveax,0CCCCCCCCh002718B9repstosdwordptres:[edi]  
002718BBmovecx,27C003h002718C0call0027131Binta=10;
002718C5movdwordptr [ebp-8],0Ahintb=20;
002718CCmovdwordptr [ebp-14h],14hintc=0;
002718D3movdwordptr [ebp-20h],0c=Add(a, b);
002718DAmoveax,dwordptr [ebp-14h]  
002718DDpusheax002718DEmovecx,dwordptr [ebp-8]  
002718E1pushecx002718E2call002710B4002718E7addesp,8002718EAmovdwordptr [ebp-20h],eaxprintf("%d", c);
002718EDmoveax,dwordptr [ebp-20h]  
002718F0pusheax002718F1push277B30h002718F6call002710D2002718FBaddesp,8return0;
002718FExoreax,eax}
00271900popedi00271901popesi00271902popebx00271903addesp,0E4h00271909cmpebp,esp0027190Bcall0027124400271910movesp,ebp00271912popebp00271913ret

首先我们要知道,main函数也是被其他函数所调用的,它是被_tmainCRTStartup这个函数所调用,我们这里主要说明函数栈帧的创建和销毁,所以这里就不带大家介绍这个函数的由来了,如果感兴趣可以自己去翻阅一下资料------

目录
相关文章
|
XML 存储 开发工具
|
缓存 JSON 前端开发
2023年最新前端面试题汇总大全二(含答案超详细,Vue,TypeScript,React,微信小程序,Webpack 汇总篇)-- 持续更新 7
2023年最新前端面试题汇总大全二(含答案超详细,Vue,TypeScript,React,微信小程序,Webpack 汇总篇)-- 持续更新
765 0
|
编译器 程序员 C语言
精简函数栈帧:优化创建和销毁过程的完全解析(建议收藏,提升内功)
精简函数栈帧:优化创建和销毁过程的完全解析(建议收藏,提升内功)
250 1
|
10月前
|
数据挖掘 BI
大模型时代下的智能数据分析
在大模型时代,智能数据分析成为企业提升效率的关键。2024年,市场逐渐回归应用本质,客户更关注模型如何落地日常业务。瓴羊Quick BI智能小Q助手接入通义千问大模型能力,提供对话式报表搭建、一键换肤美化、智能洞察归因等高效功能,助力企业数字化转型,引领数据消费新范式。
216 4
|
SQL Web App开发 Java
java.sql.SQLException: Unsupported character encoding 'utf8mb4'.
版权声明:本文为 testcs_dn(微wx笑) 原创文章,非商用自由转载-保持署名-注明出处,谢谢。 https://blog.csdn.net/testcs_dn/article/details/76199827 四月 12, 2017 3:47:52 下午 org.
4945 0
|
前端开发 JavaScript UED
什么是组件化设计
【10月更文挑战第22天】什么是组件化设计
|
物联网 C# C语言
物联网开发中C、C++和C#哪个更好用
在物联网(IoT)开发中,C、C++和C#各有优缺点,适用场景不同。C语言性能高、资源占用低,适合内存和计算能力有限的嵌入式系统,但开发复杂度高,易出错。C++支持面向对象编程,性能优秀,适用于复杂应用,但学习曲线陡峭,编译时间长。C#易于学习,与.NET框架结合紧密,适合快速开发Windows应用,但性能略低,平台支持有限。选择语言需根据具体项目需求、复杂性和团队技术栈综合考虑。
|
消息中间件 存储 监控
|
安全 前端开发 JavaScript
什么是跨域?为什么会产生跨域?怎么解决跨域?
什么是跨域?为什么会产生跨域?怎么解决跨域?
2065 0
|
存储 程序员 编译器
深入理解函数调用--函数栈帧
深入理解函数调用--函数栈帧