目录 上一页 下一页 下一章

-106- PC机汇编语言实战精解

有数据都扫一遍。而我们所需要的恰好是扫描整个串,这又该如何应用SCAS指令呢?
  幸好SCAS指令可以配合一个前缀,这个前缀就是:
助记符:REP(Repeat)
用 途:作为前缀使后面的串指令重复执行,重复次数在CX中设定。
格 式:REP 串处理指令
执 行:判断CX,若CX不为0,则CX寄存器减1,执行后面的指令,重复这三个步骤直至CX=0
  在实际应用中这个前缀往往采用这样两种形式:

REPE/REPZ-REPNE/REPNZ
  指令中的"E"和"Z"与前面讨论的条件转移指令"JE/JZ"和"JNE/JNZ"中的"E"、"Z"含义相同。REPE的意思就是"Repeat While equal"--相等则重复,NE自然是"Not Equal"了。在前面的程序中我们使用了"REPNZ"作为前缀,因为我们要寻找一个与AL寄存器相等的数据,自然要在"不相等"的情况下重复SCASB指令,而一旦找到相等的数据,即使CX不为0,REP也会停止。这样做可以提高程序的效率,避免无意义的搜索。如果我们要在一串相同的数据中寻找一个与众不同者,那么自然要用"REPE"或"REPZ"作前缀了。

  由于SCAS指令的实际动作是将串中的数据与累加器进行比较,"找到"意味着ZF=1,"找不到"对应ZF=0,因此我们可以用"JZ/JNZ"指令来检测扫描结果。注意在计算"$"的位置时我们让DI寄存器多减了1,想一想这是为什么。
  至此我们已经可以在一个串中寻找到一个字节或一个字的数据,下面我们来讨论一个更复杂的问题--如何在一个字符串中找到一个"子字符串"?
  按照前面的习惯,我们先看看一般的解决办法:
SCHSTR.ASM
data

string
substrg
ascii
data

code

main



next_str:


segment
assume
db'The sa
db'sunshi
db'012345
ends

segment
assume
proc
mov
mov
mov

mov
lodsb

ds:data
me sunshine is presented to
ne',0
6789ABCDEF'



cs:code
far
ax,data
ds,ax
di,offset string

si,offset substrg



all those who love sunshine',0







;初始化DS寄存器指向数据段

;DI寄存器指向字符串STRING

;SI寄存器指向待查字符串
;取得待查字符串的第一个字母

Copyright © 2004-2015 Reanimator www.cookmoon.org

目录 上一页 下一页 下一章