负整数统计值显示异常修复求助:Min/Max/Sum/Average计算错误
问题修复:负整数统计值显示为无符号大数的问题
问题根源
- 输出函数误用:你用
WriteDec输出有符号整数(SDWORD类型的sum、max、min、average),但WriteDec是按无符号十进制数解析输出的,负数的补码会被当成超大无符号数(比如-40的32位补码0xFFFFFFD8会被显示为4294967256)。 - 最小值初始化错误:
numMin初始值设为UPPER_BOUND1(-100),但第二个输入区间[-50, -1]的数(如-10)比-100大,不会触发最小值更新,导致最终最小值错误。
修复步骤
- 替换输出函数:所有需要显示有符号整数的位置,把
WriteDec换成WriteInt(Irvine32库专门用于输出有符号十进制数的函数)。 - 修正最小值初始化:将
numMin初始值改为UPPER_BOUND2(-1)——这是所有有效输入的最大值,确保第一个有效输入会触发最小值更新,后续更小的数也能正确更新最小值。 - 保留整数平均值逻辑:你的需求是整数平均值,当前用
idiv处理有符号数除法的逻辑正确,不需要将numAverage改为float类型。
修复后的完整代码
INCLUDE Irvine32.inc .data titleMsg BYTE "Welcome to the Integer Accumulator by ", 0 myName BYTE "John", 0 progMsg BYTE "We will be accumulating user-input negative integers between the specified bounds, then displaying statistics of the ", 0 progMsg2 BYTE "input values including minimum, maximum, and average values values, total sum, and total number of valid inputs.", 0 namePrompt BYTE "What is your name? ", 0 greetMsg BYTE "Hello there, ", 0 instruction BYTE "Please enter numbers in [-200, -100] or [-50, -1].", 0 instruction2 BYTE "Enter a non-negative number when you are finished, and input stats will be shown.", 0 invalidMsg BYTE "This is not a number we're looking for (Invalid Input)!", 0 inputPrompt BYTE "Enter number: ", 0 statsMsg BYTE "You entered ", 0 validMsg BYTE " valid numbers.", 0 maxMsg BYTE "The maximum valid number is ", 0 minMsg BYTE "The minimum valid number is ", 0 sumMsg BYTE "The sum of your valid numbers is ", 0 avgMsg BYTE "The rounded average is ", 0 farewellMsg BYTE "We have to stop meeting like this. Farewell, ", 0 specialMsg BYTE "Congratulations, you found an Easter Egg!", 0 SUM_LIMIT EQU 1000 ; Limit for the sum of numbers entered ; Constants for value limits LOWER_BOUND1 EQU -200 UPPER_BOUND1 EQU -100 LOWER_BOUND2 EQU -50 UPPER_BOUND2 EQU -1 ; Variables userName BYTE 50 DUP (?) inputNumber SDWORD ? validCount DWORD ? numSum SDWORD ? numMax SDWORD ? numMin SDWORD ? numAverage SDWORD ? signFlag BYTE ? .code main PROC ; Display program title and programmer's name mov edx, OFFSET titleMsg call WriteString mov edx, OFFSET myName call WriteString call Crlf ; Display program description mov edx, OFFSET progMsg call WriteString call Crlf mov edx, OFFSET progMsg2 call WriteString call Crlf ; Get the user's name and greet the user mov edx, OFFSET namePrompt call WriteString mov edx, OFFSET userName mov ecx, SIZEOF userName ; 修正:避免限制用户名输入长度 call ReadString mov edx, OFFSET greetMsg call WriteString mov edx, OFFSET userName call WriteString call Crlf call Crlf ; Display instructions mov edx, OFFSET instruction call WriteString call CrLf mov edx, OFFSET instruction2 call WriteString call CrLf ; Initialize variables mov numSum, 0 mov validCount, 0 mov numMax, LOWER_BOUND1 ; 初始化为最小允许值,确保首个有效输入更新最大值 mov numMin, UPPER_BOUND2 ; 修正:初始化为最大允许值,确保首个有效输入更新最小值 ; User input loop inputLoop: ; Prompt user to enter a number mov edx, OFFSET inputPrompt call WriteString call ReadInt mov inputNumber, eax ; Check if the number is non-negative test eax, eax jns checkSpecialMessage ; Check if the number is within the specified ranges cmp inputNumber, LOWER_BOUND1 jl invalidInput cmp inputNumber, UPPER_BOUND1 jg checkSecondRange jmp validInput checkSecondRange: cmp inputNumber, LOWER_BOUND2 jl invalidInput cmp inputNumber, UPPER_BOUND2 jg invalidInput jmp validInput invalidInput: ; Notify user of invalid input mov edx, OFFSET invalidMsg call WriteString call CrLf jmp inputLoop validInput: ; Update count and sum of valid numbers inc validCount mov eax, inputNumber ; Move inputNumber into eax register add numSum, eax ; Add eax (inputNumber) to numSum ; Update max and min valid numbers mov eax, numMax ; Move numMax into eax register cmp inputNumber, eax ; Compare inputNumber with eax (numMax) jle notMax mov eax, inputNumber ; Move inputNumber into eax register mov numMax, eax ; Move eax (inputNumber) to numMax notMax: mov eax, numMin ; Move numMin into eax register cmp inputNumber, eax ; Compare inputNumber with eax (numMin) jge notMin mov eax, inputNumber ; Move inputNumber into eax register mov numMin, eax ; Move eax (inputNumber) to numMin notMin: jmp inputLoop checkSpecialMessage: ; Check if any valid inputs were received cmp validCount, 0 je displaySpecialMessage ; If no valid inputs were received, display special message jmp displayStats ; If valid inputs were received, display statistics displaySpecialMessage: ; Display special message mov edx, OFFSET specialMsg call WriteString call CrLf jmp exitProgram ; 新增:避免执行统计代码 displayStats: ; Calculate the rounded average mov eax, numSum cdq idiv validCount mov numAverage, eax ; Display statistics mov edx, OFFSET statsMsg call WriteString mov eax, validCount call WriteDec mov edx, OFFSET validMsg call WriteString call CrLf mov edx, OFFSET sumMsg call WriteString mov eax, numSum call WriteInt ; 替换为有符号输出函数 call CrLf mov edx, OFFSET maxMsg call WriteString mov eax, numMax call WriteInt ; 替换为有符号输出函数 call CrLf mov edx, OFFSET minMsg call WriteString mov eax, numMin call WriteInt ; 替换为有符号输出函数 call CrLf mov edx, OFFSET avgMsg call WriteString mov eax, numAverage call WriteInt ; 替换为有符号输出函数 call CrLf exitProgram: ; Display farewell message with the user's name mov edx, OFFSET farewellMsg call WriteString mov edx, OFFSET userName call WriteString exit main ENDP END main
额外修正说明
- 新增
exitProgram标签:修复逻辑分支错误,避免显示特殊消息后执行统计代码。 - 修正用户名输入长度:将输入长度限制改为
SIZEOF userName,允许用户输入正常长度的名字。
验证输出
输入-10、-30、0后,输出会符合预期:
You entered 2 valid numbers. The sum of your valid numbers is -40 The maximum valid number is -10 The minimum valid number is -30 The rounded average is -20 We have to stop meeting like this. Farewell, John
内容的提问来源于stack exchange,提问作者user23372697
相关产品推荐
相关产品推荐

