基于Irvine32.inc的汇编数组最大值求解异常问题求助
问题分析与解决方案
看起来你的汇编程序在处理包含负数的数组时,主要有几个关键问题导致最大值计算错误,我来一步步拆解并修正:
核心问题点
- 循环初始化错误:你在把第一个元素设为初始最大值后,仍然循环了
nb_temps次,这不仅会重复比较第一个元素,还可能在某些情况下导致逻辑混乱。 - 符号扩展与寄存器同步遗漏:你只在初始时将
ax符号扩展到eax,但后续更新ax(当前最大值)时没有同步更新eax,最后输出的eax还是第一个元素的初始值。 - 输出函数选错:
WriteDec是输出无符号十进制数的指令,如果最大值是负数,会被解析成超大的无符号数;而你需要处理正负数值,应该用WriteInt来输出有符号数。 - 16位寄存器的比较局限:用16位的
ax进行有符号数比较,容易出现符号扩展不彻底的问题,改用32位寄存器处理能更严谨地支持有符号数运算。
修正后的代码
FindGreatest: mov ebx, offset CTEMPS ; 指向数组首元素 mov ecx, nb_temps ; 元素总数 cmp ecx, 0 ; 处理空数组的边界情况 je NoElements ; 数组为空时跳转到提示 ; 初始化最大值:取第一个元素并符号扩展为32位 mov ax, [ebx] movsx eax, ax add ebx, 2 ; 移动到下一个元素 dec ecx ; 循环次数减1(已处理第一个元素) jz EndFindLoop ; 如果只有一个元素,直接结束循环 FindLoop: ; 取出当前元素并符号扩展为32位 mov ax, [ebx] movsx edx, ax ; 比较当前最大值与当前元素(均为32位有符号数) cmp eax, edx jge FindCont ; 当前最大值更大,跳过更新 mov eax, edx ; 更新最大值为当前元素 FindCont: add ebx, 2 ; 移动到下一个元素 loop FindLoop ; 循环直到所有元素处理完毕 EndFindLoop: mov edx, offset HiMsg call writestring call WriteInt ; 使用有符号数输出指令 jmp FindDone NoElements: mov edx, offset EmptyMsg call writestring FindDone:
针对你的测试用例的执行流程
对于数组[6,9,-2,10],修正后的代码会按以下步骤运行:
- 初始最大值设为6(符号扩展到
eax) - 比较6和9,更新最大值为9
- 比较9和-2,9作为有符号数更大,不更新
- 比较9和10,更新最大值为10
- 用
WriteInt输出10,完全符合你的预期
内容的提问来源于stack exchange,提问作者dragon
相关产品推荐
相关产品推荐

