C7.5【x86汇编】底层分析范围for的执行过程

news2025/1/16 5:07:13

目录

1.反汇编代码

2.分析

1.栈区初始化

2.设置数组元素的值

3. 逐条分析范围for

1.arr的地址被放到[ebp-2Ch]处

2.[ebp-2Ch]指向的值被复制一份到[ebp-30h]处

3.eax暂存[ebp-2Ch]指向的值,加28h后存储到[ebp-34h]处

4.跳转指令

5.比较[ebp-30h]和[ebp-34h]指向的值,如果相等则跳转到return 0;的反汇编指令

6.将数组元素的值载入ecx寄存器,再将其赋值给变量a

7. 跳转指令

 8.更新[ebp-30h]指向的值,每次执行都+4(原因:int类型的数组)

4.函数返回,空间释放

5.总结

几个重要参数

编译器为什么要这样设计汇编指令

3.范围for的核心思想


承接C7.【C++ Cont】范围for的使用和auto关键字文章的遗留任务

1.反汇编代码

#include <iostream>
using namespace std;
int main()
{
 push        ebp  
 mov         ebp,esp  
 sub         esp,78h  
 push        ebx  
 push        esi  
 push        edi  
 mov         ecx,offset _2A500742_leetcode@cpp 
 call        @__CheckForDebuggerJustMyCode@4 
 nop  
	int arr[10] = { 1,2,3,4,5,6,7,8,9,10 };
 mov         dword ptr [arr],1  
 mov         dword ptr [ebp-24h],2  
 mov         dword ptr [ebp-20h],3  
 mov         dword ptr [ebp-1Ch],4  
 mov         dword ptr [ebp-18h],5  
 mov         dword ptr [ebp-14h],6  
 mov         dword ptr [ebp-10h],7  
 mov         dword ptr [ebp-0Ch],8  
 mov         dword ptr [ebp-8],9  
 mov         dword ptr [ebp-4],0Ah  
	for (int a : arr)
 lea         eax,[arr]  
 mov         dword ptr [ebp-2Ch],eax  
 mov         eax,dword ptr [ebp-2Ch]  
 mov         dword ptr [ebp-30h],eax  
 mov         eax,dword ptr [ebp-2Ch]  
 add         eax,28h  
 mov         dword ptr [ebp-34h],eax  
 jmp         main+7Ah 
 mov         eax,dword ptr [ebp-30h]  
 add         eax,4  
 mov         dword ptr [ebp-30h],eax  
 mov         eax,dword ptr [ebp-30h]  
 cmp         eax,dword ptr [ebp-34h]  
 je          main+8Ch 
 mov         eax,dword ptr [ebp-30h]  
 mov         ecx,dword ptr [eax]  
 mov         dword ptr [ebp-38h],ecx  
	{
		
	}
 jmp         main+71h  
	return 0;
 xor         eax,eax  
}
 pop         edi  
 pop         esi  
 pop         ebx  
 mov         esp,ebp  
 pop         ebp  
 ret

已知

jmp main+7Ah 跳转到add eax,4下方第一个mov eax,dword ptr [ebp-30h]

je main+8Ch 若符合条件,将跳转到xor eax,eax

jmp main+71h 跳转到add eax,4上方的mov eax,dword ptr [ebp-30h]

画图则为:

分析提示

汇编指令不能一条条看,需要有整体思想,按"指令块"的视角来看

2.分析

1.栈区初始化

 push        ebp  
 mov         ebp,esp  
 sub         esp,78h  
 push        ebx  
 push        esi  
 push        edi  
 mov         ecx,offset _2A500742_leetcode@cpp 
 call        @__CheckForDebuggerJustMyCode@4 
 nop 

为常规操作,具体分析见36.【C语言】函数栈帧的创建和销毁文章,不再赘述

2.设置数组元素的值

 mov         dword ptr [arr],1  
 mov         dword ptr [ebp-24h],2  
 mov         dword ptr [ebp-20h],3  
 mov         dword ptr [ebp-1Ch],4  
 mov         dword ptr [ebp-18h],5  
 mov         dword ptr [ebp-14h],6  
 mov         dword ptr [ebp-10h],7  
 mov         dword ptr [ebp-0Ch],8  
 mov         dword ptr [ebp-8],9  
 mov         dword ptr [ebp-4],0Ah 

从0x01到0x0A,依次被写入内存

注意这里的ebp寄存器,其值存储数组最后一个元素下一个位置的地址,后面会有重要作用,有几个重要的参数都依赖于ebp寄存器

3. 逐条分析范围for

1.arr的地址被放到[ebp-2Ch]处

 lea         eax,[arr]  
 mov         dword ptr [ebp-2Ch],eax  

2.[ebp-2Ch]指向的值被复制一份到[ebp-30h]处

 mov         eax,dword ptr [ebp-2Ch]  
 mov         dword ptr [ebp-30h],eax 

3.eax暂存[ebp-2Ch]指向的值,加28h后存储到[ebp-34h]处

 mov         eax,dword ptr [ebp-2Ch]  
 add         eax,28h  
 mov         dword ptr [ebp-34h],eax  

eax原本存储arr数组的地址ebp-28h,现+28h

4.跳转指令

jmp         main+7Ah 

5.比较[ebp-30h]和[ebp-34h]指向的值,如果相等则跳转到return 0;的反汇编指令

 mov         eax,dword ptr [ebp-30h]  
 cmp         eax,dword ptr [ebp-34h]  
 je          main+8Ch 

显然不满足,按顺序执行

备注: je main+8Ch是唯一能退出条件循环的出口

6.将数组元素的值载入ecx寄存器,再将其赋值给变量a

 mov         eax,dword ptr [ebp-30h]  
 mov         ecx,dword ptr [eax]  
 mov         dword ptr [ebp-38h],ecx  

备注:变量a存储在[ebp-38h]处

不规范的写出前面两行汇编指令的等价指令mov ecx,dword ptr [[ebp-30h]] 

写成C代码的形式

eax = *(ebp-30h);
ecx = *eax;

两次解引用,相当于

ecx = **(ebp-30h);

7. 跳转指令

 jmp         main+71h  

 8.更新[ebp-30h]指向的值,每次执行都+4(原因:int类型的数组)

 mov         eax,dword ptr [ebp-30h]  
 add         eax,4  
 mov         dword ptr [ebp-30h],eax  

 ......多次条件循环直到[ebp-30h]和[ebp-34h]的值相等(数组元素全部遍历完了)才结束,跳转至return 0;

4.函数返回,空间释放

 pop         edi  
 pop         esi  
 pop         ebx  
 mov         esp,ebp  
 pop         ebp  
 ret

5.总结

几个重要参数

ebp寄存器:存储数组最后一个元素下一个位置的地址

[ebp-2Ch]指向的内存空间:存储arr数组首元素的地址

[ebp-30h]指向的内存空间:第一次存储arr数组首元素的地址,其后每次更新都+4

[ebp-34h]指向的内存空间:存储数组最后一个元素下一个位置的地址

[ebp-38h]指向的内存空间:存储变量a的值

★[ebp-30h]是决定能否退出条件循环的关键参数!

编译器为什么要这样设计汇编指令

遍历数组前需要准备开始位置(即初始索引)和结束位置(最后一个元素下一个位置的地址)

这两个数据需要内存空间去存储,因此用[ebp-2Ch]和[ebp-34h]暂时存储

还需要维护一个指针去逐个访问数组中的每个元素:因此用[ebp-30h]暂时存储

for (int a : arr)需要为a开辟内存空间,因此用[ebp-38h]暂时存储

3.范围for的核心思想

从头到尾遍历数组

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/2250681.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

hue 4.11容器化部署,已结合Hive与Hadoop

配合《Hue 部署过程中的报错处理》食用更佳 官方配置说明页面&#xff1a; https://docs.gethue.com/administrator/configuration/connectors/ 官方配置hue.ini页面 https://github.com/cloudera/hue/blob/master/desktop/conf.dist/hue.ini docker部署 注意&#xff1a; …

51单片机快速入门之中断的应用 2024/11/23 串口中断

51单片机快速入门之中断的应用 基本函数: void T0(void) interrupt 1 using 1 { 这里放入中断后需要做的操作 } void T0(void)&#xff1a; 这是一个函数声明&#xff0c;表明函数 T0 不接受任何参数&#xff0c;并且不返回任何值。 interrupt 1&#xff1a; 这是关键字和参…

ffmpeg安装(windows)

ffmpeg安装-windows 前言ffmpeg安装路径安装说明 前言 ffmpeg的安装也是开箱即用的,并没有小码哥说的那么难 ffmpeg安装路径 这就下载好了! 安装说明 将上面的bin目录加入到环境变量,然后在cmd中测试一下: C:\Users\12114\Desktop\test\TaskmgrPlayer\x64\Debug>ffmpe…

HCIA笔记6--路由基础

0. 概念 自治系统&#xff1a;一个统一管理的大型网络&#xff0c;由路由器组成的集合。 路由器隔离广播域&#xff0c;交换机隔离冲突域。 1.路由器工作原理 路由器根据路由表进行转发数据包&#xff1b; 路由表中没有路由&#xff0c;直接丢弃该数据包路由表中只有一条路…

IDEA如何快速地重写方法,如equals、toString等

前言 大家好&#xff0c;我是小徐啊。我们在使用IDEA的时候&#xff0c;有时候是需要重写equals和toString等方法的。这在IDEA中已经很方便的给我们准备好了快速的操作了。今天就来讲解一下。 如何重写 首先&#xff0c;打开要重写方法的文件&#xff0c;让鼠标定位到这个文…

跨境物流市场风云变幻,集运企业需精准决策以应对挑战

跨境物流市场&#xff0c;作为全球经济的重要纽带&#xff0c;正经历着前所未有的风云变幻。据最新数据显示&#xff0c;全球海运贸易在2023年实现了2.4%的增长&#xff0c;并预计在今年年底前将再增长2%。这一增长态势虽然积极&#xff0c;但背后却隐藏着诸多挑战与不确定性。…

2024年首届数证杯 初赛wp

“数证杯”电子数据取证分析大赛致力于成为全国第一大电子数据取证分析大赛&#xff0c;面向所有网络安全从业人员公开征集参赛选手。参赛选手根据所属行业报名参赛赛道&#xff0c;比赛设置冠军、亚军、季军奖。所涉及行业包括能源、金融、通信、取证、安全等企业以及各类司法…

电机瞬态分析基础(3):空间矢量

1. 空间矢量 空间矢量的概念在交流电机分析与控制中具有非常重要的作用。将各相的电压、电流、磁链等电磁量用空间矢量表达&#xff0c;可以使三相感应电机的动态方程表达更简洁&#xff0c;为电机的分析与控制带来方便&#xff0c;并有助于对交流电机的矢量控制、直接转矩控制…

C/C++绘制爱心

系列文章 序号直达链接1C/C爱心代码2C/C跳动的爱心3C/C李峋同款跳动的爱心代码4C/C满屏飘字表白代码5C/C大雪纷飞代码6C/C烟花代码7C/C黑客帝国同款字母雨8C/C樱花树代码9C/C奥特曼代码10C/C精美圣诞树11C/C俄罗斯方块12C/C贪吃蛇13C/C孤单又灿烂的神-鬼怪14C/C闪烁的爱心15C/…

LLM应用-prompt提示:RAG query重写、相似query生成 加强检索准确率

参考&#xff1a; https://zhuanlan.zhihu.com/p/719510286 1、query重写 你是一名AI助手&#xff0c;负责在RAG&#xff08;知识库&#xff09;系统中通过重构用户查询来提高检索效果。根据原始查询&#xff0c;将其重写得更具体、详细&#xff0c;以便更有可能检索到相关信…

MTK主板_小型联发科安卓主板_行业智能终端主板基于联发科方案

MTK安卓主板是一款小巧而高效的科技产品&#xff0c;其尺寸仅为43.4mm x 57.6mm。采用了先进的联发科12nm制程工艺&#xff0c;这款主板搭载四核或八核64位A53架构的CPU&#xff0c;主频高达2.0GHz&#xff0c;不但保证了出色的计算能力&#xff0c;还实现了超低功耗的特点。系…

递归---汉诺塔

问题描述 有三根相邻的柱子&#xff0c;标号为A,B,C&#xff0c;A柱子上从下到上按金字塔状叠放着n个不同大小的圆盘&#xff0c;要把所有盘子一个一个移动到柱子B上&#xff0c;并且每次移动&#xff0c;同一根柱子上都不能出现大盘子在小盘子上方&#xff0c;输出每次的移动。…

HTML飞舞的爱心(完整代码)

写在前面 HTML语言实现飞舞的爱心完整代码。 完整代码 <!DOCTYPE html> <html lang="en"><head><meta charset="UTF-8"><title>飞舞爱心</title><style>* {margin: 0;padding: 0;}html,body {overflow: hidd…

修改训练策略,无损提升性能

&#x1f3e1;作者主页&#xff1a;点击&#xff01; &#x1f916;编程探索专栏&#xff1a;点击&#xff01; ⏰️创作时间&#xff1a;2024年11月29日15点40分 神秘男子影, 秘而不宣藏。 泣意深不见, 男子自持重, 子夜独自沉。 论文链接 点击开启你的论文编程之旅…

@bytemd/vue掘金markdown插件预览内容有误

vue项目使用bytemd/vue 来预览字符串格式的markdown内容&#xff0c;总会多出如图的一段代码&#xff0c; 请问有没有大佬知道为什么&#xff1f; 很急&#xff0c;求教&#xff01;&#xff01;&#xff01;&#xff01;&#xff01;

Web 毕设篇-适合小白、初级入门练手的 Spring Boot Web 毕业设计项目:电影院后台管理系统(前后端源码 + 数据库 sql 脚本)

&#x1f525;博客主页&#xff1a; 【小扳_-CSDN博客】 ❤感谢大家点赞&#x1f44d;收藏⭐评论✍ 文章目录 1.0 项目介绍 2.0 用户登录功能 3.0 用户管理功能 4.0 影院管理功能 5.0 电影管理功能 6.0 影厅管理功能 7.0 电影排片管理功能 8.0 用户评论管理功能 9.0 用户购票功…

window.structuredClone 深拷贝

概述&#xff1a; structuredClone 是一种新的 JavaScript 原生方法&#xff0c;用于创建一个对象的深拷贝。与传统的浅拷贝方法&#xff08;如 Object.assign 或数组的 slice&#xff09;不同&#xff0c;structuredClone 可以递归地拷贝对象&#xff0c;包括其中的嵌套对象、…

java全栈day10--后端Web基础(基础知识)

引言&#xff1a;只要能通过浏览器访问的网站全是B/S架构&#xff0c;其中最常用的服务器就是Tomcat 在浏览器与服务器交互的时候采用的协议是HTTP协议 一、Tomcat服务器 1.1介绍 官网地址&#xff1a;Apache Tomcat - Welcome! 1.2基本使用(网上有安装教程&#xff0c;建议…

java:拆箱和装箱,缓存池概念简单介绍

1.基本数据类型及其包装类&#xff1a; 举例子&#xff1a; Integer i 10; //装箱int n i; //拆箱 概念&#xff1a; 装箱就是自动将基本数据类型转换为包装器类型&#xff1b; 拆箱就是自动将包装器类型转换为基本数据类型&#xff1b; public class Main {public s…

保持角色一致性!flux新模型redux用法(含模型与工作流)

​ 目录 redux模型是什么&#xff0c;能干啥&#xff1f; 用到的工具有哪些&#xff1f; 工具和模型文件在哪里下载&#xff1f; 整合包&#xff1a; 下载后需要分别放到指定目录&#xff1a; redux模型怎么用&#xff1f; 加载工作流 上传图片和输入提示词 生成结果…