我是汇编初学者,我正试图编写一个程序,我应该从键盘输入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, cx
ja invalid_length
指令(剃掉2字节)。如果减法产生借位,你就知道这个词比字符串长,这样你就可以分支了。是否跳转到invalid_length或notfound_display由您决定…如果您将
lea si, [InputString + 2]
lea di, [InputWord + 2]
替换为add si, 2
add 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