循环指令

  • 格式: LOOP OPR
    执行的操作:(CX)=(CX)-1,若CX≠0,跳转到标号OPR处循环执行,CX=0则执行LOOP的下一条指令。
  • 格式: LOOPZ/LOOPE OPR
    执行的操作:(CX)=(CX)-1,若CX≠0,并且ZF=1则跳转到标号OPR处循环执行,若CX=0,或者ZF=0则执行LOOP的下一条指令。
    说明:结果为0或相等循环。
  • 格式: LOOPNZ/LOOPNE OPR
    执行的操作:(CX)=(CX)-1,若CX≠0,并且ZF=0则跳转到标号OPR处循环执行,若CX=0,或者ZF=1则执行LOOP的下一条指令。
    说明:结果不为0或不相等循环。

串处理

串传送

格式:MOVS DST, SRC
MOVSB
MOVSW ;ES:[DI] <— DS:[SI]

  • 和rep连用时以字节或字的形式重复传送,直到cx为0为止。
  • 串传送方向由方向标志DF指出。若DF=0,SI和DI自动加1(字节单元)或自动加2(字单元);若DF=1,SI和DI自动减量。
  • CLD指令使DF=0,STD指令使DF=1.

串比较

格式:CMPS DST, SRC
CMPSB
CMPSW

  • 分别从源串和目的串中逐个取出字节(字)数据做相减操作,结果不回送,根据比较结果改变标志位。
  • 源串的偏移地址由SI寄存器指出,目的串的偏移地址由DI寄存器指出,比较次数有CX指出。
  • REPZ/REPE前缀功能:结果为0或相等则重复操作。若CX≠0,且ZF=1,则重复,(CX)=(CX)-1,直到CX=0。如果结果不为0或者不相等,退出重复操作,此时CX还没有减为0,SI和DI已经增量。
  • REPNZ/REPNE前缀功能:结果不为0或不相等则重复操作.

串扫描

格式:SCAS DST
SCASB
SCASW

  • 在目的串DST中查找与AL或AX相同(或不相同)的字节或字,结果不保存,根据查找结果改变标志位。
  • 目的串在附加段中,偏移地址由DI寄存器指出,扫描次数由CX指出。
  • 每扫描一次,DI自动增量或减量,CX减1;
  • 和重复前缀REPZ/REPE或REPNZ/REPNE连用。
    extra segment
    value dw 1,2,0,3,5,-1,10
    addr1 dw ?
    extra ends
    code segment
    assume cs:code,es:extra
    start:
    mov ax,extra
    mov es,ax
    mov ax,-1
    lea di,value
    cld
    mov cx,addr1-value
    shr cx,1
    repnz scasw
    sub di,2
    mov addr1,di
    mov ah,4ch
    int 21h
    code ends
    end start

串获取

格式:LODS SRC
LODSB
LODSW

  • 从源串SRC中取出一字节或字,放入AL或AX中。
  • 源串在数据段定义,偏移地址由SI指出。
  • 如果与REP连用,则连续取出字节或字。取出次数由CX指出。

串存入

格式:STOS DST
STOSB
STOSW

  • 将AL或AX内容存入附加段的目的串中。
  • 目的串中附加段定义,偏移地址由DI指出。
  • 如果与REP连用,则将AL或AX中的内容连续存入目的串。存入次数由CX指出。

多重循环

冒泡排序

data segment
part dw 15,32,6,-27,8
sign dw ?
data ends
code segment
assume cs:code,ds:data
start:
mov ax,data
mov ds,ax
mov cx,sign-part ;数组长度
shr cx,1 ;元素个数
dec cx

loop1:
push cx ;保存外循环次数
mov bx,0
loop2:
mov ax,part[bx]
cmp ax,part[bx+2]
jle next ;升序
xchg ax,part[bx+2] ;交换
mov part[bx],ax
next:
add bx,2
loop loop2
pop cx ;恢复外循环次数
loop loop1

mov ah,4ch
int 21h
code ends
end start