首先,在數據段裏存放需要顯示的字符,比如輸出語句提示,另外也在數據區開闢存放輸入關鍵字和句子的區域,並定義輸入的最大長度,除此之外,爲了防止出現輸入被覆蓋的現象,我也定義了一個換行回車的字符串temp。
之後,開始運行時,首先利用串指令將提示字符輸出,然後再調用中斷21h的0ah輸入字符,這裏我限制關鍵字長度最大爲5,句子長度最大爲10,且代碼中actk,acts分別表示實際輸入的關鍵字的長度和實際輸入的句子長度。
用雙循環進行比較,外循環的比較次數是(句子的長度-關鍵字的長度+1),內循環的比較次數是關鍵字的長度,外循環比較我用的loop指令,內循環是字符串比較,可以用串指令中的字符串比較,並與repz向結合,即repz cmpsb,這兩條指令都需要用寄存器cx來控制循環次數,並且用si、di寄存器指定比較的字符,因此由外循環進入內循環時需要保存以上信息,內循環結束後恢復,代碼如下,
;*****************************************
datasg segment para 'data'
string1 db 'Enter keyword:$'
string2 db 'Enter sentence:$'
temp db 13,10,'$'
num db ?,13,10,'$'
;
mess1 db 'Match at location:',?,?,' H of the sentence',13,10,'$'
mess2 db 'No match.',13,10,'$'
;定義相關變量
keyword label byte
maxk db 5
actk db ?
keyd db 5 dup(?)
sentence label byte
maxs db 10
acts db ?
sente db 10 dup(?)
datasg ends
;*****************************************
codesg segment para 'code'
assume cs:codesg,ds:datasg,es:datasg
;-----------------------------------------
main proc far
push ds
sub ax,ax
push ax
mov ax,datasg
mov ds,ax
mov es,ax
;main part of program goes here
start:
lea dx,string1 ;提示輸入關鍵字
mov ah,09
int 21h
lea dx,keyword
mov ah,0ah
int 21h
cmp actk,0
je exit
lea dx,temp ;換行,防止覆蓋
mov ah,09
int 21h
lea dx,string2 ;提示輸入句子
mov ah,09
int 21h
lea dx,sentence
mov ah,0ah
int 21h
cmp acts,0
je exit
lea dx,temp ;換行,防止覆蓋
mov ah,09
int 21h
lea si,keyd
lea bx,sente
mov di,bx
cld
mov ch,0
mov cl,acts ;句子長度,一個字節
sub cl,actk
inc cx ;比較次數
comp:
push cx
push di
mov cl,actk ;關鍵字長度,一個字節
repz cmpsb ;如果相等繼續比較;64
jz find
pop di
pop cx
inc di
lea si,keyd
loop comp ;
lea dx,mess2 ;不匹配
mov ah,09
int 21h
jmp exit
find:
pop di
pop cx
sub di,bx
mov bx,di
inc bx ;得到十進制的位置
mov ax,bx
mov bh,16
div bh
add al,48
add ah,48
mov [mess1+18],al
mov [mess1+19],ah
lea dx,mess1 ;輸出
mov ah,09
int 21h
jmp start
exit:
ret ;return to DOS
main endp
;-------------------------------------------
codesg ends ;end of segment
;*******************************************
end main ;end assembly