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

NASM 16位DOS COM程序:数组比较结果始终异常的问题排查

问题分析与修复:DOS .COM程序数组比较始终输出"Differ"

核心问题

1. 数组长度读取错误

你定义的n是字节类型(db 5),但用16位寄存器CX直接读取:mov cx, [n]。这会一次性读取n和紧随其后的1个字节(也就是array1第一个元素的低字节01),导致CX的值变成0105h而非预期的0005h。后续shr cx,1得到的循环次数完全错误,循环执行的次数远超过实际需要的2次,最终必然触发不相等的判断。

2. 循环与判断逻辑不匹配

原代码使用loopz指令,它的执行逻辑是:先将CX减1,再判断CX≠0且ZF=1(上一次比较相等)时才继续循环。循环结束后用jnz print_differ判断,但此时ZF的状态可能因为CX减到0而保留上一次比较的结果,逻辑容易混乱,导致错误跳转。

修复后的代码

use16
org 100h

start:
    mov si, 2          ; array1奇数索引起始偏移(对应索引1)
    mov di, 0          ; array2偶数索引起始偏移(对应索引0)
    mov cl, [n]        ; 读取字节长度到CL
    xor ch, ch         ; 将CX扩展为16位,值为5
    shr cx, 1          ; 计算需要比较的次数:5//2=2
    jz print_match     ; 无比较项直接输出匹配

comparison_loop:
    mov ax, [array1 + si]
    cmp ax, [array2 + di]
    jne print_differ   ; 一旦发现不相等,直接跳转输出结果
    add si, 4          ; 移动到下一个奇数索引(每个DW占2字节,索引+2对应偏移+4)
    add di, 4          ; 移动到下一个偶数索引
    loop comparison_loop ; 循环直到CX为0

print_match:
    mov dx, msg_match
    jmp print

print_differ:
    mov dx, msg_differ

print:
    mov ah, 09h
    int 21h

exit:
    mov ax, 4C00h
    int 21h

n db 5
array1 dw 1, 2, 3, 4, 5
array2 dw 2, 0, 4, 0, 0
msg_match db 'Match.$'
msg_differ db 'Differ.$'

修复说明

  • 修正长度读取:用mov cl, [n]读取字节长度,再用xor ch, ch将CX扩展为正确的16位值,确保循环次数准确。
  • 简化判断逻辑:去掉loopz,改用jne在发现不相等时直接终止流程,逻辑更直观;所有比较完成后自动进入print_match,避免了循环后复杂的标志位判断。
  • 保持索引逻辑正确:原代码中si和di的偏移计算是正确的(每个DW元素占2字节,奇数索引/偶数索引每次跳过一个元素,对应偏移+4),保留了这部分逻辑。

内容的提问来源于stack exchange,提问作者Muhab Joumaa

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.13 00:23:17