emu8086汇编中如何正确比较字符串字符?程序恒真问题求解
汇编程序字符比较问题的修复方案
核心问题分析
- 跳转逻辑错误:
je same仅在字符相等时跳转到same标签,但不相等时程序会直接执行same中的代码(因为same紧跟在je之后,无分支跳过逻辑),导致无论字符是否匹配都会执行输出,看起来像比较条件始终为真。 - 输入缓冲区格式错误:DOS中断
int 21h 0Ah要求输入缓冲区是连续结构:第1字节为最大允许输入长度,第2字节为DOS自动填充的实际输入长度,第3字节开始存储输入字符串。你当前将长度字节和字符串存储区分开定义,会导致DOS覆盖字符串数组的起始字节,破坏数据。 - 循环逻辑冗余:固定循环255次,未判断字符串结束标志,会遍历到无效的
$字符,产生多余输出。
修复后的代码
name test .model small .stack 100h .data wrd_ask db "word: $" string_ask db "string: $" ; 正确定义输入缓冲区:最大长度 + 实际长度 + 字符存储区 s_buffer db 255, 0, 256 dup('$') w_buffer db 255, 0, 256 dup('$') .code macro convert buffer push ax push dx lea dx, buffer mov ah, 0Ah int 21h ; 将输入末尾的回车符替换为$,统一字符串结束标志 mov cl, buffer+1 mov ch, 0 mov byte ptr [buffer+2+cx], '$' pop dx pop ax endm start: mov ax, @data mov ds, ax mov dx, offset string_ask mov ah, 09h int 21h convert s_buffer mov dx, offset wrd_ask mov ah, 09h int 21h convert w_buffer mov si, 0 mov di, 0 ; 用实际输入长度设置循环次数,避免无效遍历 mov cl, s_buffer+1 mov ch, 0 mov cx, cx cycle: mov al, s_buffer[2+si] ; 取原字符串当前字符 mov bl, w_buffer[2+di] ; 取待匹配单词当前字符 cmp al, '$' je exit_loop ; 原字符串结束,提前退出循环 cmp al, bl je same_char ; 字符相等时执行输出 jmp next_char ; 不相等则跳过输出 same_char: mov dl, bl mov ah, 02h int 21h inc di ; 匹配单词指针后移 next_char: inc si ; 原字符串指针后移 LOOP cycle exit_loop: ; 程序正常退出 mov ah, 4Ch int 21h end start
关键修复说明
- 输入缓冲区修正:合并长度字节与字符串存储区,确保DOS输入中断正确写入数据,同时将回车符替换为
$,统一字符串结束标志。 - 分支逻辑修复:添加
jmp next_char跳过不相等时的输出操作,只有字符匹配时才执行输出,实现正确的条件判断。 - 循环优化:使用实际输入长度作为循环次数,同时判断
$结束符提前退出,避免无效遍历。
内容的提问来源于stack exchange,提问作者user20586260
相关产品推荐
相关产品推荐

