汇编之循环语句

今天看了《加密与解密》循环语句部分,接下来将从do-while循环,while循环,for循环三个方面去学习循环的汇编。

0x01 do-while循环

do-while循环的流程是:先执行语句块,在进行表达式判断,当表达式为真时,在继续执行语句块。接下来先看一段C语言代码

 #include "stdafx.h"

    int main(int argc, char* argv[])
    {
        int nCount=0;
        do{
            printf("%d\r\n",nCount);
            nCount++;   
        }
            while(nCount<argc);   argc为整型,用来统计程序运行时发送给main函数的命令行参数的个数,在VS中默认值为1return 0;
    }

切到反汇编模式
在这里插入图片描述
可以看到,先执行了输出语句和nCount的自增,然后比较nCount和argc的大小,若小于则循环,否则将线性向下执行。
下面是我写的汇编代码


 #include "stdafx.h"

    int main(int argc, char* argv[])
    {
            //int nCount=0;
            char *str="%d\r\n";
            _asm{
                          mov eax,0
        circle:           push eax
                          push str
                         call printf       //调用printf函数
                          add esp,8       //平衡栈
                          inc eax         //nCount自增,         
                        cmp eax,dword ptr [ebp+8]
                       jl circle             //if (nCount<argc),跳转到circle循环执行
                       xor eax,eax     //设置返回值为0
            }
    }

成功运行!
在IDA Pro里面识别do—while循环
在这里插入图片描述在这里插入图片描述

0x02 while循环

while循环的流程是:先进行表达式判断,在执行语句块,当表达式为真时,会继续执行语句块,示例如下

#include<stdio.h>
void main()
{
      char *str="%d\n";
_asm{
                  mov eax,1             //i=1
                  mov ebx,0            //sum=0
circle:           cmp eax,100
                  jg   end
                 add ebx,1              //sum++
                 inc eax,1            //i++
                 jmp circle
end:
                 push ebx
                 push str
                 call printf
                 add esp,8
}
}

切入到反汇编:
在这里插入图片描述
可以看到,先比较i与100的大小,若i<=100,则执行语句块,否则就直接输出sum。
下面是我写的汇编代码

#include<stdio.h>
void main()
{
      char *str="%d\n";
_asm{
                    mov eax,1             //i=1
                  mov ebx,0            //sum=0
circle:           cmp eax,100
                  jg   end
                 add ebx,1              //sum++
                  inc eax,1            //i++
                 jmp circle
end:
                  push ebx
                  push str
                  call printf
                 add esp,8
}
}

在IDA Pro里面识别while循环
在这里插入图片描述在这里插入图片描述
循环的特点是会向低地址跳转。while循环和do-while循环区别:
1.while循环使用的是jmp循环,while循环使用的是jxx汇编指令需要取反
2.while循环比do循环多一次if判断,因此性能上while循环不如do循环高,在Release版本中,编译器会把while循环优化成等价的do循环。

0x03 for循环

for语句由赋初值,循环条件,循环步长三条语句组成,示例如下:

  #include "stdafx.h"

    int main(int argc, char* argv[])
    {
        for(int nCount=0; nCount<argc;nCount++)
               {
                            printf("%d\r\n",nCount);
               }
                    return 0;
    }

切入到反汇编
在这里插入图片描述
在这里可以看到,对nCount赋值以后,就跳到判断的位置,如果判断结果为真,就跳上去执行语句块
接下来是我写的汇编代码

   #include "stdafx.h"

    int main(int argc, char* argv[])
    {
          char *str="%d\r\n";
    _asm{
                mov eax,0   
                         jmp judge
    circle:      add eax,1
    judge:     cmp eax,dword ptr[ebp+8]
                                 jge circle
                          push eax
                          push str
                          call printf
                add esp,8
                xor eax,eax
    }
    }

在IDA Pro里面识别for循环
在这里插入图片描述在这里插入图片描述关于循环语句的学习就先到这里。

eax加1,可以有如下两种表示:

    inc eax
    add eax,1

复制代码
虽然功能一样,可还是有以下区别:
(1) 机器码长度不同,inc短,add长。(这不是关键)
(2)INC不改变标志位CF,而ADD则改变CF。(这点很关键。)
例如:

        number dw 0FFFFH,1234H,0,0,0
       表示的80位数1234FFFFH,希望给它加2。
        MOV SI,OFFSET NUMBER
         MOV CX,4              ;4个高位的字单元
        ADD WORD PTR [SI],2   ;最低位加2
L1:
         INC SI
         ADC WORD PTR [SI],0   ;把产生的进位加到高位
        LOOP L1

若把INC SI换成ADD SI,1就会出错。原因是 ADD WORD PTR [SI],2产生了CF,若用ADD SI,1就会把CF清0,从而后面的ADC就不能把前面的进位加上。

   dec eax
   sub eax,1

复制代码
eax减1,dec和sub的区别也和加1类似。

  • 0
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值