String 在输入字符串中查找子字符串
我有一个汇编程序,需要在输入的主字符串中找到子字符串。我的问题是,即使我输入了两个完全不同的单词,它也总是输出“word found”。我不知道我的循环或条件的哪一部分是错误的。请帮我弄清楚。另外,请提供一些字符串指令,用于检查子字符串,以便缩短代码。我真的对cmpsb的工作原理感到困惑,我只是试着使用它。顺便说一句,我不知道如何使用调试器,这就是为什么我不能调试我的代码,我只是一个汇编语言新手 下面是我代码的逻辑部分String 在输入字符串中查找子字符串,string,assembly,x86-16,strstr,String,Assembly,X86 16,Strstr,我有一个汇编程序,需要在输入的主字符串中找到子字符串。我的问题是,即使我输入了两个完全不同的单词,它也总是输出“word found”。我不知道我的循环或条件的哪一部分是错误的。请帮我弄清楚。另外,请提供一些字符串指令,用于检查子字符串,以便缩短代码。我真的对cmpsb的工作原理感到困惑,我只是试着使用它。顺便说一句,我不知道如何使用调试器,这就是为什么我不能调试我的代码,我只是一个汇编语言新手 下面是我代码的逻辑部分 .data prompt1 db "Input String: $
.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 ?
strlen dw ($-InputWord)
.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, cx
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
matching:
mov al, [si]
mov ah, [di]
cmp al, ah
je check
jne iterate
iterate:
inc si
mov dx, strlen
dec dx
cmp dx, 0
je notfound_display
jmp matching
check:
mov cl, [di+1]
mov ch, 0
mov ax, si
add ax, 1
cld
repe cmpsb
jne again
jmp found_display
again:
mov si, ax
dec dx
lea di, InputWord
jmp matching
invalid_length:
mov ah, 09h
lea dx, invalid
int 21h
这没有任何用处。它计算的长度对你没有任何帮助
这里(正如Jester告诉您的那样)addsi,cx
指令是错误的。您需要add si,2
将si
设置为字符串的开头。您还需要添加adddi,2
以将di
设置为单词的开头。执行此操作,程序的有效部分将正常工作
对于匹配部件: 假设字符串有7个字符,而您要查找的单词有6个字符。你最多可以用两种方式找到这个词 假设字符串有8个字符,而您要查找的单词有6个字符。你最多可以用三种方式找到这个词 假设字符串有9个字符,而您要查找的单词有6个字符。你最多可以用4种方式找到这个词 注意到规律了吗?可能找到的数量等于长度差加1
mov bp, cx ;CX is length string (long)
sub bp, bx ;BX is length word (short)
inc bp
这将BP
设置为匹配例程中的尝试次数
检查部分将使用repe cmpsb
测试匹配项,但如果未找到匹配项,则必须能够在continue标签上返回到匹配的代码。你必须保留登记册
check:
push si
push di
mov cx, bx ;BX is length of word
repe cmpsb
pop di
pop si
jne continue
jmp found_display
“我不知道如何使用调试器”学习它!我们也不是生来就知道这一点的。事实上,这应该是第一步。鉴于这是dos代码,具有基于文本的菜单系统的turbo debugger应该需要大约2分钟的学习时间。总之,
add si,cx
真的很可疑。由于您还没有对它进行注释,所以不清楚您到底想用它做什么。使用调试器是学习汇编语言的一个很好的方法。
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