字符串显示中的子字符串



我是汇编初学者,我正试图编写一个程序,我应该从键盘输入2个字符串。第一个字符串应该是主字符串,第二个输入是我需要在主字符串中查找的子字符串。如果我找到它,我应该显示它被找到,如果没有,我应该显示它没有被找到。

我尝试比较字符串的长度,以便如果第一个字符串的字符少于第二个字符串,则消息"无效";将被显示。然后,我尝试将子字符串与字符串进行比较,直到在字符串中找到子字符串并且消息"字符串找到"为止。获取显示,如果没有,则显示消息:"字符串未找到"会显示出来。不管我输入什么单词,它总是显示"无效"。我怎样才能改变这一点呢?
下面是我的代码:

.model small
.stack 200h
.data
prompt1 db "Input String: $"
prompt2 db 10,10, 13, "Input Word: $"
prompt3 db 10,10, 13, "Output: $"
found db "Word Found. $"
notfound db "Word Not Found. $"
invalid db 10,10, 13, "Invalid. $"
InputString db 21,?,21 dup("$")  
InputWord db 21,?,21 dup("$")
actlen db ?
.code
start:
mov ax, @data
mov ds, ax
mov es, ax
;Getting input string
mov ah,09h
lea dx, prompt1
int 21h
lea si, InputString
mov ah, 0Ah
mov dx, si
int 21h
;Getting input word
mov ah,09h
lea dx, prompt2
int 21h
lea di, InputWord
mov ah, 0Ah
mov dx, di
int 21h
;To check if the length of substring is shorter than the main string
mov cl, [si+1]
mov ch, 0
add si, 2
add di, 2
mov bl, [di+1]
mov bh, 0
cmp bx, cx
ja invalid_length
je valid
jb matching
valid:
cld
repe cmpsb
je found_display
jne notfound_display
mov     bp, cx      ;CX is length string (long)
sub     bp, bx      ;BX is length word  (short)
inc     bp
cld
lea     si, [InputString + 2]
lea     di, [InputWord + 2]
matching:
mov     al, [si]    ;Next character from the string
cmp     al, [di]    ;Always the first character from the word
je      check
continue:  
inc     si          ;DI remains at start of the word
dec     bp
jnz     matching    ;More tries to do
jmp     notfound_display
check:
push    si
push    di
mov     cx, bx     ;BX is length of word
repe cmpsb
pop     di
pop     si
jne     continue
jmp     found_display
again:
mov si, ax    
dec dx
lea di, InputWord
jmp matching

invalid_length:
mov ah, 09h
lea dx, invalid
int 21h
jmp done
found_display:
mov dx, offset found
mov ah, 09h
int 21h
jmp done
notfound_display:
mov dx, offset notfound
mov ah, 09h
int 21h
;fallthrough is intentional
done:
mov ax,4C00h
int 21h        ;exit program and return to DOS

end start

我看到您已经尝试应用我在寻找输入字符串中的子字符串的答案中给出的一些建议。
但是出错主要是因为您决定使用特殊情况,即输入的字符串与输入的单词具有相同的长度. 这根本不是特例!如果发生这种情况,我对可能发现的数量的计算将保持有效,并在BP寄存器中产生1。简而言之,您的问题源于插入了有效的部分,而没有相应地编辑程序。

add si, 2
add di, 2
je valid
jb matching
valid:
cld
repe cmpsb
je found_display
jne notfound_display

一旦去掉多余的有效的部分,就不需要上面的所有内容了。

again:
mov si, ax    
dec dx
lea di, InputWord
jmp matching

不要忘记在你的程序中删除任何你实际上不需要的代码,特别是当你使用在互联网上找到的代码时。

解决方案
...
; To check if the length of substring is shorter than the main string
mov  cl, [si+1]
mov  ch, 0
mov  bl, [di+1]
mov  bh, 0
mov  bp, cx      ; CX is length string (long)
sub  bp, bx      ; BX is length word  (short)
jb   notfound_display
inc  bp          ; -> BP is number of possible finds 1+
cld
lea  si, [InputString + 2]
lea  di, [InputWord + 2]
matching:
mov  al, [si]    ; Next character from the string
cmp  al, [di]    ; Always the first character from the word
je   check
continue:  
inc  si          ; DI remains at start of the word
dec  bp
jnz  matching    ; More tries to do
jmp  notfound_display
check:
push si
push di
mov  cx, bx      ; BX is length of word
repe cmpsb
pop  di
pop  si
jne  continue
jmp  found_display
...

一些优化
  • 我在计算可能发现的数量时吸收了cmp bx, cxja invalid_length指令(剃掉2字节)。如果减法产生借位,你就知道这个词比字符串长,这样你就可以分支了。是否跳转到invalid_lengthnotfound_display由您决定…

  • 如果您将lea si, [InputString + 2]lea di, [InputWord + 2]替换为add si, 2add di, 2,则可以缩短此程序2个字节。

应该可以:

.model small
.stack 100h
print macro p
lea dx,p
mov ah,09h
int 21h
endm
.data
cn db 0
pn db 0
space db 10,13, " $"
msg db 10,13, "hjut$"
msg1 db "Introduceti primul sir:$"
msg2 db "Introduceti al doilea sir:$"
msg3 db "Al doilea sir nu se gaseste in primul.$"
msg4 db "Al doilea sir se gaseste in primul. $"
ar db 20 dup("$")
br db 20 dup("$")
.code
start:
mov ax,@data
mov ds,ax
mov si,01h
mov di,00h
mov cn,00h
print msg1
read1:mov ah,01h
int 21h
mov ar[si],al
inc si
cmp al,0dh
jnz read1

mov si,00h
print msg2
read2:mov ah,01h
int 21h
mov br[si],al
inc si
cmp al,0dh
jnz read2
mov si,00h
mov di,00h
jmp lop1
lop1: mov di,00h
inc si
mov bh,ar[si]
cmp bh,0dh
jz disp
mov bh,br[di]
cmp ar[si],bh
jnz lop1
jz lop2
lop2:inc si
inc di
mov bh,br[di]
cmp bh,0dh

jz l1
mov bh,br[di]
cmp ar[si],bh
jz lop2
jmp lop1
l1:
add cn,01h
dec si
jmp lop1
disp:
cmp cn,00h
jz disp1
print msg4
add cn,30h
mov dl,cn
mov ah,02h
int 21h
jmp exit
disp1:print msg3
exit:mov ah,4ch
int 21h
end start

最新更新