Warning: file_get_contents(/data/phpspider/zhask/data//catemap/0/assembly/5.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
String 在输入字符串中查找子字符串_String_Assembly_X86 16_Strstr - Fatal编程技术网

String 在输入字符串中查找子字符串

String 在输入字符串中查找子字符串,string,assembly,x86-16,strstr,String,Assembly,X86 16,Strstr,我有一个汇编程序,需要在输入的主字符串中找到子字符串。我的问题是,即使我输入了两个完全不同的单词,它也总是输出“word found”。我不知道我的循环或条件的哪一部分是错误的。请帮我弄清楚。另外,请提供一些字符串指令,用于检查子字符串,以便缩短代码。我真的对cmpsb的工作原理感到困惑,我只是试着使用它。顺便说一句,我不知道如何使用调试器,这就是为什么我不能调试我的代码,我只是一个汇编语言新手 下面是我代码的逻辑部分 .data prompt1 db "Input String: $

我有一个汇编程序,需要在输入的主字符串中找到子字符串。我的问题是,即使我输入了两个完全不同的单词,它也总是输出“word found”。我不知道我的循环或条件的哪一部分是错误的。请帮我弄清楚。另外,请提供一些字符串指令,用于检查子字符串,以便缩短代码。我真的对cmpsb的工作原理感到困惑,我只是试着使用它。顺便说一句,我不知道如何使用调试器,这就是为什么我不能调试我的代码,我只是一个汇编语言新手

下面是我代码的逻辑部分

.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