汇编子串判断代码异常求助:输入任意内容均输出三类提示
汇编子串判断程序问题排查
我写了一段汇编代码,用来判断输入的单词是不是输入字符串的子串。程序先读取键盘输入的字符串,再读取待判断的单词,但现在不管输入什么内容,输出始终是:“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
问题根源
- 执行流未终止:所有输出分支(
invalid_length、found_display、notfound_display)执行后,没有跳转到程序退出逻辑,会继续执行后续代码段,导致三个提示依次输出。 - 长度读取错误:获取子串长度时,
di已被偏移到InputWord+2,此时[di+1]读取的不是子串的实际长度值,而是输入内容的第三个字符。 - 代码顺序混乱:
valid分支后的匹配初始化代码位置错误,且未被正确执行。 - 缺少程序退出逻辑:没有调用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
相关产品推荐
相关产品推荐

