IT数码 购物 网址 头条 软件 日历 阅读 图书馆
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
图片批量下载器
↓批量下载图片,美女图库↓
图片自动播放器
↓图片自动播放器↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁
 
   -> C++知识库 -> C语言深层次的修炼——函数栈帧的创建与销毁 -> 正文阅读

[C++知识库]C语言深层次的修炼——函数栈帧的创建与销毁

在这里插入图片描述

栈帧是什么

不知大家接触过 “栈帧” 这个词没有,我第一次听以为是函数战争,心里怎么想也想不明白,战争(栈帧)是什么鬼????
然后我理解后才明白 栈(Stack)简单说, 是由于函数运行而临时占用的内存区域。而帧是函数开辟的会为它在栈上建立一个帧(frame)
我们了解后,那栈帧有什么用呢?
其实我们在学习C语言的时候会用很多的疑问,比如:
1.main函数肯定是要被调用的,那是被谁调用的呢?
2.函数里面的局部变量是怎么创建的?
3.局部变量又为什么是默认是随机值?而全局变量默认却是0?
4.函数是怎么传递参数的?参数的顺序又是怎么样的?
5.函数调用详细过程是怎么样的?调用后是怎么返回的?
让我们带着上面的疑问来一步步刨析吧。

大概轮廓

既然用到了函数,那我们就写一个简单的加法函数来看看过程是怎么样的吧。代码如下:

#include <stdio.h>
int Add(int x,int y)
{
	int z=0;
	z=x+y;
	return z;
}
int main()
{
	int a=2;
	int b=3;
	int c=0;
	c=Add(a,b);
	printf("%d ",c);
	return 0;
}

先说明一下我平常用的环境是vs2019,但是vs2019封装细节太多了,不容易看到整个汇编过程,所以这里我用的是 vs2010版本,由于环境不同,下面讲解的一些细节方面略有差异,但大体逻辑是不变的。
我们先来回答第一个问题,main函数是被谁调用的,
在这里插入图片描述
在这里插入图片描述

当调试的光标移动到这里,我们按F11返回调用main函数的函数,发现了调用main函数的是 __tmainCRTStartup函数 而这个函数又是被 mainCRTStartup函数调用的。
而函数是在栈上是靠寄存器 esp(栈顶指针)和ebp(栈底指针)来维护的,并且在栈区是是先使用高地址再使用底地址的,图片分析如下:
在这里插入图片描述
这就是main函数和Add函数在栈区上的大概轮廓,下面再让我们带着问题刨析main函数的具体创建过程。

函数创建过程

先让我们看看main函数的汇编是怎么样的?
在这里插入图片描述
调试到汇编:
在这里插入图片描述

接下来就是一步步的分析了,话不多说上图:
在这里插入图片描述
所以就解释了函数里面局部变量的创建过程,以及为什么局部变量会是随机值。
当main函数创建好变量后就要开始调用Add函数了,我们再分析又是怎么调用的
图片如下:
在这里插入图片描述

总之函数的创建是一步步的压栈过程,已经ebp 和esp 指针的变化过程。
所以函数的传参过程是先从后面开始时传的,先拷贝b再拷贝a,
形参存放在实参的那个函数当中的。
并且函数的形参只是实参的一份临时拷贝,改变形参不会影响实参。

函数销毁过程

函数创建执行相对于的功能后要销毁的,那是怎么样销毁呢?
其实函数的栈帧是靠esp 和ebp 指针来维护的,我们只要把ebp 赋值给 esp那么esp 和原来压进来的ebp 又维护能上一层的函数了。分析图片如下:

在这里插入图片描述

好了,分析到这里整个函数的过程就大概就是这样了,大家对开始的问题是不是已经有答案了呢?欢迎大家在评论区补充和留言。
在这里插入图片描述

  C++知识库 最新文章
【C++】友元、嵌套类、异常、RTTI、类型转换
通讯录的思路与实现(C语言)
C++PrimerPlus 第七章 函数-C++的编程模块(
Problem C: 算法9-9~9-12:平衡二叉树的基本
MSVC C++ UTF-8编程
C++进阶 多态原理
简单string类c++实现
我的年度总结
【C语言】以深厚地基筑伟岸高楼-基础篇(六
c语言常见错误合集
上一篇文章      下一篇文章      查看所有文章
加:2021-08-09 10:03:37  更:2021-08-09 10:03:50 
 
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁

360图书馆 购物 三丰科技 阅读网 日历 万年历 2024年5日历 -2024/5/9 15:26:07-

图片自动播放器
↓图片自动播放器↓
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
图片批量下载器
↓批量下载图片,美女图库↓
  网站联系: qq:121756557 email:121756557@qq.com  IT数码