【C语言__函数栈帧的创建和销毁__复习篇9】

目录

前言

一、知识补充

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

三、前言问题回答


前言

本篇主要讨论以下问题:

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/1653.shtml

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

相关文章

电商平台业务及架构演变史

不少人认为电商系统很简单&#xff0c;因为现在做电商的太多了&#xff0c;看到的电商产品也多。看来看去产品都差不多&#xff0c;没什么特别。 其实中国电商发展已有20多年历史&#xff0c;电商以销售为核心连接着研、产、供、销、服整套的信息系统体系。其中的设计并没有那…

企业公众号数量怎么申请

一般可以申请多少个公众号&#xff1f;许多用户在申请公众号时可能会遇到“公众号显示主体已达上限”的问题。这是因为在2018年11月16日对公众号申请数量进行了调整&#xff0c;具体调整如下&#xff1a;1、个人主体申请公众号数量上限从2个调整为1个。2、企业主体申请公众号数…

vue---计算属性

姓名案例 1.使用插值语法实现 <!DOCTYPE html> <html><head><meta charset"UTF-8" /><title>姓名案例_插值语法实现</title><!-- 引入Vue --><script type"text/javascript" src"../js/vue.js"&g…

从源码选择到国际化运营:打造成功的跨境电商网站必备指南

跨境电商网站的成功离不开经过精心策划和执行的全面计划。从源码选择到国际化运营&#xff0c;每一步都至关重要。作为跨境电商领域的专家&#xff0c;我将为您提供打造成功跨境电商网站的必备指南&#xff0c;帮助您开拓全球市场&#xff0c;提升边际收入。 选择优质的跨境电…

云服务器ECS选型知多少

云服务器ECS选型知多少 ECS产品规格如何选择实例规格变配 说到云服务器ECS选型&#xff0c;那可以说太重要了。因为对于一个项目来说&#xff0c;从项目到开始到最后的部署上线&#xff0c;每一步都需要付出&#xff0c;这些对于企业或者个人来说都是一笔投入&#xff0c;那么如…

会议预告 | 易基因与您相约2024中国衰老科学大会(附日程) 新品首发

由中国细胞生物学学会衰老细胞生物学分会等单位联合主办&#xff0c;瓯江实验室、温州医科大学老年研究院等共同承办的2024中国衰老科学大会暨国际衰老生物学大会将于2024年4月26日-28日在温州召开。本次大会以“解码衰老”为主题&#xff0c;旨在汇聚全球科研精英&#xff0c;…

全开源商城源码后台php全端uniapp 全开源可二开 功能强大 商城系统源码

内容目录 一、详细介绍二、效果展示1.部分代码2.效果图展示 三、学习资料下载 一、详细介绍 内置8中搭配主色(可自行扩展更多配色)、自由快捷切换适应各大行业需求 已支持小程序&#xff08;微信、QQ、百度、支付宝、头条&抖音、快手&#xff09; H5 APP App.vue中修改 r…

EasyMR6.2 全面解读:四大功能深度优化,解锁全新大数据处理和计算体验

在刚刚过去的2024春季发布会上&#xff0c;袋鼠云带来了数栈产品V6.2版本的全新发布。其中&#xff0c;EasyMR 作为数栈V6.2中的一项关键能力&#xff0c;代表了袋鼠云对大数据生态的深入理解和持续创新。 EasyMR&#xff08;后文统称EMR&#xff09;是袋鼠云基于 Hadoop、Hiv…

CH341A/B USB转USART/I2C/SPI介绍

CH341A/B USB转USART/I2C/SPI介绍 &#x1f4cd;CH341官方文档&#xff1a;https://www.wch.cn/downloads/CH341DS2_PDF.html CH341A/B是一个USB总线的转接芯片&#xff0c;通过USB总线提供异步串口、打印口、并口以及常用的2线和4线等同步串行接口。 &#x1f341;芯片封装&a…

前端表单input的简单使用

1.代码结构介绍 2.实战效果

The layered MVP architecture in Acise

Acise是一款CAx软件开发平台&#xff0c;本文给出Acise中的MVP架构模式的实现思路。 注1&#xff1a;文章内容会不定期更新。 MVP Data Model View Model 参考文献 Erich Gamma. Design Patterns:elements of reusable object-oriented software. Addison Wesley, 1994.Josep…

查询服务器上所有SQL SERVER数据库中是否包含某个字段,且该字段是否包含某个值

公司有一堆相同类别的客户&#xff0c;每个客户都部署了相同的一套系统&#xff0c;每套系统对应一个相同结构的数据库&#xff0c;昨天老板让查一下手机号码177xxxxx248是属于哪个客户的客户。 我要查的这个号码来自于oa_member表中的phone字段&#xff0c;我需要对所有的数据…

实测52.4MB/s!全志T3+FPGA的CSI通信案例分享!

CSI总线介绍与优势 CSI&#xff08;CMOS sensor parallel interfaces&#xff09;总线是一种用于连接图像传感器和处理器的并行通信接口&#xff0c;应用于工业自动化、能源电力、智慧医疗等领域&#xff0c;CSI总线接口示意图如下所示&#xff08;以全志科技T3处理器的CSI0为…

2024年51cto视频如何提取

2024年&#xff0c;对于如何提取51cto网站上的视频&#xff0c;许多人都选择在该平台购买自己所需的学习视频。然而&#xff0c;在51cto网页上观看视频将消耗用户的流量。为了解决这一问题&#xff0c;我开发了名为小白51cto工具的软件&#xff0c;使用户能够轻松将视频下载到本…

如何增强Java GCExcel API 的导入和导出性能

前言 GrapeCity Documents for Excel (以下简称GcExcel) 是葡萄城公司的一款服务端表格组件&#xff0c;它提供了一组全面的 API 以编程方式生成 Excel (XLSX) 电子表格文档的功能&#xff0c;支持为多个平台创建、操作、转换和共享与 Microsoft Excel 兼容的电子表格&#xf…

web前端(简洁版)

0. 开发环境 && 安装插件 这里我使用的是vscode开发环境 Auto Rename Tag是语法自动补齐view-in-browser是快速在浏览器中打开live server实时网页刷新 1. HTML 文件基本结构 <html><head><title>第一个页面</title></head><body&g…

开源事件通知库libevent及网络连接管理模块bufferevent详解

目录 1、libevent介绍 1.1、什么是libevent&#xff1f; 1.2、libevent特点 1.3、网络连接管理模块bufferevent 2、bufferevent有什么用&#xff1f; 3、bufferevent的整体设计与实现细节 3.1、整体概况 3.2、evbuffer与bufferevent 3.3、defer callback 4、bufferev…

python爬虫之爬取微博评论(4)

一、获取单页评论 随机选取一个微博&#xff0c;例如下面这个 【#出操死亡女生家属... - 冷暖视频的微博 - 微博 (weibo.com) 1、fnf12&#xff0c;然后点击网络&#xff0c;搜索评论内容&#xff0c;然后预览&#xff0c;就可以查看到网页内容里面还有评论内容 2、编写代码…

【C#】rdlc报表答应报错:未能加载文件或程序集“Microsoft.SqlServer.Types

文章目录 一、报错信息二、解决方式 一、报错信息 Microsoft.Reporting.WinForms.LocalProcessingException: An error occurred during local report processing. —> Microsoft.Reporting.DefinitionInvalidException: The definition of the report ‘’ is invalid. —&…

Vmware 虚拟机自定义IP地址 - UbuntuServer2204

Vmware 虚拟机自定义IP地址 - UbuntuServer2204 设置网段 选择喜欢的网段&#xff0c; 例如&#xff1a; 166 自定义 IP地址 打开虚拟机&#xff0c; 输入命令查看网卡名 ip addr查看网卡配置文件 ls -al /etc/netplan/编辑网卡配置文件 sudo vim /etc/netplan/00-installe…