函数栈帧的创建与销毁剖析
目录
一、前言
二、基础知识介绍
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引擎: 早…...
C++:std::is_convertible
C++标志库中提供is_convertible,可以测试一种类型是否可以转换为另一只类型: template <class From, class To> struct is_convertible; 使用举例: #include <iostream> #include <string>using namespace std;struct A { }; struct B : A { };int main…...

LeetCode - 394. 字符串解码
题目 394. 字符串解码 - 力扣(LeetCode) 思路 使用两个栈:一个存储重复次数,一个存储字符串 遍历输入字符串: 数字处理:遇到数字时,累积计算重复次数左括号处理:保存当前状态&a…...

Vue2 第一节_Vue2上手_插值表达式{{}}_访问数据和修改数据_Vue开发者工具
文章目录 1.Vue2上手-如何创建一个Vue实例,进行初始化渲染2. 插值表达式{{}}3. 访问数据和修改数据4. vue响应式5. Vue开发者工具--方便调试 1.Vue2上手-如何创建一个Vue实例,进行初始化渲染 准备容器引包创建Vue实例 new Vue()指定配置项 ->渲染数据 准备一个容器,例如: …...

《基于Apache Flink的流处理》笔记
思维导图 1-3 章 4-7章 8-11 章 参考资料 源码: https://github.com/streaming-with-flink 博客 https://flink.apache.org/bloghttps://www.ververica.com/blog 聚会及会议 https://flink-forward.orghttps://www.meetup.com/topics/apache-flink https://n…...
关于 WASM:1. WASM 基础原理
一、WASM 简介 1.1 WebAssembly 是什么? WebAssembly(WASM) 是一种能在现代浏览器中高效运行的二进制指令格式,它不是传统的编程语言,而是一种 低级字节码格式,可由高级语言(如 C、C、Rust&am…...

Mac下Android Studio扫描根目录卡死问题记录
环境信息 操作系统: macOS 15.5 (Apple M2芯片)Android Studio版本: Meerkat Feature Drop | 2024.3.2 Patch 1 (Build #AI-243.26053.27.2432.13536105, 2025年5月22日构建) 问题现象 在项目开发过程中,提示一个依赖外部头文件的cpp源文件需要同步,点…...

AI,如何重构理解、匹配与决策?
AI 时代,我们如何理解消费? 作者|王彬 封面|Unplash 人们通过信息理解世界。 曾几何时,PC 与移动互联网重塑了人们的购物路径:信息变得唾手可得,商品决策变得高度依赖内容。 但 AI 时代的来…...

C++ 设计模式 《小明的奶茶加料风波》
👨🎓 模式名称:装饰器模式(Decorator Pattern) 👦 小明最近上线了校园奶茶配送功能,业务火爆,大家都在加料: 有的同学要加波霸 🟤,有的要加椰果…...
python爬虫——气象数据爬取
一、导入库与全局配置 python 运行 import json import datetime import time import requests from sqlalchemy import create_engine import csv import pandas as pd作用: 引入数据解析、网络请求、时间处理、数据库操作等所需库。requests:发送 …...
「全栈技术解析」推客小程序系统开发:从架构设计到裂变增长的完整解决方案
在移动互联网营销竞争白热化的当下,推客小程序系统凭借其裂变传播、精准营销等特性,成为企业抢占市场的利器。本文将深度解析推客小程序系统开发的核心技术与实现路径,助力开发者打造具有市场竞争力的营销工具。 一、系统核心功能架构&…...