2.3.4 串操作指令
8086/8088指令系统专门提供了完成串操作指令,包括:串传送指令MOV S,串比较指令CMPS,串扫描指令SCAS,从串取指令LODS,存入串指令STOS,以及与上述基本指令配合使用的前缀指令:REP(重复),REPE/REPZ(相等/为零则重复),REPNE/REPNZ(不相等/不为零则重复)。串操作类指令可以用来实现内存区域的数据串操作。这些数据串可以是字节串,也可以是字串。
1.重复指令前缀
串操作类指令可以与重复指令前缀配合使用,从而可以使操作得以重复进行,及时停止。重复指令前缀的几种形式见表2-8所示。
表2-8 重复指令前缀
2.串指令
串指令共有五种,具体功能见表2-9。
表2-9 串操作指令
对串指令要注意以下几个问题:各指令所使用的默认寄存器是SI(源串地址)、DI(目的地址)、CX(字串长度)、AL(存取或搜索的默认值)。
源串在数据段,目的串在附加段。方向标志与地址指针的修改。DF=1,则修改地址指针时用减法;DF=0时,则修改地址指针时用加法。
MOV S、STOS、LODS指令不影响标志位。
(1)MOV S指令的功能。
把数据段中由SI间接寻址的一个字节(或一个字)传送到附加段中由DI间接寻址的一个字节单元(或一个字单元)中,然后,根据方向标志DF及所传送数据的类型(字节或字)对SI及DI进行修改,在指令重复前缀REP的控制下,可将数据段中的整串数据传送到附加段中。
【例2-49】 在数据段中有一字符串,其长度为17,要求把它们传送到附加段中的一个缓冲区中,其中源串存放在数据段中从符号地址MESS1开始的存储区域内,每个字符占一个字节;MESS2为附加段中用以存放字符串区域的首地址。实现上述功能的程序段如下:
…
LEA SI,MESS1;置源串偏移地址
LEA DI,MESS2;置目的串偏移地址
MOV CX,17;置串长度
CLD;方向标志复位
REP MOV SB;字符串传送
…
(2)CMPS指令的功能。
把数据段中由SI间接寻址的一个字节(或一个字)与附加段中由DI间接寻址的一个字节(或一个字)进行比较操作,使比较的结果影响标志位,然后根据方向标志DF及所进行比较的操作数类型(字节或字)对SI及DI进行修改,在指令重复前缀REPE/REPZ或者REPNE/REPNZ的控制下,可在两个数据串中寻找第一个不相等的字节(或字),或者第一个相等的字节(或字)。
【例2-50】 在数据段中有一字符串,其长度为17,存放在数据段中从符号地址MESS1开始的区域中;同样在附加段中有一长度相等的字符串,存放在附加段中从符号地址MESS2开始的区域中,现要求找出它们之间不相匹配的位置。
实现上述功能的程序段如下:
…
LEA SI,MESS1;装入源串偏移地址
LEA DI,MESS2;装入目的串偏移地址
MOV CX,17;装入字符串长度
CLD;方向标志复位
REPE CMPSB
…
上述程序段执行之后,SI或DI的内容即为两字符串中第一个不匹配字符的下一个字符的位置。若两字符串中没有不匹配的字符,则当比较完毕后,CX=0,退出重复操作状态。
(3)SCAS指令的功能。
用由指令指定的关键字节或关键字(分别存放在AL及AX寄存器中),与附加段中由DI间接寻址的字节串(或字串)中的一个字节(或字)进行比较操作,使比较的结果影响标志位,然后根据方向标志DF及所进行操作的数据类型(字节或字)对DI进行修改,在指令重复前缀REPE/REPZ或REPNE/REPNZ的控制下,可在指定的数据串中搜索第一个与关键字节(或字)匹配的字节(或字),或者搜索第一个与关键字节(或字)不匹配的字节(或字)。
【例2-51】 在附加段中有一个字符串,存放在以符号地址MESS2开始的区域中,长度为17,要求在该字符串中搜索空格符(ASCII码为20H)。实现上述功能的程序段如下:
…
LEA DI,MESS2;装入目的串偏移地址
MOV AL,20H;装入关键字节
MOV CX,17;装入字符串长度
REPNE SCASB
…
上述程序段执行之后,DI的内容即为相匹配字符的下一个字符的地址,CX中是剩下还未比较的字符个数。若字符串中没有所要搜索的关键字节(或字),则当查完之后(CX)=0退出重复操作状态。
(4)STOS指令的功能。
把指令中指定的一个字节或一个字(分别存放在AL及AX寄存器中),传送到附加段中由DI间接寻址的字节内存单元(或字内存单元)中,然后,根据方向标志DF及所进行操作的数据类型(字节或字)对DI进行修改操作。在指令重复前缀的控制下,可连续将AL(AX)的内容存入到附加段中的一段内存区域中去,该指令不影响标志位。
【例2-52】 要对附加段中从MESS2开始的5个连续的内存字节单元进行清0操作,可用下列程序段实现:
…
LEA DI,MESS2;装入目的区域偏移地址
MOV AL,00H;为清零操作准备
MOV CX,5;设置区域长度
REP STOSB
…
(5)LODS指令的功能。
从串中取指令实现从指定的字节串(或字串)中读出信息的操作。
【例2-53】 比较DEST和SOURCE中的500个字节,找出第一个不相同的字节。如果找到,则将SOURCE中的这个数送AL中。
…
CLD
LEA DI,ES:DEST
LEA SI,SOURCE
MOV CX,500
REPE CMPSB
JCXZ NEXT
MATCH:DEC SI
MOV AL,BYTE PTR[SI]
NEXT:…
【例2-54】 在数据段中有一个字符串,其长度为17,要求把它们传送到附加段中的一个缓冲区中。编制程序如下:
DATA SEGMENT;定义数据段
MESS1 DB ′IBMPC COMPUTER$′
DATA ENDS
EXTRA SEGMENT;定义附加数据段
MESS2 DB 17 DUP(?)
EXTRA ENDS
CODE SEGMENT;定义代码段
ASSUME CS:CODE,DS:DATA,ES:EXTRA
…
START:MOV AX,DATA;将数据段地址DATA送入DS段
MOV DS,AX
MOV AX,EXTRA;将附加数据段地址EXTRA送入ES段
MOV ES,AX
…
LEA SI,MESS1
LEA DI,MESS2
MOV CX,17
CLD
REP MOV SB
…
CODE ENDS
END START;段结束语句
其中SEGMENT,ENDS为定义段的伪操作,DB为定义字节数据的伪操作,这在第3章中将专门说明。在这里,读者只要知道MESS1为源串,存放在数据段中从符号地址MESS1开始的存储区内,每个字符占有一个字节;MESS2为目的串,存放在附加段中从符号地址MESS2开始空出17个字节的存储区内。后面的程序则存放在代码段中。
免责声明:以上内容源自网络,版权归原作者所有,如有侵犯您的原创版权请告知,我们将尽快删除相关内容。