You need to enable JavaScript to run this app. 8086汇编列表唯一值提取宏未生效,输出与原列表一致问题排查
优惠活动
大模型
产品
解决方案
定价
更多

8086汇编列表唯一值提取宏未生效,输出与原列表一致问题排查

8086去重汇编程序故障排查与修复方案

核心故障定位

  • 输出逻辑存在硬错误:主程序中mov dx,offset di是非法写法。offset操作符仅能获取内存标号的段内偏移,无法应用在寄存器DI上。这行代码实际运行时无法正确加载目标字符串list2的起始地址,会导致DOS中断输出时访问到原列表list1的地址区间,最终输出内容和原列表完全一致。
  • 目标列表存储存在空隙:在存储最后一个有效元素后,inc di会移动到下一个位置,之后判断到SI指向字符串结束符$时,会先执行一次inc di再存入结束符,导致目标列表中在最后一个有效元素和结束符之间出现1个未初始化的随机字节,输出时会出现乱码。
  • 标志位逻辑存在冗余路径:当前CX标志仅用来标记“是否碰到过匹配项”,虽然能正确区分自身位置匹配和重复匹配,但在触发第二次匹配时直接跳转,没有终止BX的遍历流程,会无意义延长扫描路径。

修复后代码

修正后的宏实现

调整结束符存储位置消除空隙,移除无效寄存器操作:

uniqueElement macro list1 list2
    local loop1,comparasionLabel,checkFlag,trigger,nextElement,addElement,endAddition
    lea si,list1
    lea di,list2 
loop1:
    mov cx,00H   ; 初始化重复标志:0=未碰到过匹配
    lea bx,list1  ; 从列表起始位置开始扫描
    mov al,BYTE PTR[SI] 
    cmp al,'$'  ; 碰到结束符则退出循环
        je endAddition
comparasionLabel:
    mov dl,BYTE PTR[BX]
    cmp dl,'$'  ; 扫描到列表结尾,说明没有第二次匹配,保留当前元素
        je addElement
    cmp al,dl
        je checkFlag
    inc bx
    jmp comparasionLabel    
            
checkFlag:           
    ; 第一次碰到匹配:置标志位,继续扫描后续元素,看是否存在第二次匹配
    cmp cx,00H    
        je trigger
    ; 已经是第二次碰到匹配:当前元素重复,跳过
    cmp cx,01H       
        je nextElement     
trigger:
    mov cx,01H
    inc bx
    jmp comparasionLabel
nextElement:
    inc si
    jmp loop1
addElement:
    mov BYTE PTR [di],al
    inc di
    inc si
    jmp loop1        
        
endAddition:
    ; 直接在当前di位置存入结束符,消除存储空隙
    mov al,'$'
    mov BYTE PTR[di],al               
endm

修正后的主程序

替换错误的输出地址加载逻辑:

.model small
.data
list1 db 'H3llo$'    
list2 db 50 DUP [?]
.code  
mov ax,@data
mov ds,ax
uniqueElement list1 list2
; 加载目标列表的起始偏移用于输出
mov ah,09H
mov dx,offset list2
int 21h

.exit

修复后效果

针对示例输入H3llo$(包含两个重复的小写l),程序会输出去重后的字符串H3lo$,完全符合唯一元素留存的预期。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.25 20:06:10