【问题标题】:Assembly division not working properly [duplicate]装配部门工作不正常[重复]
【发布时间】:2018-02-11 00:19:58
【问题描述】:

我正在为我的 CS 课程开发一个程序,该程序应该向用户询问数字,直到输入超出指定范围的数字,此时它将打印输入的数字数量、总和以及平均值。我已经把所有这些都写出来了,但是平均值给了我非常奇怪的数字,我真的很难找到解决方案。 这是我的代码:

INCLUDE Irvine32.inc

LOWERLIMIT = -100
UPPERLIMIT = -1

.data

TextOne BYTE "Welcome to the Integer Accumulator" ,0
PromptOne BYTE "What is your name? " ,0
TextTwo BYTE "Hello, " ,0
TextThree BYTE "Please enter numbers in [-100, -1]." ,0
TextFour BYTE "Enter a non-negative number when you are finished to see results." ,0
PromptTwo BYTE "Enter number: " ,0
TextFive BYTE "You entered " ,0
TextSix BYTE " valid numbers" ,0
TextSeven BYTE "The sum of your valid numbers is " ,0
TextEight BYTE "The rounded average is " ,0
TextNine BYTE "Thank you for playing Integer Accumulator! It's been a pleasure to meet you, " ,0
TextTen BYTE "." ,0
NoNums BYTE "Looks like you didn't enter any valid numbers..." ,0

Username BYTE 33 DUP(0)

CurNum DWORD ?
NumNumbers DWORD 0
Sum DWORD 0
Average DWORD 0

.code
main PROC

;--Introduction--
    mov edx, OFFSET TextOne
    call WriteString
    call CrLf

;Get user's name
    mov edx, OFFSET PromptOne
    call WriteString
    mov edx, OFFSET UserName
    mov ecx, 32
    call ReadString

;print user's name
    mov edx, OFFSET TextTwo
    call WriteString
    mov edx, OFFSET UserName
    call WriteString
    call CrLf
    call CrLf

;print instructions
    mov edx, OFFSET TextThree
    call WriteString
    call CrLf
    mov edx, OFFSET TextFour
    call WriteString
    call CrLf

;--Main Loop--

Mainloop:

;get user input
    mov edx, OFFSET PromptTwo
    call WriteString
    call ReadInt
    mov CurNum, eax

;check upper bound
    mov eax, CurNum
    cmp eax, UPPERLIMIT
    jg Endloop

;check lower bound
    mov eax, CurNum
    cmp eax, LOWERLIMIT
    jl Endloop

;if number is valid, NumNumbers is incremented by 1 and CurNum is added to sum
    inc NumNumbers

    mov eax, CurNum
    add eax, Sum
    mov Sum, eax

;loops again
    jmp Mainloop





Endloop:

;checks if any valid numbers were entered, and if no valid numbers were entered, then prints message and skips to end
    mov eax, NumNumbers
    cmp eax, 0
    jg Valid
    mov edx, OFFSET NoNums
    call WriteString
    call CrLf
    jmp NoNumbers

Valid:





;--Results--

;Displays numbers of items
    mov edx, OFFSET TextFive
    call WriteString
    mov eax, NumNumbers
    call WriteDec
    mov edx, OFFSET TextSix
    call WriteString
    call CrLf

;Displays sum of numbers
    mov edx, OFFSET TextSeven
    call WriteString
    mov eax, Sum
    call WriteInt
    call CrLf

;--Compute average--
    mov edx, 0
    mov eax, Sum
    mov ebx, NumNumbers
    div ebx
    mov Average, eax

;Displays rounded average
    mov edx, OFFSET TextEight
    call WriteString
    mov eax, Average
    call WriteInt
    call CrLf

NoNumbers:

;Prints goodbye message
    mov edx, OFFSET TextNine
    call WriteString
    mov edx, OFFSET UserName
    call WriteString
    mov edx, OFFSET TextTen
    call WriteString
    call CrLf




    exit    ; exit to operating system
main ENDP

; (insert additional procedures here)

END main

这个片段给了我这个问题:

    ;--Compute average--
    mov edx, 0
    mov eax, Sum
    mov ebx, NumNumbers
    div ebx
    mov Average, eax

例如,我将输入-1 3次,然后输入1,它会输出4294967295,而不是预期的平均值-1。

然后我也使用了 idiv 和 cdq,但我遇到了与上面相同的问题,输出相同

;--Compute average--
    mov edx, 0
    mov eax, Sum
    cdq
    mov ebx, numNumbers
    idiv ebx
    mov Average, eax

非常感谢您的帮助,并提前感谢您的帮助!

【问题讨论】:

  • “奇怪的数字”不是一个好的错误描述。提供准确的输入、实际和预期的输出。另外,学习使用调试器。
  • div 肯定不支持负值,但idiv 变体在第一次阅读时看起来还不错,因此您必须使用调试器来确定哪个细节正在破坏它。 ..顺便说一句,您可以直接从内存中idiv,例如idiv dword ptr [numNumbers],如果您已经坚持将该值存储到内存中而不是一直将其保存在寄存器中。当然,这不会解决您的错误。当您以任何方式执行cdq 时,无需mov edx,0

标签: assembly x86 masm irvine32


【解决方案1】:

4294967295-12's complement 中具有相同的二进制表示,因此您的计算是正确的,但是您将其打印为无符号而不是有符号。

在 Irvine32 文档中搜索打印有符号整数的函数。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-05-18
    • 2017-06-10
    • 1970-01-01
    • 1970-01-01
    • 2017-12-05
    相关资源
    最近更新 更多