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

017+C语言中函数栈帧的创建与销毁(VS2022环境)

0.前言

您好,这里是limou3434的一篇个人博文,感兴趣的话您也可以看看我的其他文章。本次我将和您一起学习在C语言中函数栈帧的概念。

1.学习函数栈帧的意义

  • 局部变量是怎么穿创建的?为什么局部变量的值是随机的
  • 函数是怎么传参的?传参的顺序是怎么样的?
  • 形参和实参是什么关系?
  • 函数调用是怎么做的?函数调用时结束后怎么返回?

2.先不要使用太高级的编译器

编译器越高级就越难以观察到这些细节,因为有可能编译器做了非常高的封装,使得一些细节被其隐藏。但是使用新版本的编译器也行,有些时候大差不差。(例如本例中使用的VS2022在其汇编代码中,就有部分指令是VS2022自己加上的,这些指令对我们的学习暂时无关紧要,可以先忽略)

3.不同编译器函数调用中创建的栈帧有可能不同

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

4.计算机内的寄存器

计算机内部最常见的寄存器有“eax、ebx、ecx、edx”还有“ebp、esp”,最后两个寄存器存放的是地址,而这两个地址是用来维护函数栈帧的

5.调用main函数的函数

实际上是有函数来调用main函数的,这个函数就是“__tmainCRTStartup()”,而调用这个函数的函数是“mainCRTStartup()”,而调用这个函数的是操作系统

6.粗略解释函数栈帧的开辟和esp、ebp寄存器的使用

//源代码
#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;
}

如果把函数栈帧简单理解,则对于上面的代码就对应下面的函数栈帧建立图示过程

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
但是如果仅仅是这么讲是远远不够的,接下来我们来试试读读一些相关代码的汇编代码(哪怕您没有学过汇编也不必担心,只需看懂个大概即可)

7.详细解释函数栈帧的开辟和开寄存器的使用

下面的汇编代码不用细看,只是整理出来让您结合图解来分析函数栈帧开辟的细节,您可以看完图解再回到汇编代码来复习

  • C语言的源代码
//源代码
#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;
}
  • 上述源代码生成对应的汇编代码
//main函数内部的汇编代码
int main()
{
00B518B0  push        ebp  
00B518B1  mov         ebp,esp  
00B518B3  sub         esp,0E4h  
00B518B9  push        ebx  
00B518BA  push        esi  
00B518BB  push        edi  
00B518BC  lea         edi,[ebp-24h]  
00B518BF  mov         ecx,9  
00B518C4  mov         eax,0CCCCCCCCh  
00B518C9  rep stos    dword ptr es:[edi]  
00B518CB  mov         ecx,0B5C008h  
00B518D0  call        00B5131B  int a = 10;
00B518D5  mov         dword ptr [ebp-8],0Ah  int b = 20;
00B518DC  mov         dword ptr [ebp-14h],14h  int c = 0;
00B518E3  mov         dword ptr [ebp-20h],0  c = Add(a, b);
00B518EA  mov         eax,dword ptr [ebp-14h]  
00B518ED  push        eax  
00B518EE  mov         ecx,dword ptr [ebp-8]  
00B518F1  push        ecx  
00B518F2  call        00B513B6  
00B518F7  add         esp,8  
00B518FA  mov         dword ptr [ebp-20h],eax  printf("%d\n", c);
00B518FD  mov         eax,dword ptr [ebp-20h]  
00B51900  push        eax  
00B51901  push        0B57B30h  
00B51906  call        00B510D2  
00B5190B  add         esp,8  return 0; 
00B5190E  xor         eax,eax  
}
00B51910  pop         edi  
00B51911  pop         esi  
00B51912  pop         ebx  
00B51913  add         esp,0E4h  
00B51919  cmp         ebp,esp  
00B5191B  call        00B51244  
00B51920  mov         esp,ebp  
00B51922  pop         ebp  
00B51923  ret  
//在调用Add函数时,其内部的汇编代码
int Add(int x, int y)
{
00221FF0  push        ebp  
00221FF1  mov         ebp,esp  
00221FF3  sub         esp,0CCh  
00221FF9  push        ebx  
00221FFA  push        esi  
00221FFB  push        edi  
00221FFC  lea         edi,[ebp-0Ch]  
00221FFF  mov         ecx,3  
00222004  mov         eax,0CCCCCCCCh  
00222009  rep stos    dword ptr es:[edi]  
0022200B  mov         ecx,22C008h  
00222010  call        0022131B  int z = 0;
00222015  mov         dword ptr [ebp-8],0  z = x + y;
0022201C  mov         eax,dword ptr [ebp+8]  
0022201F  add         eax,dword ptr [ebp+0Ch]  
00222022  mov         dword ptr [ebp-8],eax  return z;
00222025  mov         eax,dword ptr [ebp-8]  
}
00222028  pop         edi  
00222029  pop         esi  
0022202A  pop         ebx  
0022202B  add         esp,0CCh  
00222031  cmp         ebp,esp  
00222033  call        00221244  
00222038  mov         esp,ebp  
0022203A  pop         ebp  
0022203B  ret  

图解1(__tmainCRTStartup函数调用main函数)

在这里插入图片描述

图解2

在这里插入图片描述

图解3

在这里插入图片描述

图解4

在这里插入图片描述

图解5

在这里插入图片描述

图解6(main函数调用Add函数)

在这里插入图片描述

图解7

在这里插入图片描述

图解8

在这里插入图片描述

图解9

在这里插入图片描述

图解10

在这里插入图片描述

图解11

在这里插入图片描述

图解12

在这里插入图片描述

图解13

在这里插入图片描述

图解14

在这里插入图片描述

图解15

在这里插入图片描述

图解16

在这里插入图片描述
……后续步骤我不再给出,如果您完整的看过上面的图解后,就能很清晰的理解栈帧这一概念了,也能对后续没有做图解的汇编代码进行理解

8.总结

这次我采用绘图的方式帮助您了解函数创立栈帧的详细过程,还希望您能仔细地看下去,这是一个C程序员内功的一部分。

相关文章:

017+C语言中函数栈帧的创建与销毁(VS2022环境)

0.前言 您好&#xff0c;这里是limou3434的一篇个人博文&#xff0c;感兴趣的话您也可以看看我的其他文章。本次我将和您一起学习在C语言中函数栈帧的概念。 1.学习函数栈帧的意义 局部变量是怎么穿创建的&#xff1f;为什么局部变量的值是随机的函数是怎么传参的&#xff1…...

马斯克们叫停 GPT-5,更像是场行为艺术

目录 01 联名信说了什么&#xff1f; 02 发起方是谁&#xff1f; 03 谁签署了联名信&#xff1f; 04 联名信有哪些问题&#xff1f;三巨头的另外两位 Sam Altman 的表态 其他值得关注的署名者 比如马斯克。 另一个位于前列的署名者是 Stability AI 的创始人 Emad Most…...

事务基础知识

第13章 事务基础知识 1. 数据库事务概述 1.1 基本概念 **事务&#xff1a;**一组逻辑操作单元&#xff0c;使数据从一种状态变换到另一种状态。 **事务处理的原则&#xff1a;**保证所有事务都作为一个工作单元来执行&#xff0c;即使出现了故障&#xff0c;都不能改变这种…...

国产高性能DSP音频处理芯片的工作原理以及应用领域

DSP芯片是数字信号处理器的简称&#xff0c;它是一种专门用于数字信号处理的微处理器&#xff0c;它可以对数字信号进行高速运算和处理。DSP是一类嵌入式通用可编程微处理器&#xff0c;主要用于实现对信号的采集、识别、变换、增强、控制等算法处理&#xff0c;是各类嵌入式系…...

BEVDet4D 论文学习

1. 解决了什么问题&#xff1f; 单帧数据包含的信息很有限&#xff0c;制约了目前基于视觉的多相机 3D 目标检测方法的性能&#xff0c;尤其是关于速度预测任务&#xff0c;要远落后于基于 LiDAR 和 radar 的方法。 2. 提出了什么方法&#xff1f; BEVDet4D 将 BEVDet 方法从…...

【设计模式与范式:创建型】43 | 单例模式(下):如何设计实现一个集群环境下的分布式单例模式?

上两节课中&#xff0c;我们针对单例模式&#xff0c;讲解了单例的应用场景、几种常见的代码实现和存在的问题&#xff0c;并粗略给出了替换单例模式的方法&#xff0c;比如工厂模式、IOC 容器。今天&#xff0c;我们再进一步扩展延伸一下&#xff0c;一块讨论一下下面这几个问…...

Metal入门学习:绘制渲染三角形

一、编程指南PDF下载链接(中英文档&#xff09; 1、Metal编程指南PDF链接 https://github.com/dennie-lee/ios_tech_record/raw/main/Metal学习PDF/Metal 编程指南.pdf 2、Metal着色语言(Metal Shader Language:简称MSL)编程指南PDF链接 https://github.com/dennie-lee/ios_te…...

python 中常见变量类型

数值 a 10 b 123 … 字符串 在python中 用单引号’‘和双引号""括起来的都是字符串,不使用引号括起来的不是字符串&#xff0c;字符串是使用最多的数据类型&#xff0c;用来表示一段文本信息。 比如&#xff1a; a ‘123’ b “123” 字符串之间可以用加法运算…...

SVN使用教程(一)

文章目录 前言一、SVN是什么&#xff1f;二、SVN和Git对比&#xff0c;有什么优势&#xff1f;三、SVN主要应用四、SVN仓库五、安装SVN客户端 前言 提示&#xff1a;这里可以添加本文要记录的大概内容&#xff1a; 在制作系统或者写文档&#xff0c;都需要用于管理和跟踪开发…...

【5.19】四、性能测试—指标、种类

目录 4.1 性能测试概述 4.2 性能测试的指标 4.3 性能测试的种类 为了追求高质量、高效率的生活与工作&#xff0c;人们对软件产品的性能要求越来越高&#xff0c;例如软件产品要足够稳定、响应速度足够快&#xff0c;在用户量、工作量较大时也不会出现崩溃或卡顿等现象。人们…...

Windows平台上的5种敏捷软件开发(过程)模型

我是荔园微风&#xff0c;作为一名在IT界整整25年的老兵&#xff0c;今天总结一下Windows平台上的5种敏捷软件开发(过程)模型。 说到这个问题&#xff0c;你必须先知道除了敏捷模型还有没有其他什么模型&#xff1f;同时要比较模型的区别&#xff0c;首先还要看看什么叫软件开…...

一文实现部署AutoGPT

一文实现部署AutoGPT 简介AutoGPT的概述AutoGPT的用途和优势 预备知识Python基础机器学习基础自然语言处理基础 环境设置Python环境安装和配置需要的库和框架的安装&#xff0c;例如PyTorch, Transformers等 AutoGPT模型加载如何下载和加载预训练的AutoGPT模型模型参数和配置 使…...

数值计算 - 误差的来源

误差的来源是多方面的&#xff0c;但主要来源为&#xff1a;过失误差&#xff0c;描述误差&#xff0c;观测误差&#xff0c;截断误差和舍入误差。 过失误差 过失误差是由设备故障和人为的错误所产生的误差&#xff0c;在由于每个人都有“权利”利用机器进行数值计算,所以在计算…...

【软件测试】5年测试老鸟总结,自动化测试成功实施,你应该知道的...

目录&#xff1a;导读 前言一、Python编程入门到精通二、接口自动化项目实战三、Web自动化项目实战四、App自动化项目实战五、一线大厂简历六、测试开发DevOps体系七、常用自动化测试工具八、JMeter性能测试九、总结&#xff08;尾部小惊喜&#xff09; 前言 自动化测试 Pytho…...

【Hadoop】二、Hadoop MapReduce与Hadoop YARN

文章目录 二、Hadoop MapReduce与Hadoop YARN1、Hadoop MapReduce1.1、理解MapReduce思想1.2、Hadoop MapReduce设计构思1.3、Hadoop MapReduce介绍1.4、Hadoop MapReduce官方示例1.5、Map阶段执行流程1.6、Reduce阶段执行流程1.7、Shuffle机制 2、Hadoop YARN2.1、Hadoop YARN…...

Python教程:文件I/O的用法

本章只讲述所有基本的的I/O函数&#xff0c;更多函数请参考Python标准文档。 1.打印到屏幕 最简单的输出方法是用print语句&#xff0c;你可以给它传递零个或多个用逗号隔开的表达式。此函数把你传递的表达式转换成一个字符串表达式&#xff0c;并将结果写到标准输出如下&…...

序员工作1年,每天上班清闲,但却焦虑万分,若是你,你会吗?

有个学弟在后台留言 他谈到了自己去年毕业的 因为在大学里边有一些校企合作 所以呢他也是花了钱 然后去培训了有半年 去年毕业之后到现在工作有一年了 那目前的薪资是8,000块钱 虽然说相较于其他同学呢 这个薪资呢还算可以 但是呢 自己每天现在就处于一种非常 压抑的那种状态 所…...

Bed Bath and Beyond EDI 需求分析

Bed Bath and Beyond&#xff08;Bed Bath and Beyond&#xff09;是一家美国的家居用品零售商&#xff0c;成立于1971年&#xff0c;总部位于新泽西州Union。该公司在美国、加拿大和墨西哥拥有超过1500家门店。其产品涵盖了床上用品、浴室用品、厨房用品、家居装饰等领域&…...

【5.20】五、安全测试——渗透测试

目录 5.3 渗透测试 5.3.1 什么是渗透测试 5.3.2 渗透测试的流程 5.3 渗透测试 5.3.1 什么是渗透测试 渗透测试是利用模拟黑客攻击的方式&#xff0c;评估计算机网络系统安全性能的一种方法。这个过程是站在攻击者角度对系统的任何弱点、技术缺陷或漏洞进行主动分析&#x…...

java版鸿鹄工程项目管理系统 Spring Cloud+Spring Boot+前后端分离构建工程项目管理系统源代码

鸿鹄工程项目管理系统 Spring CloudSpring BootMybatisVueElementUI前后端分离构建工程项目管理系统 1. 项目背景 一、随着公司的快速发展&#xff0c;企业人员和经营规模不断壮大。为了提高工程管理效率、减轻劳动强度、提高信息处理速度和准确性&#xff0c;公司对内部工程管…...

Python:操作 Excel 折叠

💖亲爱的技术爱好者们,热烈欢迎来到 Kant2048 的博客!我是 Thomas Kant,很开心能在CSDN上与你们相遇~💖 本博客的精华专栏: 【自动化测试】 【测试经验】 【人工智能】 【Python】 Python 操作 Excel 系列 读取单元格数据按行写入设置行高和列宽自动调整行高和列宽水平…...

Opencv中的addweighted函数

一.addweighted函数作用 addweighted&#xff08;&#xff09;是OpenCV库中用于图像处理的函数&#xff0c;主要功能是将两个输入图像&#xff08;尺寸和类型相同&#xff09;按照指定的权重进行加权叠加&#xff08;图像融合&#xff09;&#xff0c;并添加一个标量值&#x…...

【磁盘】每天掌握一个Linux命令 - iostat

目录 【磁盘】每天掌握一个Linux命令 - iostat工具概述安装方式核心功能基础用法进阶操作实战案例面试题场景生产场景 注意事项 【磁盘】每天掌握一个Linux命令 - iostat 工具概述 iostat&#xff08;I/O Statistics&#xff09;是Linux系统下用于监视系统输入输出设备和CPU使…...

大语言模型如何处理长文本?常用文本分割技术详解

为什么需要文本分割? 引言:为什么需要文本分割?一、基础文本分割方法1. 按段落分割(Paragraph Splitting)2. 按句子分割(Sentence Splitting)二、高级文本分割策略3. 重叠分割(Sliding Window)4. 递归分割(Recursive Splitting)三、生产级工具推荐5. 使用LangChain的…...

el-switch文字内置

el-switch文字内置 效果 vue <div style"color:#ffffff;font-size:14px;float:left;margin-bottom:5px;margin-right:5px;">自动加载</div> <el-switch v-model"value" active-color"#3E99FB" inactive-color"#DCDFE6"…...

Module Federation 和 Native Federation 的比较

前言 Module Federation 是 Webpack 5 引入的微前端架构方案&#xff0c;允许不同独立构建的应用在运行时动态共享模块。 Native Federation 是 Angular 官方基于 Module Federation 理念实现的专为 Angular 优化的微前端方案。 概念解析 Module Federation (模块联邦) Modul…...

C# SqlSugar:依赖注入与仓储模式实践

C# SqlSugar&#xff1a;依赖注入与仓储模式实践 在 C# 的应用开发中&#xff0c;数据库操作是必不可少的环节。为了让数据访问层更加简洁、高效且易于维护&#xff0c;许多开发者会选择成熟的 ORM&#xff08;对象关系映射&#xff09;框架&#xff0c;SqlSugar 就是其中备受…...

多模态大语言模型arxiv论文略读(108)

CROME: Cross-Modal Adapters for Efficient Multimodal LLM ➡️ 论文标题&#xff1a;CROME: Cross-Modal Adapters for Efficient Multimodal LLM ➡️ 论文作者&#xff1a;Sayna Ebrahimi, Sercan O. Arik, Tejas Nama, Tomas Pfister ➡️ 研究机构: Google Cloud AI Re…...

网络编程(UDP编程)

思维导图 UDP基础编程&#xff08;单播&#xff09; 1.流程图 服务器&#xff1a;短信的接收方 创建套接字 (socket)-----------------------------------------》有手机指定网络信息-----------------------------------------------》有号码绑定套接字 (bind)--------------…...

【HarmonyOS 5 开发速记】如何获取用户信息(头像/昵称/手机号)

1.获取 authorizationCode&#xff1a; 2.利用 authorizationCode 获取 accessToken&#xff1a;文档中心 3.获取手机&#xff1a;文档中心 4.获取昵称头像&#xff1a;文档中心 首先创建 request 若要获取手机号&#xff0c;scope必填 phone&#xff0c;permissions 必填 …...