汇编子串匹配程序问题:输入后始终显示Invalid的解决方法
问题分析与代码修正
核心错误原因
- 长度读取逻辑错误:原代码先将
si和di移动到字符串内容区域,再尝试读取子串长度,此时[di+1]指向的是子串的第二个字符,而非存储长度的InputWord+1字节,导致bx存储的不是真实子串长度,比较时误判为子串更长,触发Invalid.。 - 代码执行路径错误:初始化匹配循环计数器
bp的代码被放在valid分支的跳转之后,永远无法被执行,导致后续匹配逻辑异常。
修改后的完整代码
.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 10,13,"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 dx, InputString mov ah, 0Ah int 21h ; 获取子串输入 mov ah,09h lea dx, prompt2 int 21h lea dx, InputWord mov ah, 0Ah int 21h ; 读取主串长度到CX,子串长度到BX mov cl, [InputString + 1] mov ch, 0 mov bl, [InputWord + 1] mov bh, 0 ; 判断子串长度是否大于主串 cmp bx, cx ja invalid_length je valid_length ; 子串更短,计算最大匹配尝试次数 mov bp, cx sub bp, bx inc bp ; 指向两个字符串的内容起始位置 lea si, InputString + 2 lea di, InputWord + 2 jmp matching valid_length: ; 长度相等,直接全串比较 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_match continue_search: inc si dec bp jnz matching jmp notfound_display check_match: push si push di mov cx, bx cld repe cmpsb pop di pop si jne continue_search jmp found_display invalid_length: mov ah, 09h lea dx, invalid int 21h jmp done found_display: mov ah, 09h lea dx, found int 21h jmp done notfound_display: mov ah, 09h lea dx, notfound int 21h done: mov ax,4C00h int 21h ; 退出程序返回DOS end start
关键修改点
- 调整长度读取顺序:先直接从
InputString+1和InputWord+1读取真实长度,再移动指针到字符串内容区域,确保cx和bx存储正确的长度值。 - 修正代码执行路径:将
bp的初始化逻辑移到matching分支之前,确保匹配循环能获取正确的计数器值。 - 优化跳转逻辑:将
valid分支的指针初始化提前,避免重复代码,同时修正prompt2的换行符(原代码用了两个10,改为标准的10,13)。
内容的提问来源于stack exchange,提问作者Ana Camen
相关产品推荐
相关产品推荐

