前言

当我们要做重复的事情时,就需要用到循环指令,在DOS时代的汇编语言中,最常用的语句就是LOOP系列指令,但是这些指令又使程序可读性差,增加了维护难度,在Win32汇编中所以增加了类似高级语言中循环语法的伪代码,本章就介绍LOOP指令和Win32中的伪指令。

LOOP

LOOP的循环次数保存在ECX中,每执行一次循环,ECX就自动减一,直到为0,如果为0则退出循环,LOOP后面跟着标号,程序走到LOOP指令时,判断ECX减一是否为0,如果是则继续下一行,否则跳到标号位置执行。

下面是执行10次循环,每次使EAX加1,最终打印EAX也因该为10。

.386
.Model Flat, StdCall
Option Casemap :None

include C:\masm32\include\kernel32.inc
includelib C:\masm32\lib\kernel32.lib
includelib C:\masm32\lib\msvcrt.lib


printf    PROTO C : dword,:vararg
system   PROTO C : dword,:vararg
scanf  PROTO C : dword,:vararg
.data


szPause db 'pause',10,13,0
szOutFmt1 byte '%d',10,13,0

.code


START:
mov ecx ,10
mov eax,0
next:
add eax,1
loop next

invoke printf,addr szOutFmt1,eax
invoke system,addr szPause

END START

Win32汇编系列六、循环结构程序设计_java在这里插入图片描述

.repeat、.until

这是其中的一种循环伪指令,结束条件放在.until 后面,如果处理器计算出条件语句的结果为假,那么会跳转到.repeat指令后面继续执行,如果中间想退出可以使用.break,这种循环结构至少被执行一次。

.386
.Model Flat, StdCall
Option Casemap :None

include C:\masm32\include\kernel32.inc
includelib C:\masm32\lib\kernel32.lib
includelib C:\masm32\lib\msvcrt.lib


printf    PROTO C : dword,:vararg
system   PROTO C : dword,:vararg
scanf  PROTO C : dword,:vararg
.data


szPause db 'pause',10,13,0
szOutFmt1 byte '%d',10,13,0

.code


START:
mov eax,0
.repeat
add eax,1
.until eax ==10
invoke printf,addr szOutFmt1,eax
invoke system,addr szPause

END START

Win32汇编系列六、循环结构程序设计_java_02或者循环中根据条件退出,使用.break .if eax==5

.386
.Model Flat, StdCall
Option Casemap :None

include C:\masm32\include\kernel32.inc
includelib C:\masm32\lib\kernel32.lib
includelib C:\masm32\lib\msvcrt.lib


printf    PROTO C : dword,:vararg
system   PROTO C : dword,:vararg
scanf  PROTO C : dword,:vararg
.data


szPause db 'pause',10,13,0
szOutFmt1 byte '%d',10,13,0

.code


START:
mov eax,0
.repeat
add eax,1
.break .if eax==5
.until eax ==10
invoke printf,addr szOutFmt1,eax
invoke system,addr szPause

END START

.WHILE、.ENDW

这是最常见的一种结构,其实这些指令和VB中的差不多,有while也有end while,这种结构先判断条件,然后在执行,如果条件为真就会执行循环体,.ENDW就是一次循环结束标识 ,他会使程序跳转到.WHILE后再次判断。

.386
.Model Flat, StdCall
Option Casemap :None

include C:\masm32\include\kernel32.inc
includelib C:\masm32\lib\kernel32.lib
includelib C:\masm32\lib\msvcrt.lib


printf    PROTO C : dword,:vararg
system   PROTO C : dword,:vararg
scanf  PROTO C : dword,:vararg
.data


szPause db 'pause',10,13,0
szOutFmt1 byte '%d',10,13,0

.code


START:
mov eax,0
.while eax<10
add eax,1
.endw
invoke printf,addr szOutFmt1,eax
invoke system,addr szPause

END START

.WHILE和.REPEAT系列伪代码最重要的区别就是.REPEAT会先执行后判断,而.WHILE会先判断在执行,另外这些伪代码都可以嵌套使用,

.BREAK、.CONTINUE

.break后面跟着.if条件,如果满足的话,就会跳出循环,同样.continue后面也是.if条件,满足的话跳出其所在的那层循环体的一次循环,继续执行下一次。

实例

统计字符串中某个字符出现的字数

.386
.Model Flat, StdCall
Option Casemap :None

include C:\masm32\include\kernel32.inc
includelib C:\masm32\lib\kernel32.lib
includelib C:\masm32\lib\msvcrt.lib


printf    PROTO C : dword,:vararg
system   PROTO C : dword,:vararg
scanf  PROTO C : dword,:vararg
.data
szText db 'abcabcabcabc',0
Caption db '统计',0


szPause db 'pause',10,13,0
szOutFmt1 byte '%d',10,13,0

.code

START:
mov ecx,0
mov ebx,offset szText
mov al ,[ebx]

.while (al!=0)
.if al=='a'
inc ecx
.endif
inc ebx
mov al,[ebx]
.endw
invoke printf,addr szOutFmt1,ecx
invoke system,addr szPause

END START

- END -