Finding the substring in an input string

谁说我不能喝 提交于 2021-01-27 23:12:38

问题


I have this assembly program where I need to find the substring in the main string I input. My problem is that it always outputs the "word found" even if I typed two completely different words. I don't know which part of my loop or condition is wrong. Please help me figure it out. Also, please suggest some string instructions that could be used in checking for a substring so that I can shorten my code. I am really confused with how the cmpsb works, I only tried to use it. Btw, I don't know how to use a debugger that's why I can't debug my code and I am just a newbie in assembly language.

Below is the logic part of my code.

.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

回答1:


strlen dw ($-InputWord)

This does nothing useful. The length that it calculate can not help you in any way!

;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

Here (as Jester told you) the add si, cx instruction is wrong. You need add si, 2 to set SI to the start of the string. You will also need to add add di, 2 to set DI to the start of the word. Do this and the valid part of your program will work correctly.


For the matching part:

Consider the case where the string has 7 characters and the word that you're looking for has 6 characters. You can find the word in at most 2 ways.

Consider the case where the string has 8 characters and the word that you're looking for has 6 characters. You can find the word in at most 3 ways.

Consider the case where the string has 9 characters and the word that you're looking for has 6 characters. You can find the word in at most 4 ways.

Notice the regularity? The number of possible finds is equal to the difference in length plus 1.

    mov     bp, cx      ;CX is length string (long)
    sub     bp, bx      ;BX is length word  (short)
    inc     bp

This sets BP to the number of tries in your matching routine.

    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

The check part will use repe cmpsb to test for a match, but in the event that the match is not found, you must be able to return to the matching code at the continue label. You have to preserve the registers.

check:
    push    si
    push    di
    mov     cx, bx     ;BX is length of word
    repe cmpsb
    pop     di
    pop     si
    jne     continue
    jmp     found_display


来源:https://stackoverflow.com/questions/47513958/finding-the-substring-in-an-input-string

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!