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

求助:x86汇编maxArray子程序实现问题(找偶数字和最大的字)

x86汇编maxArray子程序修正方案

这段x86汇编代码需要实现两个核心子程序:

  • addev:计算一个16位字(word)中所有偶数数字的和
  • maxArray:遍历输入的字数组,找出其中偶数字和最大的字,最终将该字存入AX寄存器返回

当前addev功能正常,但maxArray子程序存在多处逻辑错误,无法正确返回结果,以下是问题排查及修正后的完整内容。


原代码

.model small
.stack 100h
.data
A dw 1489, 32661, 31248, 24788, 13499, 28
N dw 6
.code
mov ax, @data
mov ds, ax
push offset A
push N
call maxArray


.exit
addev proc near
    push bp
    mov bp, sp
    mov ax, [bp + 4]
    mov bx, 10
    mov ch, 0
next:
    mov dx, 0
    div bx
    mov dh, dl
    and dl, 1
    jnz cont
    mov dl, dh
    mov dh, 0
    add ch, dl
cont:
    cmp ax, 0
    jne next
    mov al, ch
    mov bx,[bp+4]
    pop bp
    ret 2
addev endp

maxArray proc near
    push bp
    mov bp, sp
    mov bx, 0
    mov cx, 0
    mov di, [bp + 6]
    mov si, di 
next1:
    cmp cl, [bp + 4]
    je ext
    push [di]
    call addev
    pop [di]
    inc di
    inc di
    cmp ch, al
    ja cont2
    cmp ch, al
    jne check
    cmp bx, [si]
    jae cont2
    mov si, di
cont2:
    inc cl
    jmp next1
check:
    mov ch, al
    mov si, di
    jmp cont2
ext:
    mov ax, [si] 
    pop bp
    ret 4
maxArray endp
end

问题排查

  1. 栈操作错误:调用addev时已使用ret 2自动清理2字节参数,原代码额外执行pop [di]会导致栈指针异常,破坏后续执行逻辑。
  2. 寄存器冲突:maxArray用ch保存当前最大偶数字和,但addev会修改ch作为累加器,调用后ch值被覆盖,无法正确比较。
  3. 计数逻辑缺陷:用8位寄存器cl与16位的N比较,若数组长度超过255会出错,应使用完整的16位cx寄存器计数。
  4. 元素指针错误:在inc di之后才修改si,导致si指向的是下一个元素而非当前处理的元素,最终返回错误值。
  5. 相等情况逻辑混乱:bx初始为0,用来比较原数字大小的逻辑不成立,未明确偶数字和相等时的处理规则。

修正后的代码

.model small
.stack 100h
.data
A dw 1489, 32661, 31248, 24788, 13499, 28
N dw 6
.code
mov ax, @data
mov ds, ax
push offset A
push N
call maxArray


.exit
addev proc near
    push bp
    mov bp, sp
    mov ax, [bp + 4]
    mov bx, 10
    mov ch, 0
next:
    mov dx, 0
    div bx
    mov dh, dl
    and dl, 1
    jnz cont
    mov dl, dh
    mov dh, 0
    add ch, dl
cont:
    cmp ax, 0
    jne next
    mov al, ch          ; 偶数字和存入al返回
    pop bp
    ret 2               ; 自动清理栈上的2字节参数
addev endp

maxArray proc near
    push bp
    mov bp, sp
    mov cx, [bp + 4]    ; cx存数组长度,用于计数
    mov di, [bp + 6]    ; di指向当前数组元素
    mov si, di          ; si指向当前最大和的元素,初始为第一个元素
    mov dh, 0           ; dh保存当前最大偶数字和,初始为0

    ; 先计算第一个元素的偶数字和,初始化max值
    push [di]
    call addev
    mov dh, al          ; 保存第一个元素的和到dh
    add di, 2           ; 移动到下一个元素
    dec cx              ; 计数减1

next1:
    cmp cx, 0
    je ext              ; 遍历完成,退出

    ; 计算当前元素的偶数字和
    push [di]
    call addev

    ; 比较当前和与最大和
    cmp al, dh
    jb cont2            ; 当前和更小,跳过
    ja update_max       ; 当前和更大,更新最大值
    ; 和相等时,比较原数字大小,保留较大的
    cmp [di], [si]
    jbe cont2

update_max:
    mov dh, al          ; 更新最大和
    mov si, di          ; 更新最大元素的指针

cont2:
    add di, 2           ; 移动到下一个元素
    dec cx
    jmp next1

ext:
    mov ax, [si]        ; 将最大元素存入AX返回
    pop bp
    ret 4               ; 清理栈上的4字节参数(数组地址+长度)
maxArray endp
end

修改说明

  1. 移除多余栈操作:删除pop [di],依赖addev的ret 2自动清理参数,避免栈错误。
  2. 分离寄存器用途:用dh保存当前最大偶数字和,避免与addev使用的ch冲突。
  3. 修正计数逻辑:使用16位寄存器cx存储数组长度,遍历过程中递减cx直到0,兼容更大的数组长度。
  4. 调整指针顺序:在移动元素指针前更新si,确保指向当前处理的元素。
  5. 明确相等处理规则:当两个元素的偶数字和相等时,选择数值更大的元素,逻辑清晰可追溯。
  6. 初始化优化:先处理第一个元素,初始化最大和与指针,避免遍历初期的无效比较。

内容的提问来源于stack exchange,提问作者P.I.S

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.09 14:44:51