Windows逆向安全(一)之基础知识(九)

news2025/1/21 12:07:57

汇编比较三种循环

众所周知,在C语言可以使用可以使用三种循环,分别是:while、do…while和for

本文从汇编的角度出发,观察这三种循环的差异

范例代码

先贴出三种循环的代码,分别用这三种循环计算

0+1+2+3+4+5+6+7+8+9(从0一直加到9)

#include "stdafx.h"
int loop1(){
        int i=0,j=0;
        for(i=0;i<10;i++){
                j=j+i;
        }
        return j;
}

int loop2(){
        int i=0,j=0;
        while(i<10){
                j=j+i;
                i=i+1;
        }
        return j;
}
int loop3(){
        int i=0,j=0;
        do {
                j=j+i;
                i=i+1;
        } while(i<10);
        return j;
}

int main(int argc, char* argv[])
{
        int result=0;
        result=loop1();
        printf("%d\n",result);
        result=loop2();
        printf("%d\n",result);
        result=loop3();
        printf("%d\n",result);
        return 0;
}

运行结果

在这里插入图片描述

显然,这三种循环都能正确地计算出结果,接下来挨个分析这三种循环的汇编代码

for循环

省去汇编代码中保护现场、提升堆栈、初始化堆栈、恢复现场和返回的代码,直接看代码的对应汇编

9:        int i=0,j=0;
0040D748   mov         dword ptr [ebp-4],0
0040D74F   mov         dword ptr [ebp-8],0
10:       for(i=0;i<10;i++){
0040D756   mov         dword ptr [ebp-4],0
0040D75D   jmp         loop1+38h (0040d768)
0040D75F   mov         eax,dword ptr [ebp-4]
0040D762   add         eax,1
0040D765   mov         dword ptr [ebp-4],eax
0040D768   cmp         dword ptr [ebp-4],0Ah
0040D76C   jge         loop1+49h (0040d779)
11:           j=j+i;
0040D76E   mov         ecx,dword ptr [ebp-8]
0040D771   add         ecx,dword ptr [ebp-4]
0040D774   mov         dword ptr [ebp-8],ecx
12:       }
0040D777   jmp         loop1+2Fh (0040d75f)
13:       return j;
0040D779   mov         eax,dword ptr [ebp-8]
14:   }

头两行汇编对应将i和j初始化为0,没什么好说的

9:        int i=0,j=0;
0040D748   mov         dword ptr [ebp-4],0
0040D74F   mov         dword ptr [ebp-8],0

在这里插入图片描述
接下来看循环语句部分:

第一行为:

0040D756   mov         dword ptr [ebp-4],0

对应for(i=0;i<10;i++)中的i=0

接下来是一个绝对跳转指令:

0040D75D   jmp         loop1+38h (0040d768)

跳转的地址为:0040d768

0040D768   cmp         dword ptr [ebp-4],0Ah
0040D76C   jge         loop1+49h (0040d779)

这里就是比较 i 和0Ah(十六进制的10),也就是对应for(i=0;i<10;i++)中的i<10

jge指令:jump greater equal,当大于等于时跳转(有符号)

所以这里就是判断i是否大于10,如果大于10就跳转到0040d779

接下来看0040d779对应的代码:

13:       return j;
0040D779   mov         eax,dword ptr [ebp-8]

这里就是返回的语句了,已经在循环的外部了,即上面的跳转其实就是退出循环的语句

如果前面的i<10,则继续向下看汇编语句:

11:           j=j+i;
0040D76E   mov         ecx,dword ptr [ebp-8]
0040D771   add         ecx,dword ptr [ebp-4]
0040D774   mov         dword ptr [ebp-8],ecx

先将j赋值给ecx,然后用ecx加上i,最后将ecx赋值给j,即j=j+i,也就是我们循环里要执行的内容

执行完上面的j=j+1后,下一行指令是一个绝对跳转:

12:       }
0040D777   jmp         loop1+2Fh (0040d75f)

跳转的地址为0040d75f,继续观察:

0040D75F   mov         eax,dword ptr [ebp-4]
0040D762   add         eax,1
0040D765   mov         dword ptr [ebp-4],eax
0040D768   cmp         dword ptr [ebp-4],0Ah

先将i的值赋给eax,然后eax加一后把eax赋给i,对应for(i=0;i<10;i++)中的i++

然后就回到了之前的步骤,比较i是否大于等于10,是则退出循环,否则继续循环执行

for循环总结

通过前面的分析大致可以知道for循环的执行流程为:

在这里插入图片描述

while循环

省去汇编代码中保护现场、提升堆栈、初始化堆栈、恢复现场和返回的代码,直接看代码的对应汇编

17:       int i=0,j=0;
0040D7A8   mov         dword ptr [ebp-4],0
0040D7AF   mov         dword ptr [ebp-8],0
18:       while(i<10){
0040D7B6   cmp         dword ptr [ebp-4],0Ah
0040D7BA   jge         loop2+40h (0040d7d0)
19:           j=j+i;
0040D7BC   mov         eax,dword ptr [ebp-8]
0040D7BF   add         eax,dword ptr [ebp-4]
0040D7C2   mov         dword ptr [ebp-8],eax
20:           i=i+1;
0040D7C5   mov         ecx,dword ptr [ebp-4]
0040D7C8   add         ecx,1
0040D7CB   mov         dword ptr [ebp-4],ecx
21:       }
0040D7CE   jmp         loop2+26h (0040d7b6)
22:       return j;
0040D7D0   mov         eax,dword ptr [ebp-8]
23:   }

头两行初始化i和j,和前面一样,不属于循环的内容,这里给出i和j对应的地址

在这里插入图片描述

下面正式来看循环的内容:

18:       while(i<10){
0040D7B6   cmp         dword ptr [ebp-4],0Ah
0040D7BA   jge         loop2+40h (0040d7d0)

比较 i 和 10

jge:jump greater equal,大于等于就跳转(有符号)

综上两句就是用来判断 i<10 对应while(i<10)中的 判断条件 i<10

如果i>=10,则跳转到0040d7d0,退出循环

22:       return j;
0040D7D0   mov         eax,dword ptr [ebp-8]

这里就是返回的语句了,已经在循环的外部了

如果i<10,也就是没有跳转,接着看下面的语句:

19:           j=j+i;
0040D7BC   mov         eax,dword ptr [ebp-8]
0040D7BF   add         eax,dword ptr [ebp-4]
0040D7C2   mov         dword ptr [ebp-8],eax
20:           i=i+1;
0040D7C5   mov         ecx,dword ptr [ebp-4]
0040D7C8   add         ecx,1
0040D7CB   mov         dword ptr [ebp-4],ecx
21:       }

就是执行我们while里面所写的代码(执行循环内的代码)

接着看下面的语句,是一个无条件跳转,跳转到前面的0040d7b6

0040D7CE   jmp         loop2+26h (0040d7b6)

来看看0040d7b6,就是最开始的判断语句,如果i<10则继续执行,否则跳出循环

0040D7B6   cmp         dword ptr [ebp-4],0Ah
0040D7BA   jge         loop2+40h (0040d7d0)

while循环总结

通过前面的分析大致可以知道while循环的执行流程为

在这里插入图片描述

do while循环

省去汇编代码中保护现场、提升堆栈、初始化堆栈、恢复现场和返回的代码,直接看代码的对应汇编

25:       int i=0,j=0;
0040D888   mov         dword ptr [ebp-4],0
0040D88F   mov         dword ptr [ebp-8],0
26:       do {
27:           j=j+i;
0040D896   mov         eax,dword ptr [ebp-8]
0040D899   add         eax,dword ptr [ebp-4]
0040D89C   mov         dword ptr [ebp-8],eax
28:           i=i+1;
0040D89F   mov         ecx,dword ptr [ebp-4]
0040D8A2   add         ecx,1
0040D8A5   mov         dword ptr [ebp-4],ecx
29:       } while(i<10);
0040D8A8   cmp         dword ptr [ebp-4],0Ah
0040D8AC   jl          loop3+26h (0040d896)
30:       return j;
0040D8AE   mov         eax,dword ptr [ebp-8]
31:   }

头两行初始化i和j,和前面一样,不属于循环的内容,这里给出i和j对应的地址

在这里插入图片描述
下面正式来看循环的内容:

26:       do {
27:           j=j+i;
0040D896   mov         eax,dword ptr [ebp-8]
0040D899   add         eax,dword ptr [ebp-4]
0040D89C   mov         dword ptr [ebp-8],eax
28:           i=i+1;
0040D89F   mov         ecx,dword ptr [ebp-4]
0040D8A2   add         ecx,1
0040D8A5   mov         dword ptr [ebp-4],ecx

直接执行我们do while里面所写的代码(执行循环内的代码)

接着看下面的代码:

29:       } while(i<10);
0040D8A8   cmp         dword ptr [ebp-4],0Ah
0040D8AC   jl          loop3+26h (0040d896)

先是比较 i 和 10

然后 jl :jump less (有符号数),当i<10的时候才跳转

跳转地址为0040d896,也就是前面的代码

26:       do {
27:           j=j+i;
0040D896   mov         eax,dword ptr [ebp-8]

如果没有跳转则执行下面的代码

30:       return j;
0040D8AE   mov         eax,dword ptr [ebp-8]

注意到这里已经是退出循环的状态了,返回j

do while循环总结

过前面的分析大致可以知道do while循环的执行流程为:

在这里插入图片描述

比较

在这里插入图片描述在这里插入图片描述

在这里插入图片描述

从流程图就不难看出,三种循环的复杂程度:

for循环>while循环>do while循环

因此执行效率则是:

do while循环>while循环>for循环

  • for循环是先判断条件是否不满足i<10,也就是是否满足i>=10,不满足条件则跳出循环并返回;满足条件则执行循环内的代码,执行完循环内代码后无条件跳转到计数增加i=i+1再回到判断条件
  • while循环也是先判断条件是否不满足i<10,也就是是否满足i>=10,不满足条件则跳出循环并返回;满足条件则执行循环内的代码,执行完循环内代码后无条件跳转到判断条件处
  • do while循环则是先执行循环内的语句,然后再判断条件,判断条件是否满足i<10,满足条件则跳回去继续执行循环内的代码

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

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

相关文章

【PyTorch】第三节:反向传播算法

作者&#x1f575;️‍♂️&#xff1a;让机器理解语言か 专栏&#x1f387;&#xff1a;PyTorch 描述&#x1f3a8;&#xff1a;PyTorch 是一个基于 Torch 的 Python 开源机器学习库。 寄语&#x1f493;&#xff1a;&#x1f43e;没有白走的路&#xff0c;每一步都算数&#…

SpringBoot高校毕业生就业信息管理系统 附带详细运行指导视频

文章目录 一、项目演示二、项目介绍三、运行截图四、主要代码 一、项目演示 项目演示地址&#xff1a; 视频地址 二、项目介绍 项目描述&#xff1a;这是一个基于SpringBoot框架开发的高校毕业生就业信息管理系统项目。首先&#xff0c;这是一个响应式的项目&#xff0c;代码…

五:用户空间内存分配

目录 用户空间内存分配 mmap malloc 用户空间内存分配 mmap 将内核空间直接映射到用户空间&#xff0c;省去从内核到用户空间的内存拷贝。 mmap的缺点 mmap 使用时必须实现指定好内存映射的大小&#xff0c;因此 mmap 并不适合变长文件&#xff1b;mmap如果更新文件的操作…

【通过Cpython3.9源码看看python字符串的缓存机制】

基本说明 在CPython中&#xff0c;字符串intern机制是一种字符串对象缓存机制&#xff0c;用于避免创建多个相同内容的字符串对象&#xff0c;以减少内存使用。具体来说&#xff0c;如果两个字符串对象的内容相同&#xff0c;那么这两个字符串对象实际上会共享同一块内存空间。…

【Vue基础】前端工程化Vue项目

一、创建Vue项目步骤 1、新建一个文件夹&#xff0c;起名为vue_project01 2、在该文件夹中打开cmd&#xff0c;输入指令vue ui&#xff0c;打开图形化界面 3、此时跳转到网页&#xff0c;根据以下步骤配置vue项目 1&#xff09;项目名命名为test01&#xff1b;选择包管理器为…

使用R语言进行方差分析(ANOVA、ANCOVA)(一)

方差分析&#xff08;一&#xff09; 1. ANOVA模型拟合1.1 aov()函数1.2 表达式中各项的顺序 2. 单因素方差分析&#xff08;One-Way ANOVA&#xff09;2.1 绘制各组均值及其置信区间的图形2.2 多重比较-TukeyHSD2.2.1 成对比较图2.2.2 多重均值比较-TukeyHSD&#xff08;更易理…

图的存储(邻接矩阵邻接表)

图的存储 文章目录 图的存储1 邻接矩阵1.1 邻接矩阵存储结构定义1.2 完整代码应用 2 邻接表2.1 邻接表存储结构定义2.2 完整代码应用 1 邻接矩阵 A [ i ] [ j ] 1 A[i][j]1 A[i][j]1 表示顶点i与顶点j邻接&#xff0c;即i与j之间存在边或者弧。 A [ i ] [ j ] 0 A[i][j]0 A…

使用jdk17 搭建Hadoop3.3.5和Spark3.3.2 on Yarn集群模式

搭建Hadoop3.3.5和Spark3.3.2 on Yarn集群模式&#xff0c;使用jdk17 搭建Hadoop3.3.5和Spark3.3.2 on Yarn集群模式1. 创建一台虚拟机2. 安装jdk17&#xff08;1&#xff09;下载jdk17&#xff08;2&#xff09;安装jdk17&#xff08;3&#xff09;配置环境变量 3. 虚拟机之间…

【音视频第15天】webRTC协议(2)

目录 协议ICESTUNNATTURNSDPSDP结构 Signaling and ConnectingSignaling: How peers find each other in WebRTCConnecting and NAT Traversal with STUN/TURN Signalingsdp协议WebRTC如何使用sdpWebRTC会话示例 Connecting为什么WebRTC需要一个专用的子系统来连接?现实世界的…

Day949.遗留系统之殇:为什么要对遗留系统进行现代化? -遗留系统现代化实战

遗留系统之殇&#xff1a;为什么要对遗留系统进行现代化&#xff1f; Hi&#xff0c;我是阿昌&#xff0c;今天学习记录是关于遗留系统之殇&#xff1a;为什么要对遗留系统进行现代化&#xff1f;的内容。 不知道你是否跟曾经一样&#xff0c;身处一个遗留系统的漩涡之中&…

数据结构-基数排序

基数排序是和其他的各类排序方式都不同的方式&#xff0c;之前的各类排序&#xff0c;如快速排序&#xff0c;堆排序&#xff0c;冒泡排序等等&#xff0c;都是通过关键字之间的比较和移动记录这两种操作来实现的&#xff0c;而基数排序不需要记录关键字之间的比较。所谓基数排…

ubuntu 安装vmware tool

1在虚拟机种站到安装vmware-tools 然后重启虚拟机 2在磁盘中可以看到如下文件&#xff0c;将zip文件移动到桌面解压备用 3关闭虚拟机 找到编辑虚拟机设置 4点击左侧 CD/dvd(SATA) 如果是使用镜像文件&#xff0c;改成使用物理驱动器. 5 打开命令行 cd 桌面 &#xff08;如…

CSS基础——盒子模型的一些属性概念

目录 display visibility overflow 文档流 元素在文档流中的特点 块元素 内联元素 浮动 float 浮动元素特点 清除浮动 clear 小练习 效果图 具体实现 高度塌陷问题 BFC 特点 如何开启BFC 解决方案 本篇的最终练习 效果图如下&#xff1a; 具体实现 disp…

ChatGPT原理解释

写了一本介绍ChatGPT原理的课程 结构如下 01、介绍ChatGPT及其原理 1.1 ChatGPT的概述 1.2 什么是自然语言处理&#xff08;NLP&#xff09; 1.3 深度学习与NLP的关系 1.4 GPT模型的介绍 02、GPT原理探讨 2.1 GPT模型的输入与输出 2.2 GPT模型的结构 2.3 GPT模型的预训练方法…

flv怎么无损转换成mp4格式,3大超级方法分享

flv格式是目前在视频分享媒体播放网站上广泛使用的一种视频文件格式&#xff0c;可以在网站窗口中直接播放&#xff0c;这类视频文件还能够有效保护版权。但是有些时候我们可能需要将flv格式的视频转换为其他格式&#xff0c;比如mp4。但是该怎么操作呢&#xff1f; 其实有很多…

数据挖掘:汽车车交易价格预测(测评指标;EDA)

目录 一、前期工作 1.赛题介绍 赛题分析&#xff1a; 分类和回归问题的评价指标有如下一些形式&#xff1a; &#xff08;下文2.1和2.2会用到&#xff09; 2.数据简介 3.探索性分析-EDA介绍 二、实战演练 2.1分类指标评价计算示例 2.2回归指标评价计算示例 2.3数据探索…

抠图,扣掉背景图片

Remove Image Backgrounds, Free HD, No Signup - Pixian.AI https://pixian.ai/ 从电脑本地选取图片&#xff0c;然后会自动扣掉背景&#xff0c;点击DOWNLOAD就可以了 第一个&#xff1a;Pixian.AI 这是一款国外的在线抠图网站&#xff0c;把需要扣除背景的图片拖拽进来&am…

简单的了解下 Fetch API 的工作原理

简介 Fetch API是一种现代的Web API&#xff0c;提供了一种异步获取网络资源的方法。由于其简单性、灵活性和一致性&#xff0c;它已经成为Web应用程序中获取数据和资源的流行选择。在本文中&#xff0c;我们将深入探讨Fetch API的核心特性&#xff0c;并了解其工作原理。 Fetc…

Windows逆向安全(一)之基础知识(七)

汇编C语言类型转换 类型转换 类型转换的使用场景 类型转换一般为由数据宽度小的转换成数据宽度大的&#xff0c;不然可能会有高位数据被截断的现象&#xff0c;引起数据丢失 需要一个变量来存储一个数据&#xff0c;刚开始这个数据的数据宽度较小&#xff0c;后来发现存不下…

什么是UML?

文章目录 00 | 基础知识01 | 静态建模类图对象图用例图 02 | 动态建模时序图通信图状态图活动图 03 | 物理建模构件图部署图 UML&#xff08;Unified Model Language&#xff09;&#xff0c;统一建模语言&#xff0c;是一种可以用来表现设计模式的直观的&#xff0c;有效的框图…