C语言——函数栈帧的创建和销毁

news2024/10/6 18:20:31

Hello,好久没有写博客了,前两份都是之前写的,看来最近有点懈怠,最近也得快点找回学习的状态,那今天开始我们新的讲解

在我们刚开始学习C语言的时候,不知道大家有没有困惑,比如我们在使用局部变量的时候,他是怎么创建的呢

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

带着这些疑问,我们开始来介绍函数栈帧的创建和销毁

先给大家普及一个知识,就是我们的寄存器
要了解我们的函数栈帧,最主要的是ebp和esp,这两个寄存器存放的是我们的地址,是来维护函数栈帧的。在我们函数调用的时候,每一次都会创建函数栈帧来维护这个函数。

#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 c = 0;
	c = Add(a, b);
	printf("%d\n", c);
	return 0;
}

在这里插入图片描述
我们先使用的是main函数,ebp,和esp就是来维护这个函数栈帧的,ebp我们可以认为栈低指针,esp我们可以认为栈顶指针,而我们下一次函数调用的时候是在上面开辟函数栈帧,每一次调用都会开函数调用

其实我们的main函数也是被调用的

下面我们看函数的一个反汇编

在这里插入图片描述
在这里插入图片描述
因为我们的main函数也是被调用的,所以在调用之前也会开辟一个栈帧,我么来看一下这个图

在这里插入图片描述
我们在看下一条指令
在这里插入图片描述
因为我们在调用main函数的时候进行压栈,压入一个ebp,ebp中存放的是下面那个ebp的地址,而指令中的mov,就是将esp的值给了ebp,所以其实现在esp和ebp应该指向同一个地址
在这里插入图片描述

图是这样的

我们在看下一步
在这里插入图片描述
所以我们的esp指向上面的一个位置
在这里插入图片描述
那就意味着现在我们给main函数开辟了一个空间,这个空间其实很大的

继续看下面指令

在这里插入图片描述
我们不用关心这个值是有什么用,其实也是代表寄存器的,我们先不用关心,只要知道我们push三个值进去。

在这里插入图片描述
压栈进去,esp也变了

下一条指令更像是初始化,其实应该是下面的三条指令,首先看我们的lea,其实它的意思就是load effective address,是加载有效地址的意思,就是将后面的【ebp-0E4h】加载到edi里面去,edi是什么,它就是我们刚刚压栈进去的值

在这里插入图片描述
啥意思,就是相当于在栈帧中初始化
在这里插入图片描述

在这里插入图片描述
上面这么多内容都是我们给main函数开辟函数栈帧,还没进入我们main函数里头,现在我们才算是刚刚进入

在这里插入图片描述

这一步的操作就是赋值,将我们的0Ah赋值给我们的ebp-8,0Ah就是我们的变量a的10,而ebp减8,就是说明我们的ebp又要开始网上移动八个位置,在这八个位置中,我们创建变量a

所以大家可能就明白我们有时候创建一个变量的时候,有时候会给它初始化,否则就会自动初始化ccccccc,就是我们的随机值

在这里插入图片描述
后面的几个创建变量也一样,就在图里显示了

这些都做完后,我们才开始调用我们的add函数
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
上面还push两个值

在这里插入图片描述
这就是我们的传参,看到这大家是不是也明白一个问题那就是函数int Add(int x, int y)应该是y先得到b得值,从后往前

传完参数也应该进入我们得函数当中了
在这里插入图片描述
可以看到call就是调用,其实就是我们在调用得时候还压了一个地址进去,也不能完全说压入地址,就相当于我们得编译器记住这个地址,原因是我们函数需要返回,所以call指令下一条指令得地址我们记住了

在这里插入图片描述
在这里插入图片描述
同样我们进入add函数,也要给它开辟栈帧,我们要先放入main函数的ebp,以便函数返回的时候能找到

在这里插入图片描述
和上面开辟main函数差不多,就写在图里了
在这里插入图片描述
这一步就是把我们的z初始化放在ebp-8的位置

在这里插入图片描述

在这里插入图片描述
执行我们的加法,这里其实就很巧妙,我们看到ebp+8的位置其实就是我们的变量a的位置
在这里插入图片描述

将a的值10赋值到eax后,下一步操作将[ebp+0Ch]的值加到eax上,而这里的[ebp+0Ch]刚好是我们保存的形参b的值20,这里将b的值加上去也就是得到了30.所以现在eax存放的值是30!紧接着我们将eax的值赋值给[ebp-8],而大家还记不记得,其实这里的[ebp-8]就是我们之前给C的一块空间,所以这里就是将eax的值30赋值给变量z,z现在也就变成了30.
在这里插入图片描述
在这里插入图片描述
这样我们的函数add调用就结束,那我们要开始返回了

写道这里大家是否明白我们的形参其实是实参的一份临时拷贝,改变形参,并不能对实参产生影响,讲到这里,相信聪明的大家肯定明白了
在这里插入图片描述
那我们现在开始返回,因为我们出栈就销毁,如果销毁的化我们的z不就是白算了吗,所以我们现在给它放入我们的寄存器当中去,这样就安全了
那我们现在要开始返回了
pop就是出栈的意思,上面的值会一步一步的销毁

在这里插入图片描述

这样我们就把edi esi ebxpop出去了
同时我们的esp也会往下移动

那完成这些之后,我们add函数栈帧也会销毁

在这里插入图片描述

这个时候我们的esp返回的ebp位置,这就是为什么我们之前要保留这个位置的原因,就是方便它返回
在这里插入图片描述
所以当执行完这个后我们的ebp和esp应该维护的是我们main函数开辟的栈帧了
在这里插入图片描述
现在也就知道为什么call指令下面要放个地址,这就是便于我们返回,这样我们的add函数算数彻底调用返回了

讲到这里,相信大家应该就明白我们函数调用的整个过程,相应的main函数也是一样的道理,这里就不过多讲解了。那我们一开始的问题也迎刃而解了

本篇文章可能会有一些小问题,因为这个所需要的图太多,讲起来也比较费劲,也希望有错误的地方请大家及时指出,谢谢大家,今天的分享就到这里了,希望通过这篇文章,大家能对c语言继续保持热爱

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/816979.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

vue 表单form-item模板(编辑,查看,新建)

目录 formatFormData 后端数据格式​编辑 JSON解析和生成 加载&#xff08;请求前&#xff0c;await后&#xff09; formComp formatFormData 后端数据格式 为空的&#xff0c;可以直接不提交/提交null/undefined JSON解析和生成 var str {"name": "…

ERROR: No matching distribution found for wxpyhton

ERROR: No matching distribution found for wxpyhton pip install 库包名 -i http://pypi.douban.com/simple/ --trusted-host pypi.douban.compip install wxpython -i http://pypi.douban.com/simple/ --trusted-host pypi.douban.com

Voicebox:文本引导的大规模多语言通用语音生成

说白了就是录一段你的声音&#xff0c;在最短的时间内学会你说话&#xff01; Meta AI研究团队模型&#xff0c;Voicebox是一个文本转语音的工具&#xff0c;具有多种功能和应用。根据提供的搜索结果&#xff0c;以下是Voicebox的一些功能和特点&#xff1a; 多语言支持&…

语义分割、转置卷积、风格迁移(第十二次组会)

TOC 语义分割 图像分割、实例分割 上采样、下采样 转置卷积 全卷积网络 风格迁移

操作系统_进程与线程(四)

目录 4. 死锁 4.1 死锁的概念 4.1.1 死锁的定义 4.1.2 死锁产生的原因 4.1.3 死锁的处理策略 4.2 死锁预防 4.3 死锁避免 4.3.1 系统安全状态 4.3.2 银行家算法 4.3.2.1 数据结构描述 4.3.2.2 银行家算法描述 4.3.2.3 安全性算法 4.3.3 安全性算法举例 4.3.4 银行…

【EI/SCOPUS会议征稿】第三届物联网与机器学习国际学术会议(IoTML 2023)

第三届物联网与机器学习国际学术会议&#xff08;IoTML 2023&#xff09; 2023 3rd International Conference on Internet of Things and Machine Learning 2023年物联网与机器学习国际学术会议&#xff08;IoTML 2023&#xff09;将于2023年9月15-17日在新加坡召开。会议…

安装华为模拟器

安装前需要安装虚拟机 虚拟机安装 下一步 立即安装 安装驱动 完成 一路下一步 安装完成后拖动一个2240启动

【Liux下6818开发板(ARM)】实现简易相册

(꒪ꇴ꒪ ),hello我是祐言博客主页&#xff1a;C语言基础,Linux基础,软件配置领域博主&#x1f30d;快上&#x1f698;&#xff0c;一起学习&#xff01;送给读者的一句鸡汤&#x1f914;&#xff1a;集中起来的意志可以击穿顽石!作者水平很有限&#xff0c;如果发现错误&#x…

Linux NameSpace 虚拟化 资源隔离

NameSpace NameSpace介绍 在操作系统中命名空间命名空间提供的是系统资源的隔离&#xff0c;其中系统资源包括了&#xff1a;进程、网络、文件系统等等 实际上linux系统实现命名空间主要目的之一就是为了实现轻量级虚拟化服务&#xff0c;也就是我们说的容器&#xff0c;在同…

分享一个赛车动画

先看效果&#xff08;动画太大了放不上来&#xff0c;甘心去复制代码运行即可&#xff09;&#xff1a; 再看代码&#xff1a; <!DOCTYPE html> <html lang"en"> <head><meta charset"UTF-8"><title>赛车</title><…

AD21 PCB设计的高级应用(六)极坐标的应用

&#xff08;六&#xff09;极坐标的应用 在 PCB 设计过程中,特别是 LED圆形灯板的 PCB 设计,需要对 LED灯珠进行圆形等间距排列,如果每个元件都计算清楚其坐标再进行放置会非常烦琐。要实现如图 所示的元件布局效果,在 Altium Designer 软件里可以使用极坐标的方法。 (1)打开…

Vue2 第十一节 Vue的生命周期

1.生命周期的概念 2.生命周期流程图 3.生命周期分析 一.生命周期概念 生命周期又称为生命周期回调函数&#xff0c;生命周期函数&#xff0c;生命周期钩子是Vue在关键时刻帮我们调用的一些特殊名称的函数生命周期函数的名字不可更改&#xff0c;但函数的具体内容是程序员根…

【低代码开发】:加速应用开发的未来趋势

低代码开发&#xff1a;加速应用开发的未来趋势 引言什么是低代码以及功能特点&#xff1f;什么是低代码开发&#xff1f;低代码平台的特点和功能低代码平台的应用场景和优势低代码的优点低代码的缺点低代码平台项目开发流程选择和实施低代码平台 低代码未来的发展趋势低代码平…

MyBatis缓存-提高检索效率的利器--一级缓存

&#x1f600;前言 本篇博文是关于MyBatis一级缓存的介绍使用和缓存失效情况分析&#xff0c;希望能够帮助到您&#x1f60a; &#x1f3e0;个人主页&#xff1a;晨犀主页 &#x1f9d1;个人简介&#xff1a;大家好&#xff0c;我是晨犀&#xff0c;希望我的文章可以帮助到大家…

c++基础知识(inline、auto、nullptr)

⭐️ 内联函数 &#x1f4ac; 为什么会有内联函数&#xff1f;   内联函数其实是为了弥补 c 的缺陷&#xff0c;比如当我们遇到了一些少量逻辑和代码的情况时&#xff0c;而这些少量的代码又需要被重复使用多次&#xff08;swap&#xff09;&#xff0c;我们往往会封装成为一…

linux快速安装tomcat

linux快速安装tomcat 前提安装好jdk 下载Tomcat安装包 wget https://dlcdn.apache.org/tomcat/tomcat-10/v10.0.27/bin/apache-tomcat-10.0.27.tar.gz如果出现颁发的证书已经过期的错误提示,用下面命令 wget --no-check-certificate https://dlcdn.apache.org/tomcat/tomcat-1…

剑指 Offer 第二版

剑指 Offer 第二版 文章目录 剑指 Offer 第二版[剑指 Offer 06. 从尾到头打印链表](https://www.nowcoder.com/practice/d0267f7f55b3412ba93bd35cfa8e8035?tpId13&tqId23278&ru/exam/oj/ta&qru/ta/coding-interviews/question-ranking&sourceUrl%2Fexam%2Foj…

区块链实验室(13) - 在PBFT中节点的度与其流量的特征

前面若干实验说明了PBFT的耗时、流量与度的特征&#xff0c;见 区块链实验室(10) - 实例说明PBFT的共识过程, 区块链实验室(11) - PBFT耗时与流量特征, 区块链实验室(12) - 网络拓扑对PBFT共识流量的影响 同样的实验方案&#xff0c;在100个节点构成的无标度网络中完成100次交…

html学习4(区块、布局)

1、<div> 是块级元素&#xff0c;它独占一行&#xff0c;可以设置宽度、高度以及边距等样式属性。它适合用于创建页面的大块结构&#xff0c;例如页面的主体区域、容器、布局等。 2、<span> 是行内元素&#xff0c;它不会独占一行&#xff0c;宽度默认由其内容决定…

Ubuntu20.04安装Autoware.universe并与Awsim联调

文章目录 引言一、安装依赖1.1 安装git1.2 克隆Autoware到本地1.3 自动安装相关依赖1.4 安装显卡驱动1.5 安装ROS2 Galactic1.6 安装ros2_dev_tools1.7 安装rmw_implementation1.8 安装pacmod1.9 安装autoware_core1.10 安装autoware universe dependencies1.11 安装pre_commit…