You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

汇编子串判断代码异常求助:输入任意内容均输出三类提示

汇编子串判断程序问题排查

我写了一段汇编代码,用来判断输入的单词是不是输入字符串的子串。程序先读取键盘输入的字符串,再读取待判断的单词,但现在不管输入什么内容,输出始终是:“Invalid. Word found. Word not found.”。我已经添加了子串长度大于主串时输出“invalid”的判断逻辑,但问题仍未解决。

原代码

.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



found_display:
mov dx, offset found
mov ah, 09h
int 21h



notfound_display:
mov dx, offset notfound
mov ah, 09h
int 21h



end start

问题根源

  1. 执行流未终止:所有输出分支(invalid_length、found_display、notfound_display)执行后,没有跳转到程序退出逻辑,会继续执行后续代码段,导致三个提示依次输出。
  2. 长度读取错误:获取子串长度时,di已被偏移到InputWord+2,此时[di+1]读取的不是子串的实际长度值,而是输入内容的第三个字符。
  3. 代码顺序混乱:valid分支后的匹配初始化代码位置错误,且未被正确执行。
  4. 缺少程序退出逻辑:没有调用DOS中断退出程序,导致程序执行完输出后会跑入未知代码。

修复后的代码

.model small
.stack 200h
.data
     prompt1 db "Input String: $"
     prompt2 db 10,13, "Input Word: $"
     found db "Word Found. $"
     notfound db "Word Not Found. $"
     invalid db "Invalid. $"
     InputString db 21,?,21 dup("$")  
     InputWord db 21,?,21 dup("$")

.code
start:
      mov ax, @data
      mov ds, ax
      mov es, ax

     ; 获取输入字符串
     mov ah,09h
     lea dx, prompt1
     int 21h

     lea si, InputString
     mov ah, 0Ah
     mov dx, si
     int 21h

     ; 获取输入单词
     mov ah,09h
     lea dx, prompt2
     int 21h

     lea di, InputWord
     mov ah, 0Ah
     mov dx, di
     int 21h

     ; 检查子串长度是否大于主串
     mov cl, [InputString + 1]  ; 直接从主串结构读取实际长度
     mov ch, 0
     mov bx, 0
     mov bl, [InputWord + 1]    ; 直接从子串结构读取实际长度
     cmp bx, cx
     ja invalid_length          ; 子串更长,输出invalid
     je check_full_match        ; 长度相等,直接全串比较
     ; 子串更短,初始化匹配参数
     mov bp, cx
     sub bp, bx
     inc bp                     ; 计算最大匹配尝试次数
     lea si, [InputString + 2]
     lea di, [InputWord + 2]
     jmp matching

check_full_match:
     lea si, [InputString + 2]
     lea di, [InputWord + 2]
     cld
     repe cmpsb
     je found_display
     jmp notfound_display

matching:
    mov al, [si]
    cmp al, [di]
    je check
continue:  
    inc si
    dec bp
    jnz matching
    jmp notfound_display

check:
    push si
    push di
    mov cx, bx
    cld
    repe cmpsb
    pop di
    pop si
    jne continue
    jmp found_display

invalid_length:
     mov ah, 09h
     lea dx, invalid
     int 21h
     jmp exit_program  ; 输出后直接退出

found_display:
mov dx, offset found
mov ah, 09h
int 21h
jmp exit_program  ; 输出后退出

notfound_display:
mov dx, offset notfound
mov ah, 09h
int 21h
jmp exit_program  ; 输出后退出

exit_program:
mov ah, 4Ch  ; DOS程序退出中断
int 21h

end start

修复说明

  • 添加退出逻辑:每个输出分支后都跳转到exit_program,调用int 21h的4Ch功能终止程序,避免执行后续代码。
  • 修正长度读取:直接通过InputString+1和InputWord+1读取输入的实际长度,规避寄存器偏移导致的错误。
  • 调整代码顺序:将匹配初始化代码移到正确位置,确保matching分支执行前参数已正确设置。
  • 优化换行符:把prompt2中的重复换行符10,10,13改为标准的10,13,避免多余换行。

内容的提问来源于stack exchange,提问作者Ana Camen

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.04 10:55:21