【C++庖丁解牛】函数栈帧的创建与销毁

目录
- 1. 寄存器
- 2. ebp和esp是如何对堆栈进行维护的,mian函数栈帧如何创建
- 2.1 push ebp
- 2.1 move ebp esp
- 2.2 sub esp, 0E4h
- 2.3 push exb
- 2.4 push exi
- 2.5 push edi
- 2.6 push edi
- 2.6 lea edi,[ebp+FFFFFF1Ch]
- 2.7 mov ecx,39h 以及mov eax,0CCCCCCCCh
- 2.8 rep stos dword ptr es : [edi]
- 3. 局部变量栈帧的创建
- 3.1 对a分配空间
- 3.2 对b分配空间
- 3.3 对c分配空间
- 4. 函数的调用
1. 寄存器
寄存器我们了解过有eax、ebx、ecx、edx、ebp、esp等等
本节的重点是我们的ebp、esp这两个寄存器,这两个寄存器中存放的是地址,这两个地址是用来维护函数栈帧的
每一个函数的调用都要创建一块空间,这个空间创建在栈区上。
- esp则为我们的栈顶指针
- ebp就是我们的栈底指针
esp (EStack Pointer):栈顶指针,它指向当前栈帧中的栈顶位置。每当一个新的函数被调用时,esp会动态地更新以跟踪新参数的压入和局部变量的分配。当函数执行完毕,esp会回退到释放这些资源的位置。
ebp (EBase Pointer):栈底指针,又称为基指针,它通常用于存储当前函数的帧信息,比如函数的局部变量、参数和其他数据。ebp在函数开始时被设置为栈顶减去函数头部所需的空间,这样就可以作为访问栈中所有局部变量的基地址。
在函数调用过程中,esp和ebp经常被用来进行帧布局的操作,例如保存旧的esp值,然后将新的esp指向新的函数参数,而 ebp则保持不变,作为固定不变的局部变量基址。当函数返回时,esp通常会恢复到原来的值,释放栈帧,而ebp也会回到正确的基址,以便后续函数继续正确地访问局部变量。
2. ebp和esp是如何对堆栈进行维护的,mian函数栈帧如何创建
其实main函数也是被另一个内部系统函数调用的
具体调用为
mainCRTStartup
—>__tmainCRTStartup
—>main
前两个函数都是系统里的调用函数
程序在一开始运行时,ebp以及esp是维护__tmainCRTStartup的函数栈帧的
栈空间的使用是由高地址往低地址使用的
在执行main函数的时候就会往上进行创建栈帧
2.1 push ebp
我们将写的代码进行反汇编的操作,看到程序底层的汇编代码可以看到第一步就是对于ebp
的push
操作
push ebp
的作用是将ebp
的值压栈(Push the value of ebp onto the stack),这样在函数执行过程中,ebp
就不会被其他操作覆盖,保持对函数调用上下文的引用。
当函数开始执行时,push ebp 让 ebp 保存当前堆栈帧的状态,然后
mov ebp, esp
将esp
(栈指针)的内容赋给ebp
,从而esp
指向新的栈顶,用来作为新创建的局部变量的内存地址。这样做有助于维护函数调用的上下文,便于后续访问和管理局部变量、参数等。
也就是说将ebp此时的值存入栈中,以便后面进行查找,在此时就是__tmainCRTStartup的ebp值
当我们在没有执行push操作时,esp与ebp的值如下
在我们执行后esp的值从后两位为a8,变为了a4
这也说明了esp被压入栈。
此时的esp则往低地址走了几步,现在指向的就是__tmainCRTStartup的ebp
的地方了
2.1 move ebp esp
执行了 push ebp
之后,第二步就是move ebp esp
move ebp esp
的操作意味着将ebp
的值赋给esp
。这种操作经常发生在函数返回或异常处理时,因为当函数结束时,可能需要清空堆栈,将esp
回退到栈帧之前的状态,以便为下一次函数调用腾出空间。在清理过程中,ebp
通常会被用来保存堆栈的原有状态,然后将其位置替换到esp
,这样就可以清除函数调用时的信息。
也就是ebp与esp都指向__tmainCRTStartup的ebp
2.2 sub esp, 0E4h
第三步为sub esp, 0E4h
sub esp, 0E4h
是一个指令组合,它代表"从堆栈指针ESP(通常用于跟踪函数调用时的局部变量和参数)中减去0E4个字节(16进制的0E4等于十进制的220)"。这个操作常用于函数调用或内存分配,可能是为了为新的局部变量分配空间或者调整堆栈布局。
具体来说:
- sub是"subtract"的缩写,即减法操作。
- esp是堆栈指针,它指向栈顶,减去一个数意味着将栈顶地址向下移动。
- 0E4h是一个16进制数,转换成十进制就是220,所以实际上是将栈顶的220个字节移除或压入栈中。
这段空间其实就是为main函数预留的一段空间
在执行完这个操作后
2.3 push exb
push exb顾名思义也是将exb此时的数据存储到栈中
2.4 push exi
将esi此时的数据存储到栈中
2.5 push edi
2.6 push edi
2.6 lea edi,[ebp+FFFFFF1Ch]
lea edi, [ebp+FFFFFF1Ch]
是一条x86汇编指令,其中 “lea” 是load effective address
(有效地址加载)的缩写,它用于计算并存储一个内存地址到寄存器edi中。在这个指令中:
edi
是destination operand
(目标操作数),通常用于存放计算出的内存地址。[ebp+FFFFFF1Ch]
是source operand
(源操作数),它使用基址加变址寻址方式。ebp
是基指针(base pointer),用于访问栈帧中的数据。加上偏移量FFFFFF1Ch
,意味着从栈帧的当前位置向上偏移0xFFFFFF1Ch
处的内存位置。
这条指令的作用是将栈上某个特定位置的地址赋值给edi,这个位置通常是函数调用时为了后续操作需要而存储的数据地址。在分析程序代码时,这可能对应于函数的局部变量、参数或其他动态分配的数据结构的地址。
在这里其实就是mian函数的栈顶地址给了edi寄存器
2.7 mov ecx,39h 以及mov eax,0CCCCCCCCh
-
mov ecx, 39h
: 这行指令将立即数39h
(十六进制,等于十进制的 57)传送到名为 ecx 的寄存器中。ecx 通常用于索引或循环计数。在这里,ecx 被设置为一个特定的值,可能用于控制某种循环次数或者作为数组操作的下标。 -
mov eax, 0CCCCCCCCh
: 这行指令将十六进制数值0CCCCCCCCh
(十进制的 -1073741821) 移动到 eax 寄存器。eax 在x86架构中是一个常用的通用寄存器,常用于存储操作数。0CCCCCCCCh
是一个特殊的值,有时在某些情况下用于测试内存是否已初始化(因为它几乎不会出现在正常的初始化中)。
相当于代码
ecx = 39h
eax = 0CCCCCCCCh
对这两个寄存器赋值
2.8 rep stos dword ptr es : [edi]
dword ptr es:[edi] ,edi(EAX的低16位)是一个寄存器,指向存储的起始位置,es(额外段寄存器)指定数据段,ptr表示是按字节偏移地址。因此,这整个指令组合的意思是:
从
edx寄存器
开始,重复执行存储操作,每次将源操作数中的两个字节写入es段的当前指定位,然后地址指针edi
递增指向下一个存储位置,直到所有数据都被写入。
也就是将ecx
中39h
个空间全部写入成eax
的0CCCCCCCCh
,相当于给我们开辟的空间进行初始化
以上这个部分main函数的函数栈帧就已经创建完成了
3. 局部变量栈帧的创建
3.1 对a分配空间
这里就是将a放入ebp-8的位置上去,a为int类型四个字节
3.2 对b分配空间
3.3 对c分配空间
4. 函数的调用
这里的步骤就是
- 将b的值放入eax中,再将eax压栈,放入栈中
- 将a的值放入ecx中,再将ecx压栈,放入栈中
- call指令调用add函数,call指令前面的地址为call指令的下一条地址
- 跳到add函数准备栈帧,并执行add函数
最后通过函数的调用返回结果,最后得到结果
相关文章:

【C++庖丁解牛】函数栈帧的创建与销毁
🍁你好,我是 RO-BERRY 📗 致力于C、C、数据结构、TCP/IP、数据库等等一系列知识 🎄感谢你的陪伴与支持 ,故事既有了开头,就要画上一个完美的句号,让我们一起加油 目录 1. 寄存器2. ebp和esp是如…...
Java基础16(集合框架 List ArrayList容器类 ArrayList底层源码解析及扩容机制)
目录 一、什么是集合? 二、集合接口 三、List集合 四、ArrayList容器类 1. 常用方法 1.1 增加 1.2 查找 int size() E get(int index) int indexOf(Object c) boolean contains(Object c) boolean isEmpty() List SubList(int fromindex,int …...

数组:移除元素
参考资料:代码随想录 本题思路:通过快慢指针将两次循环减少到一次 class Solution {public int removeElement(int[] nums, int val) {//0 1 2 2 2 2 3int fast 0;int slow 0;while(fast < nums.length){if(nums[fast] ! val){nums[slow] nums[f…...

胡说八道(24.6.22)——通信杂谈(完结)
上回书说到雷达和香农的信息论,今天来进行完结。 数字幅值调制或幅值键控(ASK)调制方式是指载波信号的幅值随数字基带信号而变化,因此可以实现将基带信号搬移到载波频段。2ASK是利用代表数字信息0或1的基带矩形脉冲去键控一个连续…...

设计模式原则——里氏替换原则
设计模式原则 设计模式示例代码库地址: https://gitee.com/Jasonpupil/designPatterns 里氏替换原则 继承必须确保父类所拥有的性质在子类中依然成立 与开闭原则不同的是开闭原则可以改变父类原有的功能,里氏替换原则不能修改父类的原有的性质&#…...

详解 ClickHouse 的 SQL 操作
传统关系型数据库(以 MySQL 为例)的 SQL 语句,ClickHouse 基本都支持 一、插入 --语法: insert into table_name values(xxxxxx),(yyyyyyy),...;insert into table_name select xxxxx from table_name2 where yyyyy;二、更新和删…...

WPF与Winform,你的选择是?
概述 在桌面应用的发展历程中,Winform和WPF作为微软推出的两大框架,各自承载着不同的设计理念和技术特色。Winform以其稳定、成熟的技术基础,长期占据着企业级应用开发的重要地位。而WPF,作为后来者,以其现代化的UI设计…...

基于SpringBoot的实习管理系统设计与实现
你好呀,我是计算机学姐码农小野!如果有相关需求,可以私信联系我。 开发语言: Java 数据库: MySQL 技术: SpringBoot框架,B/S模式 工具: MyEclipse,Tomcat 系统展示 …...

编程用什么电脑不卡的:深度解析与推荐
编程用什么电脑不卡的:深度解析与推荐 在编程的世界里,一台流畅不卡的电脑无疑是每个开发者的得力助手。然而,面对市场上琳琅满目的电脑品牌和型号,如何选择一台适合编程的电脑却成为了一个令人困惑的问题。本文将从四个方面、五…...

优先级队列模拟实现
目录 1.堆的概念 2.堆性质堆中的某个元素小于或大于他的左右孩子 3.小根堆实例 4.堆创建 4.1调整思路 4.2向下调整思路 4.3代码实现(大根堆) 5.堆的删除 6.堆的插入 7.常用接口 7.1PriorityQueue和PriorityBlockingQueue 1.堆的概念 如果有一…...

记一次服务器崩溃事件
今天在安装Jenkins的时候,进行到插件安装这一步,本来一切顺利,结果最后安装完成之后一直进不去网页,显示连接超时,网上搜索了一圈也没发现什么相似的情况,当我疑惑的时候回到Linux控制台,发现命…...

神经网络 #数据挖掘 #Python
神经网络是一种受生物神经元系统启发的人工计算模型,用于模仿人脑的学习和决策过程。它由大量互相连接的节点(称为神经元)组成,这些节点处理和传递信息。神经网络通常包含输入层、隐藏层(可有多个)和输出层…...

营销复盘秘籍,6步法让你的活动效果翻倍
在营销的世界中,每一次活动都是一次探险,而复盘就是探险后的宝藏图,指引我们发现问题、提炼经验、优化策略。 想要学习如何复盘,只要了解以下复盘六大步骤,即可不断总结,逐渐走向卓越。 第一步࿱…...

Linux下命令行文件创建删除、目录创建删除
在Linux命令行下,文件和目录的创建与删除是通过一系列基础命令完成的,这些命令对于日常的系统管理和文件操作至关重要。 下面将详细介绍这些命令的功能和使用方法。 普通文件的创建与删除 创建文件 touch命令:主要用于创建一个空文件&…...

数字排列问题
题目:有1、2、3、4个数字,能组成多少个互不相同且无重复数字的三位数?都是多少? 代码: #include <stdio.h> int main() { int count 0; // 计数器,记录生成的三位数的数量 // 使用三个嵌套的fo…...

CentOS Linux 7系统中离线安装MySQL5.7步骤
预计数据文件存储目录为:/opt/mysql/data 1、文件下载: 安装文件下载链接:https://downloads.mysql.com/archives/community/ 2、检查当前系统是否安装过MySQL [rootcnic51 mysql]# rpm -qa|grep mariadb mariadb-libs-5.5.68-1.el7.x86_6…...

XSS跨站攻击漏洞
XSS跨站攻击漏洞 一 概述 1 XSS概述 xss全称为:Cross Site Scripting,指跨站攻击脚本,XSS漏洞发生在前端,攻击的是浏览器的解析引擎,XSS就是让攻击者的JavaScript代码在受害者的浏览器上执行。 XSS攻击者的目的就是…...

PMP到底值不值得考?
首先,咱们得明白PMP是个啥。 PMP,全称Project Management Professional,是美国项目管理协会PMI颁发的一个项目管理专业人士资格认证。 PMP证书在项目管理领域可是有着举足轻重的地位,与MBA、MPA并驾齐驱,被称为“全球…...

redis面试总结
redis的数据类型? string字符串:类似于java中Map<String,String>。存储字符串、JSON数据、验证码等。 Hash字典:类似java中Map<String, Map<Spring,String>>。比较适合存储对象数据。 List列表:类似java中Ma…...

大模型日报2024-06-24
大模型日报 2024-06-24 大模型资讯 大模型产品 AI快速生成专业播客 摘要: MakePodcast.io使用AI语音,只需提供脚本并选择声音,即可在几分钟内生成专业质量的播客。 Sherloq:SQL用户的AI协作仓库 摘要: Sherloq为SQL查询提供一站式管理&#x…...

深入理解计算机系统 CSAPP 练习题7.4
A:0x4004e8(-4)-50x4004df B:0x5...

摘苹果-第13届蓝桥杯省赛Python真题精选
[导读]:超平老师的Scratch蓝桥杯真题解读系列在推出之后,受到了广大老师和家长的好评,非常感谢各位的认可和厚爱。作为回馈,超平老师计划推出《Python蓝桥杯真题解析100讲》,这是解读系列的第88讲。 摘苹果࿰…...

开源项目推荐-vue2+element+axios 个人财务管理系统
文章目录 financialmanagement项目简介项目特色项目预览卫星的实现方式:首次进入卫星效果的实现方式:卫星跟随鼠标滑动的随机效果实现方式:环境准备项目启动项目部署项目地址 financialmanagement 项目简介 vue2elementaxios 个人财务管理系…...

手机数据如何恢复?11 款最佳安卓手机恢复软件
媒体可能由于各种原因而从您的设备中删除,可能是意外或病毒攻击。 在这些情况下,照片恢复应用程序是唯一的解决方案。理想的照片恢复应用程序取决于各种因素,例如存储设备的损坏程度、删除照片后的持续时间以及应用程序使用的恢复算法的有效性…...

大语言模型千问2的web搭建(streamlit)
Qwen2的web搭建(streamlit) 千问2前段时间发布了,个人觉得千问系列是我用过最好的中文开源大模型,所以这里基于streamlit进行一个千问2的web搭建,来进行模型的测试 一、硬件要求 该文档中使用的千问模型为7B-Instruct,需要5g以…...

守护生产车间安全:可燃气体报警器预警与检测的重要性
近日,东莞一材料厂发生的火灾事故再次敲响了工业安全生产的警钟。 这起事故不仅给工厂带来了巨大的经济损失,也暴露了一些企业在安全管理方面的疏漏。其中,可燃气体报警器的应用与预警功能在火灾防范中扮演了至关重要的角色。 接下来&#…...

[创业之路-125] :制造业企业的必备管理神器-ERP-计算的资源管理与企业的资源管理的异同
目录 一、计算机的资源与企业资源相同点与不同点 1.1 相同点: 1.2 不同点: 二、计算机的内存管理与企业的库存管理相同点与不同点 2.1 相同点: 2.2 不同点: 一、计算机的资源与企业资源相同点与不同点 计算机的资源与企业资…...

TDengine Cloud 新增签约,这次是能源物联网平台
最近,全托管的物联网、工业大数据云服务平台 TDengine Cloud 新增一项签约🥳。为进一步提升平台的数据处理能力与系统稳定性,推动智能设备数据管理和能效优化到新的高度, 德中恒越物联网数据平台选择应用 TDengine Cloud ☁️。 …...

Kafka 最佳实践:构建高性能、可靠的数据管道
目录 1. 部署最佳实践 1.1 硬件配置 1.2 集群配置 1.3 ZooKeeper 配置 2. 主题和分区设计 2.1 分区设计 2.2 数据保留策略 3. 生产者最佳实践 3.1 生产确认机制 3.2 重试机制 3.3 批量发送 4. 消费者最佳实践 4.1 消费组管理 4.2 并行处理 4.3 错误处理 5. 安全…...

进军韩国5G市场!移远通信5G模组RG500L-EU率先获得KT、LGU+认证
近日,移远通信工规级5G模组RG500L-EU再传喜讯,率先通过了韩国两大运营商KT和LGU的严格认证。在此之前,该模组已顺利通过KC认证(韩国法规认证),此次再获运营商认证表明,RG500L-EU已完全满足韩国…...