字符串操作举例
下面再举几例来说明字符串操作指令和重复前缀的使用,同时说明如何进行字符串操作。
例2.1:写一个判别字符是否在字符串中出现的子程序。设字符串以0结尾。
串扫描指令可用于在字符串中搜索指定的字符,从而判别字符是否属于字符串。下面的子程序并没有利用串扫描指令,代码虽长,自有其独到之处,请注意。
;子程序名:STRCHR
;功 能:判字符是否属于字符串
;入口参数:DS:SI搜索字符串首地址的段值:偏移
; AL=字符代码
;出口参数:CF=0表示字符在字符串中,字符首次出现处的偏移
; CF=1表示字符不在字符串中
STRCHR PROC
PUSH BX
PUSH SI
CLD
MOV BL,AL ;字符串复制到BL寄存器
TEST SI,1 ;判地址是否为偶
JZ STRCHR1 ;是,转
LODSB ;取第一个字符,比较之
CMP AL,BL
JZ STRCHR3
AND AL,AL
JZ STRCHR2
STRCHR1: LODSW ;取一个字
CMP AL,BL ;比较低字节
JZ STRCHR4
AND AL,AL
JZ STRCHR2
CMP AH,BL
JZ STRCHR3
AND AH,AH
JNZ STRCHR1
STRCHR2: STC
JMP SHORT STRCHR5
STRCHR3: INC SI
STRCHR4: LEA AX,[SI-2]
STRCHR5: POP SI
POP BX
RET
STRCHR ENDP
上面的子程序对从奇地址开始存放的字符串的第一个字符作了特别处理。在随后的循环处理中,字符串便从偶地址开始,每次取一个字,即两个字符,在逐个字符比较。为什么要从偶地址开始取一个字?较好的理由留给读者思考。
例2.2:写一个在字符串1后追加字符串2的子程序。设字符串均以0结尾。
该子程序的实现流程如图6.1所示。现再作几点说明:(1)要传送的字符串2包括其结束标志;(2)字符串2的传送以字传送为主,考虑了从偶地址开始进行字的传颂;(3)最后处理可能遗留的一字节
;子程序明:STRCAT
;功 能:在字符串1末追加字符串2
;入口参数:DS:SI字符串1起始地址的段值:偏移
; DS:DI字符串2起始地址的段值:偏移
;出口参数:无
;说 明:不考虑在字符串1后是否留有足够的空间
STRCAT PROC
PUSH ES
PUSH AX
PUSH CX
PUSH SI
PUSH DI
CLD
PUSH DS
POP ES
PUSH DI
MOV DI,SI
XOR AL,AL
MOV CX,0FFFFH
REPNZ SCASB ;确定字符串1的尾
LEA SI,[DI-1] ;SI指向字符串1的结束标志
POP DI
MOV CX,0FFFFH
REPNZ SCASB ;CX测字符串2的长度
NOT CX ;DI为字符串2包括结束标志的长度
SUB DI,CX ;再次指向字符串2的首
XCHG SI,DI ;为拼接作准备
TEST SI,1 ;字符串2是否从奇地址开始?
JZ STRCAT1
MOVSB ;特别处理第一字节
DEC CX
STRCAT1: SHR CX,1 ;移动数据块长度除2
REPZ: MOVSW ;字移动
JNC: STRCAT2
MOVSB ;补字移动时遗留的一字节
STRCAT2: POP DI
POP SI
POP CX
POP AX
POP ES
RET
STRCAT ENDP