[3] 以逆向的角度来看循环语句——do、while、for的比较

1. do循环

​ 先执行循环体,后比较判断

#include <stdio.h>
int main(int argc, char* argv[]) {
int sum = 0;
int i = 0;
do {
sum += i;
i++;
}
while(i <= argc);
return sum;
}

汇编标识:

;x86_vs
00401000 push ebp
00401001 mov ebp, esp
00401003 sub esp, 8
00401006 mov dword ptr [ebp-8], 0 ;sum=0
0040100D mov dword ptr [ebp-4], 0 ;i=0
{
00401014 mov eax, [ebp-8] ;do_while语句块代码
00401017 add eax, [ebp-4]
0040101A mov [ebp-8], eax ;sum+=i
0040101D mov ecx, [ebp-4]
00401020 add ecx, 1
00401023 mov [ebp-4], ecx ;i+=1
}00401026 mov edx, [ebp-4]
00401029 cmp edx, [ebp+8]
0040102C jle short loc_401014 ;如果i<=argc,跳转到do_while语句块代码
0040102E mov eax, [ebp-8] ;do_while结束代码块
00401031 mov esp, ebp
00401033 pop ebp
00401034 retn ;x86_gcc
00401510 push ebp
00401511 mov ebp, esp
00401513 and esp, 0FFFFFFF0h
00401516 sub esp, 10h
00401519 call ___main
0040151E mov dword ptr [esp+0Ch], 0 ;sum=0
00401526 mov dword ptr [esp+8], 0 ;i=0
{
0040152E mov eax, [esp+8] ;do_while语句块代码
00401532 add [esp+0Ch], eax ;sum+=i
00401536 add dword ptr [esp+8], 1 ;i+=1
0040153B mov eax, [esp+8]
0040153F cmp eax, [ebp+8]
00401542 jg short loc_401546 ;如果i>argc,跳转到do_while结束代码块
}
00401544 jmp short loc_40152E ;跳转到do_while语句块代码
00401546 mov eax, [esp+0Ch] ;do_while结束代码块

逆向总结:

​ x86_vs:while语句的比较数是相同的

{
DO_WHILE语句代码块
...
}
执行影响标志位指令
JXX跳转到DO_WHILE语句代码块

​ x86_gcc:while语句的比较数是相反的

{
DO_WHILE语句代码块
执行影响标志位指令
JXX跳转到DO_WHILE结束代码块
...
}
跳转到DO_WHILE语句代码块
DO_WHILE结束代码块

2. while循环:先比较判断,后执行循环体

#include <stdio.h>
int main(int argc, char* argv[]) {
int sum = 0;
int i = 0;
while(i <= argc) {
sum += i;
i++;
}
return sum;
}

汇编标识:

00401000  push    ebp
00401001 mov ebp, esp
00401003 sub esp, 8
00401006 mov dword ptr [ebp-8], 0 ;sum=0
0040100D mov dword ptr [ebp-4], 0 ;i=0
{
00401014 mov eax, [ebp-4] ;while语句代码块
00401017 cmp eax, [ebp+8]
0040101A jg short loc_401030 ;如果i>argc,则跳转到while结束代码块
0040101C mov ecx, [ebp-8]
0040101F add ecx, [ebp-4]
00401022 mov [ebp-8], ecx ;sum+=i
00401025 mov edx, [ebp-4]
00401028 add edx, 1
0040102B mov [ebp-4], edx ;i+=1
}
0040102E jmp short loc_401014 ;跳转到while语句代码块
00401030 mov eax, [ebp-8] ;while结束代码块

注意:

​ while循环结构中使用了两次跳转指令完成循环,因为多使用了一次跳转指令,所以while循环比do循环效率低一些

​ while循环结构很可能被优化成do循环结构,被转换后的while结构需要检查是否可以被成功执行一次,通常会被嵌套在if单分支结构中

逆向总结:

{
while语句代码块
执行影响标志位指令
JXX跳转到while结束代码块
...
}
JMP跳转到while语句代码块
while结束代码块

3. for循环:先初始化,再比较判断,最后执行循环体

#include <stdio.h>
int main(int argc, char* argv[]) {
int sum = 0;
for (int i = 0; i <= argc ; i++) {
sum += i;
}
return sum;
}

汇编标识:

00401006  mov     dword ptr [ebp-8], 0         ;sum=0
{
0040100D mov dword ptr [ebp-4], 0 ;赋初值语句代码块,i=0
}
00401014 jmp short loc_40101F ;跳转到for语句代码块
{
00401016 mov eax, [ebp-4] ;步长语句代码块
00401019 add eax, 1
0040101C mov [ebp-4], eax ;i+=1
}
{
0040101F mov ecx, [ebp-4] ;for语句代码块
00401022 cmp ecx, [ebp+8]
00401025 jg short loc_401032 ;如果i>argc,则跳转到for结束语句块
00401027 mov edx, [ebp-8]
0040102A add edx, [ebp-4]
0040102D mov [ebp-8], edx ;sum+=i}
00401030 jmp short loc_401016 ;跳转到步长语句代码块
00401032 mov eax, [ebp-8] ;for结束语句块

逆向总结:

赋初值语句代码块
JMP跳转到for语句代码块
{
步长语句代码块
...
}
{
for语句代码块
执行影响标志位的指令
JXX跳转到for结束语句块
...
}
JMP跳转到步长语句代码块
for结束语句块

​ 计数器变量被赋初值后,利用jmp跳过第一次步长计算。然后,通过3个跳转指令还原for循环的各个组成部分:

​ 1)第一个jmp指令之前的代码为初始化部分;

​ 2)从第一个jmp指令到循环条件比较处之间的代码为步长计算部分;

​ 3)在条件跳转指令jxx之后寻找向上跳转的jmp指令,且其目标是到步长计算的位置,在jxx和这个jmp指令之间的代码即为循环语句块

4. 三种循环结构的效率比较

Release优化

​ 1)do循环效率最高

​ 2)while循环执行两次JMP跳转,效率低于do循环,可将其优化为if嵌套的do循环提高效率

int LoopWhile(int count){
int sum = 0;
int i = 0; if(count >= 0){
do {
sum += i;
i++;
}
while(i <= count)
}
return sum;
}

​ 3)for循环执行三次JMP跳转,效率最低,可将其优化为if嵌套的do循环提高效率

[3] 以逆向的角度来看循环语句——do、while、for的比较的更多相关文章

  1. Python学习【第五篇】循环语句

    Python循环语句 接下来将介绍Python的循环语句,程序在一般情况下是按顺序执行的. 编程语言提供了各种控制结构,允许更复杂的执行路径. 循环语句允许我们执行一个语句或语句组多次. Python ...

  2. 高性能JavaScript 循环语句和流程控制

    前言 上一篇探讨了达夫设备对于代码性能的影响,本文主要探讨并且测试各种常见的循环语句的性能以及流程控制中常见的优化. 循环语句 众所周知,常用的循环语句有for.while.do-while以及for ...

  3. 【C语言探索之旅】 第一部分第七课:循环语句

    内容简介 1.课程大纲 2.第一部分第七课: 循环语句 3.第一部分第八课预告: 第一个C语言小游戏 课程大纲 我们的课程分为四大部分,每一个部分结束后都会有练习题,并会公布答案.还会带大家用C语言编 ...

  4. 子数涵数·C语言——循环语句

      之前,我们讲过了编程中的三种结构(顺序.条件.循环),现在我们来看一下循环语句如何编写. 一.while循环语句(先判断后执行) 1 #include<stdio.h> 2 int m ...

  5. python3 第七章 - 循环语句

    为了让计算机能计算成千上万次的重复运算,我们就需要循环语句. Python中的循环语句有 while for 循环语句的执行过程,如下图: while 循环 Python中while语句的一般形式: ...

  6. Python 学习笔记8 循环语句 while

    While循环是哟中利用条件语句,不断的执行某一段代码块,达到批量操作输出等一系列的操作,直到条件不满足或者被强制退出为止. 其工作流程如下: (图片来源菜鸟教程:http://www.runoob. ...

  7. 第二节 Python基础之变量,运算符,if语句,while和for循环语句

    我们在上一节中,我们发现当我们用字符串进行一些功能处理的时候,我们都是把整个字符串写下来的,比如"jasonhy".startwith("j"),如果我们在程序 ...

  8. #7 Python顺序、条件、循环语句

    前言 上一节讲解了Python的数据类型和运算,本节将继续深入,涉及Python的语句结构,相当于Python的语法,是以后编写程序的重要基础! 一.顺序语句 顺序语句很好理解,就是按程序的顺序逻辑编 ...

  9. Kotlin入门(7)循环语句的操作

    上一篇文章介绍了简单分支与多路分支的实现,控制语句除了这两种条件分支之外,还有对循环处理的控制,那么本文接下来继续阐述Kotlin如何对循环语句进行操作. Koltin处理循环语句依旧采纳了for和w ...

  10. python2.7入门---循环语句(for&嵌套循环)

        咱们直接先来看for循环.Python for循环可以遍历任何序列的项目,如一个列表或者一个字符串.然后再来看一下它的语法结构: for iterating_var in sequence: ...

随机推荐

  1. 压测工具 wrk

    wrk 是一款针对 Http 协议的基准测试工具,它能够在单机多核 CPU 的条件下,使用系统自带的高性能 I/O 机制,如 epoll,kqueue 等,通过多线程和事件模式,对目标机器产生大量的负 ...

  2. mysql--ERROR 2059 (HY000): Authentication plugin 'caching_sha2_password' cannot be loaded: /usr/lib64/mysql/plugin/caching_sha2_password.so: cannot open shared object file: No such file or directory

    问题背景: 1.在授权机器上连接mysql 8.0的数据库,账号.密码都没有问题,报错 2.使用 navicat工具连接8.0版本,报错 排查思路: 可能是创建用户没有指定插件使用了8.0自带的插件, ...

  3. JSONObject--- JSON---与bean对象的转换

    1.对象PO转json-string:  String json = JSON.toJSONString(customerBueventAccountPO); 1.可能用到的jar宝: json-li ...

  4. UNI-APP 使用Echart

    UNI-APP 使用Echart(含地图教程) https://blog.csdn.net/weixin_43548442/article/details/121468189 uniapp使用echa ...

  5. P5719 水题

    https://www.luogu.com.cn/problem/P5719 唠唠:别看这题很水,且只要求保留小数点后一位,倘若用float而不是double的话就无法AC,洛谷评测则只有40分.所以 ...

  6. 机器学习-线性分类-支持向量机SVM-软间隔-核函数-13

    目录 1. 总结 SVM 2. 软间隔svm 4. 核函数 1. 总结 SVM SVM算法的基础是感知器模型, 感知器模型 与 逻辑回归的不同之处? 逻辑回归 sigmoid(θx) 映射到 0-1之 ...

  7. SV Interface and Program 2

    Clocking:激励的时序 memory检测start信号,当start上升沿的时候,如果write信号拉高之后,将data存储到mem中 start\write\addr\data - 四个信号是 ...

  8. PS去除PDF中的WPS 编辑试用水印

    1. 问题 自己的学习资料.pdf被添加上了相关水印,导致阅读起来很不舒服 2. 解决方式(适用于白底黑字的pdf资料,去除水印) 2.1 初始图片如下: 2.2 打开PS,选择菜单栏中选择一项中的色 ...

  9. 【TouchGFX】使用CubeMX创建touchgfx项目 -- 初始篇

    1.系统构成,黑色块表示组件非必须 2.环境准备 CubeMX:6.0.1 touchgfx:4.15.0 rt-thread:2020-8-14 commit Keil:5.30 board:stm ...

  10. 神经网络优化篇:详解调试处理(Tuning process)

    调试处理 关于训练深度最难的事情之一是要处理的参数的数量,从学习速率\(a\)到Momentum(动量梯度下降法)的参数\(\beta\).如果使用Momentum或Adam优化算法的参数,\(\be ...