求助: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
问题排查
- 栈操作错误:调用
addev时已使用ret 2自动清理2字节参数,原代码额外执行pop [di]会导致栈指针异常,破坏后续执行逻辑。 - 寄存器冲突:
maxArray用ch保存当前最大偶数字和,但addev会修改ch作为累加器,调用后ch值被覆盖,无法正确比较。 - 计数逻辑缺陷:用8位寄存器
cl与16位的N比较,若数组长度超过255会出错,应使用完整的16位cx寄存器计数。 - 元素指针错误:在
inc di之后才修改si,导致si指向的是下一个元素而非当前处理的元素,最终返回错误值。 - 相等情况逻辑混乱:
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
修改说明
- 移除多余栈操作:删除
pop [di],依赖addev的ret 2自动清理参数,避免栈错误。 - 分离寄存器用途:用
dh保存当前最大偶数字和,避免与addev使用的ch冲突。 - 修正计数逻辑:使用16位寄存器
cx存储数组长度,遍历过程中递减cx直到0,兼容更大的数组长度。 - 调整指针顺序:在移动元素指针前更新
si,确保指向当前处理的元素。 - 明确相等处理规则:当两个元素的偶数字和相等时,选择数值更大的元素,逻辑清晰可追溯。
- 初始化优化:先处理第一个元素,初始化最大和与指针,避免遍历初期的无效比较。
内容的提问来源于stack exchange,提问作者P.I.S
相关产品推荐
相关产品推荐

