字符串操作指令的实质是对一片连续的存储单元进行处理,这片存储单元是由DS:SI或ES:DI来指定的。字符串操作指令可对内存单元按字节或字进行处理,并能根据操作对象的规定使SI(或DI)增减,具体规定如下:
· 当DF=0时,变址寄存器SI(或DI)增加1或2。
· 当DF=1时,变址寄存器SI(或DI)减少1或2。
在使用串指令前,须先进行以下设置。
· 必须事先设置隐含的寄存器。
· 设置方向标志位DF。
· 如果使用重复前缀,还必须把重复次数放入CX中。
(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。
重复前缀只能用在串操作指令的前面,重复次数应事先设置在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
运行结果:
清屏。