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

在EMU8086中借助recherchemax过程实现数组排序的问题排查

问题:使用recherchemax过程实现数组排序时内存移动操作异常

我尝试用recherchemax过程(用于查找数组最大值)实现数组排序,思路是每次找到最大值后将其放到正确位置,但发现相关内存移动指令无法正常工作,代码如下:

data segment
    tab db 30h,38h,35h,32h,37h,39h
    n dw 6
    max db ? 
    pos dw ?
ends

stack segment
    dw   128  dup(0)
ends

code segment
    recherchemax proc near
       mov di,0
       mov al,byte ptr tab[di]
       mov max,al
       mov pos,di
       inc di
       etq:
        mov al,byte ptr tab[di] 
        cmp al,max
        jbe negal  
        
        mov max,al
        mov pos,di
        negal:
        
        cmp di,n
        jae fin
        
        inc di
       jmp etq
        
    fin:    
    ret
start:
    mov ax, data
    mov ds, ax
    mov es, ax 
    
    mov cx,6
    mov si,offset tab
    boucle:
        call recherchemax
        mov al,max 
        add si,n 
        mov bl, byte ptr [si]
        mov byte ptr [si],al 
        mov si,0
        add si,pos
        mov byte ptr [si],bl 
        
        dec n      
    loop boucle
    
    mov ax, 4c00h 
    int 21h    
ends

end start 

问题原因及修复方案

1. 数组索引越界

原代码中add si,n会导致访问数组外的内存:si初始为tab的偏移地址,n初始值为6,而tab只有6个字节(下标0-5),offset tab + 6已经超出数组有效范围,会破坏未知内存区域的数据。

正确做法是定位到当前未排序部分的末尾,地址应为offset tab + n - 1。

2. 最大值查找的循环终止条件错误

recherchemax中cmp di,n后用jae fin,会导致最后一个元素(下标n-1)未被比较。应调整为inc di后再判断di是否小于n,确保遍历所有元素。

3. 交换逻辑冗余且错误

原交换逻辑绕路且因索引错误无法正确交换最大值和末尾元素,修复后直接定位两个位置的地址完成交换。

修复后的完整代码

data segment
    tab db 30h,38h,35h,32h,37h,39h
    n dw 6
    pos dw ?
ends

stack segment
    dw   128  dup(0)
ends

code segment
    recherchemax proc near
       mov di,0
       mov pos,di
       inc di
       etq:
        mov al,byte ptr tab[di] 
        cmp al,byte ptr tab[pos]
        jbe negal  
        
        mov pos,di
        negal:
        
        inc di
        cmp di,n
        jb etq
        
    fin:    
    ret
start:
    mov ax, data
    mov ds, ax
    mov es, ax 
    
    mov cx,6
    boucle:
        call recherchemax
        ; 定位未排序部分末尾地址
               mov bx, offset tab
        add bx, n
        dec bx
        ; 交换最大值位置和末尾位置的元素
        mov al, byte ptr tab[pos]
        mov dl, byte ptr [bx]
        mov byte ptr tab[pos], dl
        mov byte ptr [bx], al
        
        dec n      
    loop boucle
    
    mov ax, 4c00h 
    int 21h    
ends

end start 

额外优化

  • 移除了不必要的max变量,直接通过pos访问最大值元素,减少内存操作。
  • 简化了查找最大值的逻辑,直接比较当前元素和已记录最大值位置的元素,更高效。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.02 15:15:20