当前位置: 首页 > news >正文

函数栈帧的创建与销毁剖析

目录

一、前言

二、基础知识介绍

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)。

一般与esp配合使用,其内存放着一个指针,该指针永远指向系统栈最上面一个栈帧的底部

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函…...

性能测试-如何进行监控设计

监控设计步骤 首先&#xff0c;你要分析系统的架构。在知道架构中使用的组件之后&#xff0c;再针对每个组件进行监控。 其次&#xff0c;监控要有层次&#xff0c;要有步骤。先全局&#xff0c;后定向定量分析。 最后&#xff0c;通过分析全局、定向、分层的监控数据做分析…...

大数据List去重

概述 两个超大List集合去重&#xff0c;时间最短的方式去实现。 详细 MaxList模块主要是对Java集合大数据去重的相关介绍。 背景: 最近在项目中遇到了List集合中的数据要去重&#xff0c;大概一个2500万的数据&#xff0c;开始存储在List中&#xff0c;需要跟一个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工业锅炉司炉模拟考试

题库来源&#xff1a;安全生产模拟考试一点通公众号小程序 2023年G1工业锅炉司炉考试题为正在备考G1工业锅炉司炉操作证的学员准备的理论考试专题&#xff0c;每个月更新的G1工业锅炉司炉模拟考试祝您顺利通过G1工业锅炉司炉考试。 1、【多选题】TSGG0001-2012《锅炉安全技术监…...

观察者模式 行为型设计模式之七

1.定义 在GOF的《设计模式&#xff1a;可复用面向对象软件的基础》一书中对观察者模式是这样定义的&#xff1a;定义对象的一种一对多的依赖关系&#xff0c;当一个对象的状态发生改变时&#xff0c;所有依赖于它的对象都得到通知并被自动更新。当一个对象发生了变化&#xff0…...

数据结构与算法之堆: Leetcode 451. 根据字符出现频率排序 (Typescript版)

根据字符出现频率排序 https://leetcode.cn/problems/sort-characters-by-frequency/ 描述 给定一个字符串 s &#xff0c;根据字符出现的 频率 对其进行 降序排序 。一个字符出现的 频率 是它出现在字符串中的次数。返回 已排序的字符串 。如果有多个答案&#xff0c;返回其…...

吃透底层:从路由到前缀树

前言 今天学到关于路由相关文章&#xff0c;发现动态路由中有一个很常见的实现方式是前缀树&#xff0c;很感兴趣这个算法&#xff0c;故进行记录。 前缀树 Trie&#xff08;又被叫做字典树&#xff09;可以看作是一个确定有限状态自动机&#xff0c;尽管边上的符号一般是隐含…...

SparkSQL外部数据源

1.简介 1.1 多数据源支持 Spark 支持以下六个核心数据源,同时 Spark 社区还提供了多达上百种数据源的读取方式,能够满足绝大部分使用场景。 - CSV - JSON - Parquet - ORC - JDBC/ODBC connections - Plain-text files 1.2 读数据格式 所有读取 API 遵循以下调用格式: // …...

林沛满-TCP 是如何避免被发送方分片的?

TCP 可以避免被发送方分片&#xff0c;是因为它主动把数据分成小段再交给网络层。最大的分段大小称为 MSS&#xff08;Maximum Segment Size&#xff09;&#xff0c;它相当于把 MTU 刨去 IP头和 TCP 头之后的大小&#xff0c;所以一个 MSS 恰好能装进一个 MTU 中。 图4 图 4 …...

Java中的枚举是什么?

Java枚举详解 枚举&#xff08;Enum&#xff09;是Java编程语言中的一种特殊数据类型&#xff0c;它用于表示一组具名的常量。枚举提供了一种更加类型安全和易于理解的方式来表示常量值&#xff0c;使代码更加清晰和可维护。 为什么需要枚举&#xff1f; 在介绍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第六天

方法一&#xff1a;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类&#xff0c;定义了Real Subject和Proxy的共用接口&#xff0c;这样就在任何使用Real Subject的地方都可以使用Proxy。 abstract class Subject : MonoBehaviour {public abstract void Request(); } RealSubject类&#xff0c;定义Proxy所代表的真实实体。 class R…...

SpringBoot 如何使用 Grafana 进行可视化监控

使用Spring Boot Sleuth进行分布式跟踪 在现代分布式应用程序中&#xff0c;跟踪请求和了解应用程序的性能是至关重要的。Spring Boot Sleuth是一个分布式跟踪解决方案&#xff0c;它可以帮助您在分布式系统中跟踪请求并分析性能问题。本文将介绍如何在Spring Boot应用程序中使…...

【Codeforces】 CF1762E Tree Sum

题目链接 CF方向 Luogu方向 题目解法 首先考虑 n n n 为奇数的情况无解&#xff0c;这个可以通过乘积矛盾简单证明 接下来考虑一个结论是&#xff1a;偶数个点的树的形态确定之后&#xff0c;只有恰好 1 1 1 种染色方案&#xff0c;即从叶子一层一层往上面染&#xff0c;…...

用《斗破苍穹》的视角打开C#委托2 委托链 / 泛型委托 / GetInvocationList

委托链 经过不懈地努力&#xff0c;我终于成为了斗师&#xff0c;并成功掌握了两种斗技——八极崩和焰分噬浪尺。于是&#xff0c;我琢磨着&#xff0c;能不能搞一套连招&#xff0c;直接把对方带走。 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&#xff0c;学习以风格/ID为控制信号的几何形变残差&#xff0c;实现几何风格化。通过对超分网络引入AdaIN&#xff0c;实现纹理风格化。由于没有修改3D GAN空间&#xff0c;因此可以便捷实现Edit…...

配置Hive使用Spark执行引擎

配置Hive使用Spark执行引擎 Hive引擎概述兼容问题安装SparkSpark配置Hive配置HDFS上传Spark的jar包执行测试速度对比 Hive引擎 概述 在Hive中&#xff0c;可以通过配置来指定使用不同的执行引擎。Hive执行引擎包括&#xff1a;默认MR、tez、spark MapReduce引擎&#xff1a; 早…...

wordpress后台更新后 前端没变化的解决方法

使用siteground主机的wordpress网站&#xff0c;会出现更新了网站内容和修改了php模板文件、js文件、css文件、图片文件后&#xff0c;网站没有变化的情况。 不熟悉siteground主机的新手&#xff0c;遇到这个问题&#xff0c;就很抓狂&#xff0c;明明是哪都没操作错误&#x…...

基于ASP.NET+ SQL Server实现(Web)医院信息管理系统

医院信息管理系统 1. 课程设计内容 在 visual studio 2017 平台上&#xff0c;开发一个“医院信息管理系统”Web 程序。 2. 课程设计目的 综合运用 c#.net 知识&#xff0c;在 vs 2017 平台上&#xff0c;进行 ASP.NET 应用程序和简易网站的开发&#xff1b;初步熟悉开发一…...

STM32+rt-thread判断是否联网

一、根据NETDEV_FLAG_INTERNET_UP位判断 static bool is_conncected(void) {struct netdev *dev RT_NULL;dev netdev_get_first_by_flags(NETDEV_FLAG_INTERNET_UP);if (dev RT_NULL){printf("wait netdev internet up...");return false;}else{printf("loc…...

多模态商品数据接口:融合图像、语音与文字的下一代商品详情体验

一、多模态商品数据接口的技术架构 &#xff08;一&#xff09;多模态数据融合引擎 跨模态语义对齐 通过Transformer架构实现图像、语音、文字的语义关联。例如&#xff0c;当用户上传一张“蓝色连衣裙”的图片时&#xff0c;接口可自动提取图像中的颜色&#xff08;RGB值&…...

Keil 中设置 STM32 Flash 和 RAM 地址详解

文章目录 Keil 中设置 STM32 Flash 和 RAM 地址详解一、Flash 和 RAM 配置界面(Target 选项卡)1. IROM1(用于配置 Flash)2. IRAM1(用于配置 RAM)二、链接器设置界面(Linker 选项卡)1. 勾选“Use Memory Layout from Target Dialog”2. 查看链接器参数(如果没有勾选上面…...

NLP学习路线图(二十三):长短期记忆网络(LSTM)

在自然语言处理(NLP)领域,我们时刻面临着处理序列数据的核心挑战。无论是理解句子的结构、分析文本的情感,还是实现语言的翻译,都需要模型能够捕捉词语之间依时序产生的复杂依赖关系。传统的神经网络结构在处理这种序列依赖时显得力不从心,而循环神经网络(RNN) 曾被视为…...

[Java恶补day16] 238.除自身以外数组的乘积

给你一个整数数组 nums&#xff0c;返回 数组 answer &#xff0c;其中 answer[i] 等于 nums 中除 nums[i] 之外其余各元素的乘积 。 题目数据 保证 数组 nums之中任意元素的全部前缀元素和后缀的乘积都在 32 位 整数范围内。 请 不要使用除法&#xff0c;且在 O(n) 时间复杂度…...

Linux离线(zip方式)安装docker

目录 基础信息操作系统信息docker信息 安装实例安装步骤示例 遇到的问题问题1&#xff1a;修改默认工作路径启动失败问题2 找不到对应组 基础信息 操作系统信息 OS版本&#xff1a;CentOS 7 64位 内核版本&#xff1a;3.10.0 相关命令&#xff1a; uname -rcat /etc/os-rele…...

Go 并发编程基础:通道(Channel)的使用

在 Go 中&#xff0c;Channel 是 Goroutine 之间通信的核心机制。它提供了一个线程安全的通信方式&#xff0c;用于在多个 Goroutine 之间传递数据&#xff0c;从而实现高效的并发编程。 本章将介绍 Channel 的基本概念、用法、缓冲、关闭机制以及 select 的使用。 一、Channel…...

GO协程(Goroutine)问题总结

在使用Go语言来编写代码时&#xff0c;遇到的一些问题总结一下 [参考文档]&#xff1a;https://www.topgoer.com/%E5%B9%B6%E5%8F%91%E7%BC%96%E7%A8%8B/goroutine.html 1. main()函数默认的Goroutine 场景再现&#xff1a; 今天在看到这个教程的时候&#xff0c;在自己的电…...