安防之家讯:强制 CPU 重复执行同一指令集合的一种程序结构,它可以使许多重复性工作的程序大为简化。
循环结构一般是根据某一条件判断为真或假来确定是否重复执行循环体,循环指令和转移指令可以实现循环控制;还可以采用 MASM 6.x 提供的循环控制伪指令实现
循环结构
.model small
.stack
.data
sum dw ?
.code
.startup
xor ax,ax ; 被加数 AX 清 0
mov cx,100
again: add ax,cx
; 从 100,99,...,2,1 倒序累加
loop again
mov sum,ax ; 将累加和送入指定单元
.exit 0
end
例 1 : 在内存 40000H 开始的顺序 30 个单元中存放着 8 位无符号数,若将它们的和放在 DX 中,其程序如下:
MOV AX , 4000H
MOV DS , AX
MOV SI , 0000H
MOV CX , 30
XOR AX , AX
GOON : ADD AL , [SI]
ADC : AH , 00H
INC SI
DEC CX
JNZ GOON
MOV DX , AX
HLT
例 2 :在 DS 所决定的数据段,从偏移地址 BUFFER 开始顺序存放 100 个无符号的 16 位数,现欲编程序将 100 个字按大小顺序排列:
LEA DI , BUFFER
MOV BL , 99
NEXT0 :
MOV SI , DI
MOV CL , BL
NEXT3 :
MOV AX , [DI]
;第一个数 -->AX
ADD SI , 2
CMP AX , [SI]
;第一个数同第二个数比较
JNC NEXT5
;第一个数 第二个数,转 NEXT5
MOV DX , [SI]
;若第一个数 < 第二个数,第二个数 --> DX
MOV [DI] , DX
; DX--> 第一个位置
MOV [SI] , AX
NEXT5 :
DEC CL
JNZ NEXT3
; CL 0
INC DI
INC DI
DEC BL
JNZ NEXT0
HLT
例 3 . 求 1-100 的和
计数控制循环
, 循环次数固定
mov ah,1 ; 从键盘输入一个字符
int 21h
mov bl,al ;BL ← AL =字符的 ASCII 码
;DOS 功能会改变 AL 内容,故字符 ASCII 码存入 BL
mov ah,2
mov dl,':' ; 显示一个分号,用于分隔
int 21h
mov cx,8 ;CX ← 8 (循环次数)
again: shl bl,1 ; 左移进 CF ,从高位开始显示
mov dl,0 ;MOV 指令不改变 CF
adc dl,30h ;DL ← 0 + 30H + CF
;CF 若是 0 ,则 DL ← '0' ;若是 1 ,则 DL ← '1'
mov ah,2
int 21h ; 显示
loop again ;CX 减 1 ,如果 CX 未减至 0 ,则循环
例 4: 用二进制显示从键盘输入的一个字符的 ASCII 码
mov bx,offset string
again: mov al,[bx] ; 取一个字符
or al,al ; 是否为结尾符 0
jz done ; 是,退出循环
cmp al,'A' ; 是否为大写 A ~ Z
jb next
cmp al,'Z'
ja next
or al,20h
; 是,转换为小写字母(使 D5=1 )
mov [bx],al ; 仍保存在原位置
next: inc bx
jmp again ; 继续循环
done: .exit 0
例 5. 大小写
条件控制循环 , 利用标志退出
冒泡法
“冒泡法”是一种排序算法,不是最优的算法,但它易于理解和实现
冒泡法从第一个元素开始,依次对相邻的两个元素进行比较,使前一个元素不大于后一个元素;将所有元素比较完之后,最大的元素排到了最后;然后,除掉最后一个元素之外的元素依上述方法再进行比较,得到次大的元素排在后面;如此重复,直至完成就实现元素从小到大的排序
这需要一个双重循环程序结构
冒泡法的排序过程
比较遍数
序号 数 1 2 3 4
1 32 32 16 15 8
2 85 16 15 8 15
3 16 15 8 16 16
4 5 8 32 32 32
5 18 85 85 85 85
mov cx,count ;CX ←数组元素个数
dec cx ; 元素个数减 1 为外循环次数
outlp: mov dx,cx ;DX ←内循环次数
mov bx,offset array
inlp: mov al,[bx] ; 取前一个元素
cmp al,[bx+1] ; 与后一个元素比较
jna next
; 前一个不大于后一个元素,则不进行交换
xchg al,[bx+1] ; 否则,进行交换
mov [bx],al
next: inc bx ; 下一对元素
dec dx
jnz inlp ; 内循环尾
loop outlp ; 外循环尾
计数控制双重循环
; 现有一个以 $ 结尾的字符串,要求剔除其中的空格
.data
string db 'Let us have a try !','$'
.code
.startup
mov si,offset string
outlp: cmp byte ptr [di],'$'
; 外循环,先判断后循环
jz done ; 为 $ 结束
cmp byte ptr [si],' '
; 检测是否是空格
jnz next ; 不是空格继续循环
例 : 剔除空格
mov di,si ; 是空格,进入剔除空格分支
; 该分支是循环程序段
inlp: inc di
mov al,[di] ; 前移一个位置
mov [di-1],al
cmp byte ptr [di],'$'
; 内循环,先循环后判断
jnz inlp
jmp outlp
next: inc si ; 继续对后续字符进行处理
jmp outlp
done: .exit 0 ; 结束安防之家专注于各种家居的安防,监控,防盗,安防监控,安防器材,安防设备的新闻资讯和O2O电商导购服务,敬请登陆安防之家:http://anfang.jc68.com/