8086汇编——循环程序设计
一、循环指令LOOP格式: LOOP OPR执行的操作: (CX) ←(CX)-1。 若CX≠0,跳转到标号OPR处循环执行;若CX=0,则退出循环,执行LOOP的下一条指令。LOOPZ/LOOPE格式: LOOPZ/LOOPE OPR执行的操作: (CX) = (CX)-1。 若CX≠0,并且ZF=1,则跳转到标号OPR处循环执行; 若CX=0,或者ZF=0,则执行下一条指令。功...
一、循环指令
LOOP
格式: LOOP OPR
执行的操作: (CX) ←(CX)-1。 若CX≠0,跳转到标号OPR处循环执行;若CX=0,则退出循环,执行LOOP的下一条指令。
LOOPZ/LOOPE
格式: LOOPZ/LOOPE OPR
执行的操作: (CX) = (CX)-1。 若CX≠0,并且ZF=1,则跳转到标号OPR处循环执行; 若CX=0,或者ZF=0,则执行下一条指令。
功能:结果为0或相等循环。当执行到LOOPZ/LOOPE时,如果之前的指令结果为0或者相等继续循环,如果结果不为0或者不相等,提前退出循环,即使计数值CX还未减为0。
如果CMP条件不成立,则跳出循环。
LOOPNZ/LOOPNE
格式: LOOPNZ/LOOPNE OPR
执行的操作: (CX) = (CX)-1。 若CX≠0,并且ZF=0,则跳转到标号OPR处循环执行;若CX=0,或者ZF=1,则执行下一条指令。
说明:结果不为0或不相等循环。当执行到LOOPNZ/LOOPNE时,如果之前的指令结果不为0或者不相等继续循环,如果结果为0或者相等,提前退出循环,即使计数值CX还未减为0。
如果CMP条件成立,则跳出循环。
二、串处理
在前面,我们多次用到查ASCII码表、求数组元素的累加值、在字符串中查找字母等操作。这些操作都可归结为对数据串的处理,在此之前我们利用其他指令编程实现了串操作。利用汇编语言提供的专门的串处理指令,可以简化程序、方便编程,使程序清晰易读。
串传送
MOVS DST, SRC
MOVSB
MOVSW
执行的操作:串中的数据按字节
传送或按字
传送。
格式要求:
- 串传送指令要求源串的偏移地址由SI寄存器指出,目的串的偏移地址由DI寄存器指出,传送次数由CX指出。串传送指令要求和重复前缀REP连用。
- REP 前缀功能为:重复串操作直到(CX) = (CX) -1=0。
- 串的传送方向由方向标志DF指出。若DF=0,传送时存储单元地址SI和DI自动加1(字节单元)或自动加2 (字单元);若DF=1, SI 和DI自动减量。CLD 指令使DF =0,STD指令使DF=1。
功能:和REP连用时以字节或字的形式重复传送,直到CX为0为止。
REP MOVS BYTE PTR ES :[DI],DS:[SI]
这种格式的双操作数要显式地指出源和目的操作数的地址和属性,例如,传送字节数据串。
REP MOVSB 以字节形式重复传送
REP MOVSW 以字形式重复传送
两种格式隐含地指出源和目的串的地址和属性,即指令中没有操作数,只有操作码:
串比较
CMPS DST, SRC
CMPSB
CMPSW
分别从源串和目的串中逐个取出字节数据或字数据做相减操作,结果不回送,根据比较结果改变标志位。
说明:第一种格式的双操作数要显式地指出源和目的操作数的地址和属性。后两种格式隐含地指出源和目的串的地址和属性。CMPSB为字节串比较,CMPSW为字串比较。
格式要求:
- 源串的偏移地址由SI寄存器指出,目的串的偏移地址由DI寄存器指出,比较次数由CX指出。串比较指令和重复前缀REPZ/ REPE或REPNZ/REPNE连用。
REPZ/ REPE
前缀功能为:结果为0或相等则重复操作。若CX≠0,且ZF=1,则重复,(CX) = (CX)-1,直到CX =0。 如果结果不为0或者不相等,提前退出重复操作,此时CX还没有减为0,SI 和DI已经增量。REPNZ/REPNE
前缀:结果不为0或不相等则重复。若CX≠0,且ZF=0,则重复,(CX) = (CX)-1, 直到CX=0。如果结果为0或者相等,提前退出重复操作,同样CX还没有减为0,SI和DI已经增量。
串扫描
SCAS DST
SCASB
SCASW
在目的串DST中查找与AL或AX相同(或不相同)的字节或者字,结果不保存,根据查找结果改变标志位。SCASB为字节串扫描,SCASW 为字串扫描。
格式要求:
- 目的串在附加段中,偏移地址由DI寄存器指出,扫描次数由CX指出;
- 每扫描一次,DI自动增量或减量,CX 减1;
- 串扫描指令和重复前缀REPZ/ REPE或REPNZ/REPNE连用。
注意:
- 和REPZ/REPE连用时,扫描结果为0或相等则在串中重复扫描,直到找到与AL或AX不相同的数退出扫描。此时CX没有减为0,DI 已经增量。
- 和REPNZ/ REPNE连用时,扫描结果不为0或不相等则在串中重复扫描,直到找到与AL或AX相同的数退出扫描。同样CX没有减为0, DI已经增量。
串获取
LODS SRC
LODSB
LODSW
从源串SRC中取出一字节或者字,放入AL或AX中。
源串在数据段定义,偏移地址由SI指出。如果与REP连用,则连续取出字节或字。取出次数由CX指出。
串存入
STOS DST
STOSB
STOSW
将AL或AX内容存人附加段的目的串中。
格式要求:
- 目的串在附加段定义,偏移地址由DI指出。
- 如果与REP连用,则将AL或AX中的内容连续存人目的串。存入次数由CX指出。
三、多重循环
在多重循环程序编写过程中,要注意循环体内条件转移指令的转移方向。一般来说,可以从内循环跳入外循环,或者跳出外循环,不允许从外循环跳入内循环或者直接从循环外跳入循环内。
四、样例
判断学号末位数并按下述要求进行累加操作后输出结果。根据学号长度在数据段中定义类型为字节的存储单元stu_no;从键盘输入个人学号,保存至stu_no;对个人学号最后一位进行判断;如果是偶数,则对stu_no内偏移地址为偶数的字节单元进行求和;如果是奇数,则对stu_no内偏移地址为奇数的字节单元进行求和;
个人思路,有两个思路,一是在输入时将偏移地址为偶数和奇数地分别相加,看最后一位地输出相应结果。第二是输入完毕后再判断相加。
在此写一下第二种情况地代码:
DATAS SEGMENT
stu_no DB 20 DUP(?)
LL DW 2 DUP(?)
DATAS ENDS
STACKS SEGMENT
;此处输入堆栈段代码
STACKS ENDS
CODES SEGMENT
ASSUME CS:CODES,DS:DATAS,SS:STACKS
START:
MOV AX,DATAS
MOV DS,AX
MOV AH,01H
MOV BX,0000H
MOV CX,0020H
SS1:
INT 21H
MOV stu_no[BX],AL
INC BX
CMP AL,0DH ;如果是回车则退出
LOOPNE SS1
SUB BX,01H
MOV stu_no[BX],0H
SUB BX,01H ;最后一位数偏移地址为BX-2
MOV LL,BX
MOV AL,stu_no[BX]
SUB AL,30H
TEST AL,01H
JZ EVENNUMBER
MOV BX,0001H
MOV AX,0000H
;对于偶数奇数两种情况而言只是起始位置不一样而已
EVENNUMBER:
MOV AX,0000H
MOV BX,0000H
SS2:
ADD AL,stu_no[BX]
SUB AL,30H
ADD BX,02H
CMP BX,LL
JA OUT1 ;如果大于则转移到out1
LOOPNE SS2
OUT1:
AAM
MOV BX,AX
ADD BX,3030H
MOV AH,02H
MOV DL,BH
INT 21H
MOV DL,BL
INT 21H
MOV AH,4CH
INT 21H
CODES ENDS
END START
更多推荐
所有评论(0)