我在尝试显示用户输入的负整数的最小/最大、总和和平均值的正确值时遇到问题。当我运行代码并输入两个负值(-10 和 -30)时,结果如下(用户输入以粗体显示):
Welcome to the Integer Accumulator by John
We will be accumulating user-input negative integers between the specified bounds, then displaying statistics of the
input values including minimum, maximum, and average values values, total sum, and total number of valid inputs.
What is your name? **John**
Hello there, John
Please enter numbers in [-200, -100] or [-50, -1].
Enter a non-negative number when you are finished, and input stats will be shown.
Enter number: **-10**
Enter number: **-30**
Enter number: 0
You entered 2 valid numbers.
The sum of your valid numbers is 4294967256
The maximum valid number is 4294967286
The minimum valid number is 4294967196
The rounded average is 4294967276
We have to stop meeting like this. Farewell, John
您是否发现数字的总和、最小值、最大值和平均值都不正确?这就是我正在努力解决的问题。预期输出应该是:
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
这是下面的代码。我可能还需要将 numAverage 数据变量更改为浮点数,但我还没有测试它:
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 myName
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 ; Initialize to the smallest possible value
mov numMin, UPPER_BOUND1 ; Initialize to the largest possible value
; 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
; Display farewell message with the user's name
mov edx, OFFSET farewellMsg
call WriteString
mov edx, OFFSET userName
call WriteString
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 WriteDec
call CrLf
mov edx, OFFSET maxMsg
call WriteString
mov eax, numMax
call WriteDec
call CrLf
mov edx, OFFSET minMsg
call WriteString
mov eax, numMin
call WriteDec
call CrLf
mov edx, OFFSET avgMsg
call WriteString
mov eax, numAverage
call WriteDec
call CrLf
; 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
比较您的期望:
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
用你得到的:
The sum of your valid numbers is 4294967256 The maximum valid number is 4294967286 The minimum valid number is 4294967196 The rounded average is 4294967276
很明显您正在将这些带符号的结果作为无符号数字输出。
仔细观察最小有效数字的值 4294967196 还可以发现,程序中的某个地方一定存在错误(因为 -30 应该显示为 4294967266)。
WriteDec
来输出 signed 32 位整数,而不是用于输出 unsigned32 位整数。您已将 numMin
但这不是最大可能值(尽管您在评论中说明了这一点)。真正最大的可能值是 UPPER_BOUND2 等式中的 -1,因此请使用以下命令更正它: mov numMax, LOWER_BOUND1 ;初始化为可能的最小值-200 mov numMin, UPPER_BOUND2 ;初始化为最大可能值-1
您过于频繁地使用基于内存的变量!
WriteInt
以复制粘贴的方式(你不会相信你会删掉多少字节):
mov inputNumber, eax
test eax, eax
jns checkSpecialMessage
cmp inputNumber, LOWER_BOUND1 cmp eax, LOWER_BOUND1
jl invalidInput
cmp inputNumber, UPPER_BOUND1 cmp eax, UPPER_BOUND1
jg checkSecondRange
jmp validInput
checkSecondRange:
cmp inputNumber, LOWER_BOUND2 cmp eax, LOWER_BOUND2
jl invalidInput
cmp inputNumber, UPPER_BOUND2 cmp eax, UPPER_BOUND2
jg invalidInput \ jng validInput
jmp validInput / ; else fall-through
invalidInput:
mov edx, OFFSET invalidMsg
call WriteString
call CrLf
jmp inputLoop
validInput:
inc validCount
mov eax, inputNumber Remove this, EAX still has inputNumber
add numSum, eax
mov eax, numMax Remove this, No need to load/clobber EAX
cmp inputNumber, eax Then write this as: cmp eax, numMax
jle notMax
mov eax, inputNumber Remove this, EAX still has inputNumber
mov numMax, eax
notMax:
mov eax, numMin Remove this, No need to load/clobber EAX
cmp inputNumber, eax Then write this as: cmp eax, numMin
jge notMin
mov eax, inputNumber Remove this, EAX still has inputNumber
mov numMin, eax
notMin:
jmp inputLoop