函数栈帧的创建与销毁剖析
目录
一、前言
二、基础知识介绍
2.1 寄存器介绍
2.2、汇编指令介绍
三、函数栈帧的创建销毁过程
3.1 调用main函数的函数
3.2 main函数开辟栈帧
3.3 在main函数中创建变量
3.4 调用Add函数前的准备
3.5 为Add函数开辟栈帧
3.6 在Add函数中创建变量并运算
3.7 Add函数栈帧的销毁
3.8 返回main函数栈帧
一、前言
在C语言的过程中,我们心中难免有一些懵懂的地方。譬如:
1.局部变量到底是怎么在栈上创建的?
2.为什么局部变量不初始化为随机值?
3.函数是怎么传参的?传参的先后顺序是什么?
4.形参和实参是什么关系?
5.函数调用是怎么实现的?
6.函数调用后是怎么返回的?
学习完函数栈帧的创建与销毁,想必就能有一个比较清晰的认识了
本文的调试结果是使用vs2013和vs2019反汇编调试而出的,不同编译器函数栈帧的创建销毁过程略有不同,具体细节取决于编译器的实现。(越高级的编译器封装越好,越不易观察学习)
二、基础知识介绍
2.1 寄存器介绍
| 寄存器名称 | 功能 |
| eax | 累加器,是多数加法乘法指令的缺省寄存器 |
| ebx | 基地址寄存器,在内存寻址时存放基地址 |
| ecx | 计数寄存器,用于循环操作,比如重复的字符存储操作,或者数字统计 |
| edx | 作为eax的溢出寄存器,总是被用来放整数除法产生的余数 |
| esi | 源变址寄存器,主要用于存放存储单元在段内的偏移量 通常在内存操作指令中作为“源地址指针”使用 |
| edi | 目的变址寄存器,主要用于存放存储单元在段内的偏移量 |
| eip | 控制寄存器,存储CPU下次所执行的指令地址(存放指令偏移地址) |
| esp | 栈指针寄存器(extended stack pointer),其内存放着一个指针。 该指针永远指向栈最上面一个栈帧的栈顶。esp用于堆栈操作,被形象地称为栈顶指针。 |
| ebp | 基址指针,指栈的栈底指针。基址指针寄存器(extended base pointer)。 一般与 |
2.2、汇编指令介绍
| 指令 | 名称 | 作用 |
| push | 进栈指令 | 将源操作数压入栈中 |
| pop | 弹栈指令 | 从栈中弹出双字或字数据至目的操作数中 |
| mov | 传送指令 | 把一个字节、字、或双字从源操作数传送至目的操作数 |
| add | 加法指令 | 目的操作数加源操作数,结果送至目的操作数 |
| sub | 减法指令 | 目的操作数减源操作数,结果送至目的操作数 |
| lea | 取有效地址指令 | 将源操作数的有效地址传送到通用寄存器 |
| call | 过程调用指令 | 程序下一条指令的位置的地址压入堆栈中,并转移到调用的子程序 |
| ret | 段内过程返回指令 | 从调用过程返回,继续执行主程序。 |
| jmp | 无条件转移指令 | 使程序无条件地转移到指令规定的目的地址去执行指令 |
字(word):表示两个字节长度的数值 双字(dword):表示四个字节长度的数值
三、函数栈帧的创建销毁过程
接下来使用下述代码进行演示 (语句简单,易于观察)
#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;
}
3.1 调用main函数的函数
vs2013进入调试,打开窗口中的调用堆栈,F10不断调试,得到下图

可以发现main函数也是由别的函数(__tmainCRTStartup函数)调用的,而__tmainCRTStartup函数则是由mainCRTStartup函数调用的。
3.2 main函数开辟栈帧

3.3 在main函数中创建变量

在main函数开辟的栈帧中创建变量
3.4 调用Add函数前的准备

3.5 为Add函数开辟栈帧

3.6 在Add函数中创建变量并运算

3.7 Add函数栈帧的销毁

3.8 返回main函数栈帧

相关文章:
函数栈帧的创建与销毁剖析
目录 一、前言 二、基础知识介绍 2.1 寄存器介绍 2.2、汇编指令介绍 三、函数栈帧的创建销毁过程 3.1 调用main函数的函数 3.2 main函数开辟栈帧 3.3 在main函数中创建变量 3.4 调用Add函数前的准备 3.5 为Add函数开辟栈帧 3.6 在Add函数中创建变量并运算 3.7 Add函…...
性能测试-如何进行监控设计
监控设计步骤 首先,你要分析系统的架构。在知道架构中使用的组件之后,再针对每个组件进行监控。 其次,监控要有层次,要有步骤。先全局,后定向定量分析。 最后,通过分析全局、定向、分层的监控数据做分析…...
大数据List去重
概述 两个超大List集合去重,时间最短的方式去实现。 详细 MaxList模块主要是对Java集合大数据去重的相关介绍。 背景: 最近在项目中遇到了List集合中的数据要去重,大概一个2500万的数据,开始存储在List中,需要跟一个2万的List去…...
CentOS8.2重启网络
查看网络配置命令 # ip addr # nmcli ens160: 已连接 到 ens160"VMware VMXNET3"ethernet (vmxnet3), 00:50:56:B6:34:84, 硬件, mtu 1500ip4 默认inet4 10.3.10.111/24route4 10.3.10.0/24route4 0.0.0.0/0inet6 fe80::250:56ff:feb6:3484/64route6 ff00::/8rou…...
2023年【G1工业锅炉司炉】考试题及G1工业锅炉司炉模拟考试
题库来源:安全生产模拟考试一点通公众号小程序 2023年G1工业锅炉司炉考试题为正在备考G1工业锅炉司炉操作证的学员准备的理论考试专题,每个月更新的G1工业锅炉司炉模拟考试祝您顺利通过G1工业锅炉司炉考试。 1、【多选题】TSGG0001-2012《锅炉安全技术监…...
观察者模式 行为型设计模式之七
1.定义 在GOF的《设计模式:可复用面向对象软件的基础》一书中对观察者模式是这样定义的:定义对象的一种一对多的依赖关系,当一个对象的状态发生改变时,所有依赖于它的对象都得到通知并被自动更新。当一个对象发生了变化࿰…...
数据结构与算法之堆: Leetcode 451. 根据字符出现频率排序 (Typescript版)
根据字符出现频率排序 https://leetcode.cn/problems/sort-characters-by-frequency/ 描述 给定一个字符串 s ,根据字符出现的 频率 对其进行 降序排序 。一个字符出现的 频率 是它出现在字符串中的次数。返回 已排序的字符串 。如果有多个答案,返回其…...
吃透底层:从路由到前缀树
前言 今天学到关于路由相关文章,发现动态路由中有一个很常见的实现方式是前缀树,很感兴趣这个算法,故进行记录。 前缀树 Trie(又被叫做字典树)可以看作是一个确定有限状态自动机,尽管边上的符号一般是隐含…...
SparkSQL外部数据源
1.简介 1.1 多数据源支持 Spark 支持以下六个核心数据源,同时 Spark 社区还提供了多达上百种数据源的读取方式,能够满足绝大部分使用场景。 - CSV - JSON - Parquet - ORC - JDBC/ODBC connections - Plain-text files 1.2 读数据格式 所有读取 API 遵循以下调用格式: // …...
林沛满-TCP 是如何避免被发送方分片的?
TCP 可以避免被发送方分片,是因为它主动把数据分成小段再交给网络层。最大的分段大小称为 MSS(Maximum Segment Size),它相当于把 MTU 刨去 IP头和 TCP 头之后的大小,所以一个 MSS 恰好能装进一个 MTU 中。 图4 图 4 …...
Java中的枚举是什么?
Java枚举详解 枚举(Enum)是Java编程语言中的一种特殊数据类型,它用于表示一组具名的常量。枚举提供了一种更加类型安全和易于理解的方式来表示常量值,使代码更加清晰和可维护。 为什么需要枚举? 在介绍Java枚举的具…...
java学习--day24(单例模式序列化Lambda表达式)
文章目录 回顾今天的内容1.单例模式2.序列化3.Lambda表达式3.1入门案例3.2lambda表达式语法格式3.2.1无参无返回值的形式3.2.2有参无返返回值的方法3.2.3无参有返回值3.2.4有参有返回值的 回顾 1.三种创建Class对象的形式Class.forName("")类.class对象.getCalss()字…...
从0开始学go第六天
方法一:gin获取querystring参数 package main//querystring import ("net/http""github.com/gin-gonic/gin" )func main() {r : gin.Default()r.GET("/web", func(c *gin.Context) {//获取浏览器那边发请求携带的query String参数//…...
unity设计模式——代理模式
Subject类,定义了Real Subject和Proxy的共用接口,这样就在任何使用Real Subject的地方都可以使用Proxy。 abstract class Subject : MonoBehaviour {public abstract void Request(); } RealSubject类,定义Proxy所代表的真实实体。 class R…...
SpringBoot 如何使用 Grafana 进行可视化监控
使用Spring Boot Sleuth进行分布式跟踪 在现代分布式应用程序中,跟踪请求和了解应用程序的性能是至关重要的。Spring Boot Sleuth是一个分布式跟踪解决方案,它可以帮助您在分布式系统中跟踪请求并分析性能问题。本文将介绍如何在Spring Boot应用程序中使…...
【Codeforces】 CF1762E Tree Sum
题目链接 CF方向 Luogu方向 题目解法 首先考虑 n n n 为奇数的情况无解,这个可以通过乘积矛盾简单证明 接下来考虑一个结论是:偶数个点的树的形态确定之后,只有恰好 1 1 1 种染色方案,即从叶子一层一层往上面染,…...
用《斗破苍穹》的视角打开C#委托2 委托链 / 泛型委托 / GetInvocationList
委托链 经过不懈地努力,我终于成为了斗师,并成功掌握了两种斗技——八极崩和焰分噬浪尺。于是,我琢磨着,能不能搞一套连招,直接把对方带走。 using System; using System.Collections.Generic; using System.Linq; u…...
唐老师讲电赛
dc-dc电源布局要点...
[ICCV-23] DeformToon3D: Deformable Neural Radiance Fields for 3D Toonification
pdf | code 将3D人脸风格化问题拆分为几何风格化与纹理风格化。提出StyleField,学习以风格/ID为控制信号的几何形变残差,实现几何风格化。通过对超分网络引入AdaIN,实现纹理风格化。由于没有修改3D GAN空间,因此可以便捷实现Edit…...
配置Hive使用Spark执行引擎
配置Hive使用Spark执行引擎 Hive引擎概述兼容问题安装SparkSpark配置Hive配置HDFS上传Spark的jar包执行测试速度对比 Hive引擎 概述 在Hive中,可以通过配置来指定使用不同的执行引擎。Hive执行引擎包括:默认MR、tez、spark MapReduce引擎: 早…...
如何快速掌握深度学习调参技巧:tuning_playbook_zh_cn完全解析
如何快速掌握深度学习调参技巧:tuning_playbook_zh_cn完全解析 【免费下载链接】tuning_playbook_zh_cn 一本系统地教你将深度学习模型的性能最大化的战术手册。 项目地址: https://gitcode.com/gh_mirrors/tu/tuning_playbook_zh_cn tuning_playbook_zh_cn是…...
保姆级教程:用YOLOv8+PyQt5打造你的番茄成熟度检测桌面应用(附完整源码与数据集)
从零构建番茄成熟度检测桌面应用:YOLOv8与PyQt5深度整合实战 在农业智能化浪潮中,计算机视觉技术正逐步改变传统农业生产方式。以番茄种植为例,成熟度判断直接影响采摘效率和经济效益。本文将带您完整实现一个结合YOLOv8目标检测与PyQt5图形界…...
Java程序员6年焦虑,转行AI后薪资暴涨40%!这8个岗位,普通人也能入局?年薪百万不是梦!
文章讲述了一位Java程序员老周因对纯业务开发感到焦虑,于去年3月开始系统学习AI相关技术,并于去年7月成功跳槽至AI创业公司,薪资涨幅达40%。文章分析了2026年AI相关岗位的招聘趋势,指出AI岗位需求旺盛,但需要程序员具备…...
coze-loop效果展示:看AI如何将冗长代码重构为高效简洁版本
coze-loop效果展示:看AI如何将冗长代码重构为高效简洁版本 1. 引言:AI代码优化的革命性工具 在软件开发领域,代码优化一直是一项既重要又具有挑战性的任务。传统的优化过程往往需要开发者具备深厚的算法知识和丰富的经验积累。而今天&#…...
3个步骤实现教育资源高效获取:电子教材下载工具全攻略
3个步骤实现教育资源高效获取:电子教材下载工具全攻略 【免费下载链接】tchMaterial-parser 国家中小学智慧教育平台 电子课本下载工具 项目地址: https://gitcode.com/GitHub_Trending/tc/tchMaterial-parser tchMaterial-parser是一款专为教育工作者和学习…...
不止于地图:深入QGC地图插件机制,打造你的自定义地图源
不止于地图:深入QGC地图插件机制,打造你的自定义地图源 在无人机地面站软件生态中,QGroundControl(QGC)以其开源特性和模块化设计,成为开发者扩展定制的首选平台。当我们谈论地图功能时,大多数用…...
别再死记硬背TTS原理了!用Python+TensorFlow复现一个简易Deep Voice,从音素到语音全流程拆解
用PythonTensorFlow实战Deep Voice:从音素到语音的完整实现指南 当你第一次听到计算机生成的语音时,是否好奇过这背后的魔法是如何实现的?现代文本转语音(TTS)系统已经能够产生几乎与真人无异的语音,而Deep Voice作为早期端到端TT…...
美图靠AI一年收入38亿,不靠免费大模型API,靠的是什么?
财报数据显示,美图2025年全年实现营业收入38.6亿元,同比大幅增长28.8%,整体营收规模再创新高,展现出核心业务的强劲增长韧性。不过公司常规账面净利润为7亿元,同比下降12.7%,看似利润下滑的背后,…...
逆向视角看iOS加固:从机器码到伪代码,手把手教你分析加固效果与潜在风险
逆向视角看iOS加固:从机器码到伪代码的深度解析 当你在App Store下载一个应用时,可能不会想到这个看似简单的IPA文件背后隐藏着怎样的技术博弈。作为iOS开发者或安全研究员,我们常常需要从另一个角度思考——不是如何保护自己的应用…...
手把手教你配置:用微型纵向加密搞定IEC-104协议的风光数据安全上传
新能源场站IEC-104协议安全传输实战:微型纵向加密配置全指南 在新能源场站的自动化系统中,IEC-104协议作为电力行业标准通信规约,承担着风机、光伏逆变器与升压站之间关键运行数据传输的重任。然而,传统光纤环网中的明文传输方式存…...
