现在的位置: 首页 > 综合 > 正文

串操作指令(二)

2013年12月01日 ⁄ 综合 ⁄ 共 3016字 ⁄ 字号 评论关闭


串操作指令就是用一条指令实现对一串字符或数据的操作。8086的串操作指令的特点是:

◆ 通过加重复前缀来实现重复操作。重复的次数取决于CX寄存器的内容(在字符串比较和字符串检索指令中还与ZF标志有关)。

◆ 可以对字节串进行操作,也可以对字串进行操作。

◆ 所有的串操作指令都用寄存器SI对源操作数进行间接寻址,默认段寄存器为DS;所有的串操作指令都用寄存器DI为目的操作数进行间接寻址,默认段寄存器为ES。串操作指令是唯一的一组源操作数和目的操作数都在存储器中的指令。

◆ 串操作时,地址指针的修改与方向标志DF有关,当DF=1时,SI和DI作自动减量修改,当DF=0时,SI和DI作自动增量修改。

串操作指令一共有5条:

 字符串传送指令MOVSB/MOVSW

◆ 字符串比较指令CMPSB/CMPSW

◆ 字符串检索指令SCASB/SCASW

◆ 取字符串指令LODSB/LODSW

◆ 存字符串指令STOSB/STOSW

与上面串操作指令配合使用的重复前缀有:

 重复 REP

◆ 相等则重复/为零则重复 REPE/REPZ

◆ 不相等则重复/不为零则重复 REPNE/REPNZ

在串操作指令的前面加上重复前缀,使CPU能重复执行该指令,这使处理长字符串比用软件循环处理快得多。在执行有重复前缀的串操作指令时,CX寄存器控制重复次数,每重复执行一次,CX内容减1,CX减为0结束;此外,还可以按规定的条件(ZF=1或ZF=0)结束重复过程。重复前缀对规定条件的检测,是在每次进入串操作以前进行的。所以若初始化使操作次数CX为0,它将不会引起任何操作。

一、字符串传送指令MOVSB/MOVSW

字符串传送指令MOVSB/MOVSW将位于DS段的、由SI所指出的存储单元的内容传送到位于ES段、由DI所指的存储单元中,再修改SI和DI,从而指向下一个元素,MOVSB用于字节传送,MOVSW用于字传送。

MOVSB或MOVSW指令前面通常加重复前缀REP。重复执行的次数取决于CX寄存器的值,每次执行先检查CX内容,当CX为0则退出,不为0则将CX内容减1,然后传送一次。

【例】我们来看下面的程序段。

MOV    SI,1000H    ;源有效地址地址为1000H

MOV    DI,2000H    ;目的有效地址地址为2000H

MOV    CX,100      ;字符串长100个字节

CLD                ;方向标志清0,使指针按增量方向修改

REP    MOVSB       ;将源地址开始的100个字节传送到目的地址,每传送一次,地址指针加1,CX内容减1 

二、字符串比较指令CMPSB/CMPSW

字符串比较指令CMPSB/CMPSW把在DS段中由SI所指的字节或者字和在ES段中由DI所指的字节或者字相比较(相减),影响标志位,并自动修改地址指针。

CMPSB/CMPSW指令的前面常常加重复前缀REPE/REPZ 或REPNE/REPNZ。通过重复前缀的控制,利用CMPSB或者CMPSW,可以实现在两个字符串中寻找第一个不相等的元素或者第一个相等的元素。

【例】下面这段程序:假定在缓冲区BUF1和缓冲区BUF2各存有一个字符串,长度为10个字符。程序比较两个字符串,如果相等,将BL寄存器置为1,否则置为0。

LEA    SI,BUF1    ;SI寄存器指向BUF1

LEA    DI,BUF2    ;DI寄存器指向BUF2

CLD           ;清方向标志

MOV    CX,0AH     ;计数器为10

MOV    BL,1       ;先将BL置为1

REPZ   CMPSB       ;如比较结果相等,则重复执行,DI和S1分别加1,CX减1

JZ     DONE        ;如10个字节都相同,则BL=1

DEC    BL          ;否则BL置为0  

DONE:             ;后续处理

 

使用CMPSB/CMPSW指令时,要注意

前缀REPNZ/REPNE表示两个字符串的字节(或字)比较不等时,继续进行比较。前缀REPZ/REPE表示两个字符串的字节(或字)比较相等时,继续比较。每一种前缀都有两种形式,比如REPNZ和REPNE,它们的功能一样,使用时可以任意选择。

三、字符串检索指令SCASB/SCASW

使用字符串检索指令SCASB或者SCASW时,将AL中的字节或者AX中的字与位于 ES段由DI寄存器所指的内存单元的字节或字相比较(相减,影响标志位)。通过前缀,可以实现在DI所指的字符串中,寻找第一个与AL(或AX)的内容不同的字节(或字),或者寻找第一个与AL(或 AX)的内容相同的字节(或字)。

【例】下面这段程序,要在TAB开始的100个字节串数据中查找’$’字符,如果找到则把BL寄存器置为1,没有找到则BL置为0。

MOV    BL,1

MOV    AL,’$’

LEA    DI,TAB    ;字符串首地址送到DI

CLD               ;方向标志清0

MOV    CX,100    ;字符串中共有100个字节

REPNZ  SCASB      ;比较结果不等,则继续往下比

JZ     DONE       ;找到和AL内容相同的字符则BL=1,转后续处理

DEC    BL         ;AL中的值和字符串中的所有字节都不等,置BL=0

DONE:            ;后续处理

 

使用SCASB/SCASW指令时,有几点要注意:

1、目的字符串默认在ES段中,字符串首址的偏移量必须用DI指出。

2、上面例子中,退出REPNZ SCASB串操作循环的情况有两种:一种情况是检索到字符串中某个字节与AL中的字节相等,从而退出;另一种情况是字符串中没有任何一个字节和 AL中的字节相等,但已经检索完毕,从而退出。随后,可以通过对ZF的检测来判断当前是处于哪种情况。如果是前一种情况,则ZF=l;如果是后一种情况,则ZF=0。要注意的是, ZF并不受CX在串操作过程中不断减1的影响。

四、取字符串指令LODSB/LODSW

取字符串指令LODSB/LODSW将位于DS段由SI所指的存储单元的内容取到AL或AX中。用LODSB时,取的是字节,取完后,地址自动加1或减l;用LODSW时取的是字,取完后地址自动加2或减2。

因为使用LODSB/lODSW指令时,取来的字节或字放在AL或AX中,所以LODSB/LODSW指令前不能加前缀,否则,AL或AX中的内容会被后一次取到的内容所覆盖,最后只能得到字符串的最后1个字节或字。实际使用时,LODSB/LODSW指令一般用在循环程序中。

五、存字符串指令STOSB/STOSW

存字符串指令STOSB/STOSW把AL或AX中的数存到ES段中由DI寄存器所指的内存单元,并且自动修改地址指针。加上前缀REP以后,用STOSB或STOSW指令可以使一个内存区域中填满相同的数。

【例】下面的程序段使0400H开始的256个单元清0。

CLD                   ;清除方向标志

LEA    DI,[0400H]    ;将目的地址0400H送DI

MOV    CX,0080H      ;每次传送一个字,共有128个字

XOR    AX,AX         ;AX清0

REP    STOSW          ;将目的区的256个字节清0


抱歉!评论已关闭.