1

As the title suggests, I have trouble dividing in assembly. The user inputs 4 grades and the program suppose to get an average. The program will print the correct result if the sum of the four grades happen to be divisible by 4. It will output a big number when it is not. The code uses C for it's output. How do I fix this error? Here is the code.

.586
.MODEL FLAT

INCLUDE io.h            ; header file for input/output

.STACK 4096

.DATA
 g1   DWORD   ?
 g2   DWORD   ?
 g3   DWORD   ?
 g4   DWORD   ?
 jj   BYTE  4
 prompt1 BYTE    "Enter grade 1", 0     
 prompt2 BYTE    "Enter grade 2", 0
 prompt3 BYTE    "Enter grade 3", 0
 prompt4 BYTE    "Enter grade 4", 0
 string  BYTE    40 DUP (?)
 resultLbl BYTE  "The average is", 0
 sum     BYTE    11 DUP (?), 0
 sum2    BYTE    11 DUP (?), 0

  .CODE
  MainProc PROC
        input   prompt1, string, 40      ; read ASCII characters
        atod    string          ; convert to integer
        mov     g1, eax    ; store in memory

        input   prompt2, string, 40      ; repeat for second number
        atod    string
        mov g2, eax

        input prompt3, string, 40        ;Repeat for third character
        atod string
        mov g3, eax

        input prompt4, string, 40        ;Repeat for third character
        atod string
        mov g4, eax

        mov eax, g1
        add eax, g2
        add eax, g3
        add eax, g4


       div jj


       dtoa    sum, eax        ; convert to ASCII characters
       output  resultLbl, sum         ; output label and sum

       mov     eax, 0  ; exit with return code 0
       ret
  _MainProc ENDP
  END                             ; end of source code
Michael Petch
  • 46,082
  • 8
  • 107
  • 198
Brody Gore
  • 77
  • 2
  • 11
  • 1
    `jj` is defined as a byte with value 4 (with `jj BYTE 4`). MASM will use 16 bit division by 8 bit division to perform `div jj` because you defined `jj` as a BYTE.. _AX_ is divided the byte at memory location `jj` (which is the value 4) and the quotient is stored in _AL_ and remainder in _AH_ . When the remainder is not zero then the value in AH is non zero and yields a larger value if you try to print out _EAX_ – Michael Petch Oct 10 '18 at 00:22
  • 1
    After you do the division you could do `MOVZX EAX, AL` to zero extend the value in _AL_ (the quotient) across the entire 32-bit register _EAX_ . That is assuming you don't care about the remainder that was stored in _AH_. – Michael Petch Oct 10 '18 at 00:26
  • 1
    It would be more normal do do 32-bit division since you're summing with 32-bit EAX. `xor edx,edx` / `div`. [8086 assembly on DOSBox: Bug with idiv instruction?](https://stackoverflow.com/a/43575674). Of course, your divisor is 4, so you should just `shr eax, 2`. – Peter Cordes Oct 10 '18 at 00:34
  • Both worked, I just moved 0 to AH and it fixed it. Thanks guys – Brody Gore Oct 10 '18 at 00:37

0 Answers0