您的位置: 网站首页 > 程序开发 > 汇编语言与微机原理教程 > 第9章 80x86的寻址方式与指令系统 > 【9.3.6 串处理指令】

9.3.6 串处理指令

 

9.3.6  串处理指令

字符串操作指令的实质是对一片连续的存储单元进行处理,这片存储单元是由DS:SI或ES:DI来指定的。字符串操作指令可对内存单元按字节或字进行处理,并能根据操作对象的规定使SI(或DI)增减,具体规定如下:

·    当DF=0时,变址寄存器SI(或DI)增加1或2。

·    当DF=1时,变址寄存器SI(或DI)减少1或2。

在使用串指令前,须先进行以下设置。

·    必须事先设置隐含的寄存器。

·    设置方向标志位DF。

·    如果使用重复前缀,还必须把重复次数放入CX中。

1.串指令的形式及功能

(1)LODS——取字符串数据指令。

形式:LODS  地址表达式。

功能:AL/AX←(DS:SI),调整SI。

该指令还有如下两种形式:

LODSB       ;AL←(DS:SI),SI←SI±1

LODSW       ;AX←(DS:SI),SI←SI±2

(2)STOS——置字符串数据指令。

形式:STOS  地址表达式。

功能:(ES:DI)←AL/AX,调整DI。

该指令还有如下两种形式:

STOSB       ;(ES:DI)←AL,DI←DI±1

STOSW       ;(ES:DI)←AX,DI←DI±2

(3)MOVS——传送字符串指令。

形式:MOVS  地址表达式。

功能:(ES:DI)←(DS:SI),调整SI、DI。

该指令还有如下两种形式:

MOVSB       ;(ES:DI)←(DS:SI),SI←SI±1,DI←DI±1

MOVSW       ;(ES:DI)←(DS:SI),SI←SI±2,DI←DI±2

(4)CMPS——比较字符串指令。

形式:CMPS  地址表达式。

功能:(ES:DI)-(DS:SI),结果影响标志位,调整SI、DI。

该指令还有如下两种形式:

CMPSB       ; (ES:DI)- (DS:SI),结果影响标志位,SI←S1±1,DI←DI±1

CMPSW       ; (ES:DI)- (DS:SI),结果影响标志位,SI←SI±2,DI←DI±2

(5)SCAS——扫描字符串指令。

形式:SCAS  地址表达式。

功能:(ES:DI)-AL/AX,结果影响标志位,调整DI。

该指令还有如下两种形式:

SCASB       ; (ES:DI)-AL,结果影响标志位,DI←DI±1

SCASW       ; (ES:DI)-AX,结果影响标志位,DI←DI±2

【例9-9】编写一段程序,计算数字字符串‘123456789’中的各数值之和。

注意:我们可循环地取出字符串中的字符,转换为数字,然后累加到BX。

源程序:

.MODEL SMALL

.STACK 100H

.DATA

MESS DB ' 123456789'

.CODE

start:  MOV AX,SEG MESS

MOV DS,AX

LEA SI,MESS

MOV CX,9

CLD   

MOV AH,0

MOV BX,0

Again:LODSB

AND AL,0FH

ADD BX,AX

LOOP again

.EXIT 0

END Start

在调试环境下运行程序,可以看到BX寄存器的内容为002DH。

2.重复前缀

重复前缀只能用在串操作指令的前面,重复次数应事先设置在CX中。有3种形式的重复前缀。

(1)REP——重复前缀。

形式:REP 传送字符串指令或置字符串指令。

功能:步骤1,如果(CX)=0,则退出循环,执行步骤2的语句;步骤2,如果(CX)≠0,则执行所写串操作指令一次且CX=(CX)-1,转步骤1。

例如:

REP  MOVSB

REP  MOVSW

REP  STOSB

REP  STOSW

(2)REPE/REPZ——相等重复前缀。

形式:REPE/REPZ  扫描字符串指令或比较字符串指令。

功能:步骤1,如果(CX)=0或(ZF)=1,则退出循环;步骤2,如果(CX)≠0且(ZF)=0,则执行所写串操作指令一次且CX=(CX)-1,转步骤1。

例如:

REPE/REPZ  SCASB

REPE/REPZ  SCASW

REPE/REPZ  CMPSB

REPE/REPZ  CMPSW

显然,该重复前缀只能使用在影响ZF标志位的串指令前。

(3)REPNE/REPNZ——不相等重复前缀。

形式:REPNE/REPNZ  扫描字符串指令或比较字符串指令。

功能:步骤1,如果(CX)=0或(ZF)=0,则退出循环;步骤2,如果(CX)≠0且(ZF)=1,则执行所写串操作指令一次且CX=(CX)-1,转步骤1。

例如:

REPNE/REPNZ SCASB

REPNE/REPNZ SCASW

REPNE/REPNz CMPSB

REPNE/REPNZ CMPSW

显然,该重复前缀也只能在影响ZF标志位的串指令前使用。

【例9-10】将显示器缓冲区的内容传送到dBuf变量中,长度为2000字,然后将显示器缓冲区写入空格,完成清屏功能。

注意:显示器缓冲区的首地址为0B800H:0000H,我们可通过置字符串指令完成清屏功能。

源程序:

.MODEL  SMALL

.STACK  i00H

.DATA

dScreen DD 0B8000000h

wBuf DW 2000 DUP(?)

dBuffAdd DD WBuf

.CODE

start:    MOV  AX,@DATA

MOV     DS,AX

CLD

MOV     CX,2000

LES     DI,dBuffAdd

LDS     SI,dScreen

REP     MOVSW

LES     DI,dScreen

MOV     CX,2000

MOV     AX,2020H

REP     STOSW

.EXIT   0

END     start

运行结果:

清屏。