Win32汇编系列六、循环结构程序设计

前言

当我们要做重复的事情时,就需要用到循环指令,在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

在这里插入图片描述

.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

在这里插入图片描述

或者循环中根据条件退出,使用.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
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值