该指令是用指针ES:DI所指向字节/字/双字的值与相应的AL/AX/EAX的值相减,并依据所得到的差值来设置相关标志位;与此同时,变址寄存器DI还将根据方向标志DF的值来做相应的增减;
八、重复字符串操作指令(Repeat String Instruction)前面的字符串操作指令:取字符串数据、置字符串数据、字符串传送、输入字符串、输出字符串、字符串比较、字符串扫描,等指令,都是执行一次所具有的功能;但是,每个字符串通常都是由多个字符组成的,所以,需要重复执行这些字符串操作指令;为了满足这种需要,指令系统提供了一组重复前缀指令;
虽然在这些字符串指令的前面都可以添加一个重复前缀指令,但是由于指令执行结果的差异,对某个具体的字符串指令又不用重复前缀指令而改用其它循环来实现重复的需要;
重复字符串操作指令对标志位的影响是由被重复的字符串操作指令来决定;
1.重复前缀指令REP(Repeat String Instruction)
重复前缀指令是重复其后指定的字符串操作指令,重复的次数由计数寄存器CX来决定;
指令格式:
REP LODS/LODSB/LODSW/LODSD
REP STOS/STOSB/STOSW/STOSD
REP MOVS/MOVSB/MOVSW/MOVSD
REP INS/INSB/INSW/INSD
REP OUTS/OUTSB/OUTSW/OUTSD
重复前缀指令的
执行步骤如下:
STEP1:判断: CX=0
STEP2:如果CX=0,则结束重复操作,执行程序中的下一条指令;
STEP3:否则,CX=CX-1(不影响相关标志位),并执行重复前缀指令后面指定的字符串操作指令,在该指令执行完后,再转到步骤STEP1;
从上面的重复前缀指令格式来看,虽然我们可以使用重复前缀指令来重复取字符串数据指令(第一组指令),但是可能会因为指令的执行结果而在程序中几乎不会使用;
例如:编写一段程序,计算字符串"12345abcdefg"中各个字符的ASCII之和;
解:
......
MESS DB '12345abcdefg' ;在数据段进行变量说明
......
MOV AX,SEG MESS
MOV DS,AX
LEA SI,MESS ;用DS:SI来指向字符串的首地址;
MOV CX,13D ;重复次数
XOR BX,BX ;置求和的初值为0
REP LODSB ;循环去处字符;
......
从程序片段中看,虽然"REP LODSB"能从字符串中逐一取出每个字符,但这个操作是在同一条指令中完成的,程序的其它指令根本无法处理每次取出的字符数据,指令的执行结果是:AL中只保存了最后一次取出的字符'h'的ASCII码;
所以,为了实现本例的要求,不能使用重复前缀指令,而要把指令"REP LODSB"改写成如下四条指令:
XOR AH,AH ;为后面的累加做准备
AGAIN:LODSB
ADD BX,AX ;AL是被取出的字符,AH已被清0
LOOP AGAIN
2.条件重复前缀指令(Repeat String Conditionally)条件重复前缀指令与重复前缀指令的功能相似,所不同的是:条件重复前缀指令中的重复次数不仅由CX来决定,而且还会由标志位ZF的值来决定;根据ZF所起的作用又可分为两种:相等重复前缀指令和不等重复前缀指令;
A.相等重复前缀指令:
指令格式:
REPE/REPZ SCAS/SCASB/SCASW/SCASD
REPE/REPZ CMPS/CMPSB/CMPSW/CMPSD
该重复前缀指令的
执行步骤如下:
STEP1:判断条件: CX!=0 且 ZF=1
STEP2:如果条件不成立,则结束重复操作,执行程序中的下一条指令;
STEP3:否则,CX=CX-1(不影响任何标志位),并执行重复前缀指令后面指定的字符串操作指令,在该指令执行后,再转到步骤STEP1;
B.不等重复前缀指令:
指令格式:
REPNE/REPNZ SCAS/SCASB/SCASW/SCASD
REPNE/REPNZ CMPS/CMPSB/CMPSW/CMPSD
该重复前缀指令的
执行步骤如下:
STEP1:判断条件:CX!=0 且 ZF=0
STEP2:如果条件不成立,则结束重复操作,执行程序中的下一条指令;
STEP3:否则,CX=CX-1(不影响任何标志位),并执行重复前缀指令后面指定的字符串操作指令,在该指令执行完后,再转到步骤STEP1;
评论