【C语言】/*函数栈帧的创建和销毁*/

目录

前言

一、知识补充

二、分析创建和销毁的过程

三、前言问题回答


前言

本篇主要讨论以下问题:

1. 编译器什么时候为局部变量分配的空间

2. 为什么局部变量的值是随机的

3. 函数是怎么传参的,传参的顺序是怎样的

4. 形参和实参是什么关系

5. 函数调用是怎么做的

6. 函数调用结束后怎么返回的

一、知识补充

1. 使用的环境是VS2013,因为越高级的编译器越不容易观察细节。

2. 在不同的编译器下,函数调用过程中栈帧的创建略有差异,具体细节取决于编译器。

3. 寄存器ebp(栈底指针)、esp(栈顶指针) 中存放的是地址,这里面的地址是专门用来维护函数栈帧的。

4. 每一次函数调用,都要在栈区创建一个空间,这个空间就叫该函数的函数栈帧,在调用哪个函数寄存器ebp、esp就维护哪块函数栈帧。

5. 栈区的使用习惯,先使用高地址,再使用低地址。

6. main函数其实也是被其它函数调用的,例如再VS2013中,mainCRTStartup函数调用__tmainCRTStartup函数,由__tmainCRTStartup函数调用的main函数。

7. 在研究函数栈帧时看的是汇编代码。

8. 相关寄存器:

    eax:通用寄存器,保留临时数据,常用于返回值

    ebx:通用寄存器,保留临时数据

    ebp:栈底寄存器

    esp:栈顶寄存器

    eip:指令寄存器,保存当前指令的下一条指令的地址

 

二、分析创建和销毁的过程

调试到main函数开始执行的第一行,右击鼠标转到反汇编。

//【研究的源代码】
#include <stdio.h>
int Add(int x, int y)
{int z = 0;z = x + y;return z;
}int main()
{int a = 3;int b = 5;int ret = 0;ret = Add(a, b);printf("%d\n", ret);return 0;
}

  main函数内的汇编代码:

Add函数内的汇编代码:  

 

 栈区内存开辟示意图: 

 

函数栈帧创建和销毁过程的过程简易描述:

在进入被调用函数的第一行后,汇编指令会先将主调函数的栈底指针的地址进行压栈操作,再将esp的值给ebp,esp接着sub一个值,此步结束后相当于初步搭建起了被调函数的函数栈帧。接着会在栈顶压入三个地址,结束后会进行初始化刚刚开辟的函数栈帧空间,里面会初始化一些随机值,然后在函数栈帧中为局部变量开辟空间并存入局部变量初始化的值,在执行过程中如果存在函数调用,且被调用的函数有参数,则会将从右向左参数的值依次压栈入栈顶(为形参开辟空间),接着执行call指令,在执行call指令时会压入call指令下一条指令的地址,接着程序就会跳入被调用函数的汇编代码中,并执行上面打横线的步骤,执行完后如果后面的指令中需要使用形参的值,则会利用指针偏移找到形参所在的位置,函数的返回类型如果不为void那么函数的返回值会存放在寄存器eax中,此步骤结束后会开始进行一系列pop操作,使得寄存器ebp、esp回到维护主调函数栈帧的位置上,程序回到主调函数的汇编代码中是依靠ret指令完成的,回到主调函数的汇编代码后,会根据代码内容继续执行其他的汇编指令。

三、前言问题回答

1. 编译器什么时候为局部变量分配的空间?

答:编译器为被调用函数分配栈帧空间后,会立即为刚刚开辟的空间初始化,然后再为局部变量分配空间并放入代码中局部变量指定的初始化值。

2. 为什么局部变量的值是随机的?

答:因为在为被调用函数分配栈帧空间后,系统会先初始化一次栈帧空间,此时放入初始化的值就是随机的,如果我们在创建局部变量后就为局部变量初始化就能达到覆盖随机值的效果。

3. 函数是怎么传参的,传参的顺序是怎样的?

答:在进入被调函数前就已经把从右向左的实参的值拷贝并push在栈顶了,在需要使用形参的值时通过指针偏移就能找到对应的形参。

4. 形参和实参是什么关系?

答:形参是实参的一份临时拷贝,改变形参不影响实参。

5. 函数调用是怎么做的?

答:略。

6. 函数调用结束后怎么返回的?

答:函数返回与两个指令有关。在执行call指令之前先会把call指令的下一条指令的地址进行压栈操作,这个操作是为了解决当函数调用结束后要回到call指令的下一条指令的地方,继续往后执行;ret指令的执行,首先是从栈顶弹出一个值,此时栈顶的值就是call指令下一条指令的地址,此时esp+4,然后编译器会直接跳转到call指令下一条指令的地址处,从而实现回到主调函数的汇编代码中。

  本篇文章已完结,谢谢支持!!!

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

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

相关文章

vue3--element-plus-抽屉文件上传和富文本编辑器

一、封装组件 article/components/ArticleEdit.vue <script setup> import { ref } from vue const visibleDrawer ref(false)const open (row) > {visibleDrawer.value trueconsole.log(row) }defineExpose({open }) </script><template><!-- 抽…

SSM+Vue+小程序+基于微信小程序的高校学生事务管理系统

项目配合学校日常生活通知&#xff0c;考试等管理需要&#xff0c;开发学校事务管理系统&#xff0c;maven管理依赖&#xff0c;mybatis处理数据库交互 学校管理 学院管理 班级管理 年级管理 教师管理 通知公告管理 学生资料管理 待办事项管理 教务处通知管理 讲座通…

OpenCV(一) —— OpenCV 基础

1、OpenCV 简介 OpenCV&#xff08;Open Source Computer Vision Library&#xff09;是一个基于 BSD 许可开源发行的跨平台的计算机视觉库。可用于开发实时的图像处理、计算机视觉以及模式识别程序。由英特尔公司发起并参与开发&#xff0c;以 BSD 许可证授权发行&#xff0c…

网络知识点之—QoS

QoS&#xff08;Quality of Service&#xff0c;服务质量&#xff09;指一个网络能够利用各种基础技术&#xff0c;为指定的网络通信提供更好的服务能力&#xff0c;是网络的一种安全机制&#xff0c; 是用来解决网络延迟和阻塞等问题的一种技术。QoS的保证对于容量有限的网络来…

C++11:右值引用和左值引用

1.decltype decltype可以推导出一个表达式的类型&#xff0c;可以用这个类型定义变量。 测试代码 template<class T1,class T2> void test1(T1 &a,T2 & b) {decltype(a* b) ret;cout << typeid(ret).name() << endl; } 2.范围for void test2()…

上位机图像处理和嵌入式模块部署(树莓派4b部署java环境)

【 声明&#xff1a;版权所有&#xff0c;欢迎转载&#xff0c;请勿用于商业用途。 联系信箱&#xff1a;feixiaoxing 163.com】 通常我们都会认为java是部署在pc服务器上面的&#xff0c;或者是用java开发android应用程序。其实不然&#xff0c;java也可以部署在嵌入式开发板子…

前端工程化03-贝壳找房项目案例JavaScript常用的js库

4、项目实战&#xff08;贝壳找房&#xff09; 这个项目包含&#xff0c;基本的ajax请求调用,内容的渲染&#xff0c;防抖节流的基本使用&#xff0c;ajax请求工具类的封装 4.1、项目的接口文档 下述接口文档&#xff1a; 简述内容baseURL&#xff1a;http://123.207.32.32…

ESP32 烧录固件

第一步&#xff1a;下载固件 git clone --recursive https://github.com/espressif/esp-at.git 第二步&#xff1a;执行编译 在该目录执行 python build.py install 如图&#xff1a; 第三步&#xff1a;选择芯片 输入2 第四步&#xff1a;选择固件 输入1 第五步&#…

error LNK2001: 无法解析的外部符号 “__declspec(dllimport) public: __cdecl ......

运行程序时&#xff0c;报如上图所示错误&#xff0c;其中一条是&#xff1a; ReflectionProbe.obj : error LNK2001: 无法解析的外部符号 "__declspec(dllimport) public: __cdecl osg::Object::Object(bool)" (__imp_??0ObjectosgQEAA_NZ) 报这个错误一般是因为…

银行ETL-监管报送

1104报表 1104报表主要包括&#xff1a;资产负债&#xff0c;表外业务、流动性风险、贷款质量、投向行业和地区、重点客户等。 1104报表分类 普通报表、机构特色类报表。 反洗钱 大额交易、可疑交易。标签分类&#xff1a;疑似犯罪、疑似毒品、疑似传销。 反洗钱—接口报…

揭秘Fabric交易流程:一文带你深入了解

随着区块链技术的日益普及&#xff0c;Hyperledger Fabric作为一种联盟链解决方案&#xff0c;受到了广泛关注。那么&#xff0c;Fabric的交易流程究竟是怎样的呢&#xff1f;本文将为您一一揭晓。 1. Fabric交易的参与方 客户端&#xff1a;交易流程的发起方&#xff0c;发起…

Windows 容器镜像踩坑记录

为什么研究windows容器&#xff1f;emm&#xff0c;公司需要&#xff0c;不想多说。 dotnet后端 问题描述&#xff1a; 基于mcr.microsoft.com/dotnet/aspnet:6.0镜像撰写dockerfile编译.net core后端项目后运行容器出现类库不存在问题&#xff1a; 程序中使用了fastreport&a…

数据库(MySQL)—— DQL语句(基本查询和条件查询)

数据库&#xff08;MySQL&#xff09;—— DQL语句&#xff08;基本查询和条件查询&#xff09; 什么是DQL语句基本查询查询多个字段字段设置别名去除重复记录 条件查询语法条件 我们今天进入MySQL的DQL语句的学习&#xff1a; 什么是DQL语句 MySQL中的DQL&#xff08;Data Q…

【论文】关于网页上能打开的文章下载PDF“显示无效或损坏的 PDF 文件”的解决办法

1. 遇到的问题 今天我在 dl.acm.org/doi 下载论文时发现下载后的pdf打开出现“显示无效或损坏的 PDF 文件” 可是在原网址是可以打开并显示的 2. 解决方案 这里我用到了和之前【论文】去除PDF论文行号的完美解决方案 的相似的解决办法 就是下载的时候不直接下载&#xf…

【前端项目——分页器】手写分页器实现(JS / React)

组件介绍 用了两种方式实现&#xff0c;注释详细~ 可能代码写的不够简洁&#xff0c;见谅&#x1f641; 1. 包含内容显示的分页器 网上看了很多实现&#xff0c;很多只有分页器部分&#xff0c;没和内容显示联动。 因此我增加了模拟content的显示&#xff0c;这里模拟了32条数…

环形链表面试题详解

A. 环形链表1 给你一个链表的头节点 head &#xff0c;判断链表中是否有环. 如果链表中有某个节点&#xff0c;可以通过连续跟踪 next 指针再次到达&#xff0c;则链表中存在环。 为了表示给定链表中的环&#xff0c;评测系统内部使用整数 pos 来表示链表尾连接到链表中的位置…

【数据结构】第四讲:双向链表

目录 一、链表的分类 二、双向链表的结构及实现 1.带头双向链表的结构 2.创建节点 3.初始化 4.尾插 5.打印 6.头插 7.尾删 8.头删 9.在pos位置之后插入数据 10.删除pos节点 11.查找 12.销毁 个人主页&#xff1a;深情秋刀鱼-CSDN博客 数据结构专栏&#xff1a;数…

虚拟化技术 安装并配置ESXi服务器系统

安装并配置ESXi服务器系统 一、实验目的与要求 1.掌握创建VMware ESXi虚拟机 2.掌握安装VMware ESXi系统 3.掌握配置VMware ESXi系统的管理IP 4.掌握开启VMware ESXi的shell和ssh功能的方法 二、实验内容 1.安装VMware workstation 15或更高版本 2.创建VMware ESXi虚拟…

专业渗透测试 Phpsploit-Framework(PSF)框架软件小白入门教程(三)

本系列课程&#xff0c;将重点讲解Phpsploit-Framework框架软件的基础使用&#xff01; 本文章仅提供学习&#xff0c;切勿将其用于不法手段&#xff01; 继续接上一篇文章内容&#xff0c;讲述如何进行Phpsploit-Framework软件的基础使用和二次开发。 当我们点击 submit 提…

基于t972 Android9 AP6256,如何在设置中添加5G热点选项,并使其正常打开

通过设置的的WiFi热点选项可以知道关键词“2.4GHz”&#xff0c;因此可以其全局搜索&#xff0c;在packages\apps\Settings\res\values\strings.xml文件下找到如下图所示&#xff0c; 从上面注释可以知道&#xff0c;选项按键选择2.4GHz触发的按键关键词是“wifi_ap_choose_2G…