0

I tried writing my first, very simple program in Assembly. It is supposed to take two digits as input and perform addition, subtraction, multiplication and division on it. I currently do not care about how the program performs when you enter numbers like 5 and 5 (the sum and product of which wouldn't display correctly), cause I'm still learning, and will get to expanding the program further later. Right now, everything works like a charm, except division. When inputting 4 and 2, it, for example, returns the letter 'r' under the quotient. The code that should do this is:

;lastly, division

mov eax, SYS_WRITE
mov ebx, STDOUT
mov ecx, msg6
mov edx, len6
int 0x80

mov ax, [num1]
sub ax, '0'

mov ebx, [num2]
sub ebx, '0'

div ebx
add al, '0'

add ah, '0' ;in case there is a remainder

mov [quot], al
mov [rem], ah

mov eax, SYS_WRITE
mov ebx, STDOUT
mov ecx, quot
mov edx, 1
int 0x80

mov eax, SYS_WRITE
mov ebx, STDOUT
mov ecx, spacer
mov edx, len8
int 0x80

mov eax, SYS_WRITE
mov ebx, STDOUT
mov ecx, msg7
mov edx, len7
int 0x80

mov eax, SYS_WRITE
mov ebx, STDOUT
mov ecx, rem
mov edx, 1
int 0x80

Just for the record, msg6 is just the message: "The quotient is: " and msg7 is the message "The remainder is: ". num1 and num2 are the input numbers. spacer is my way of inputting spacing between the results. Thanks in advance!

Quantomic
  • 13
  • 3

1 Answers1

0
div   ebx

divides ebx by eax, and puts the remainder in edx. This is because ebx is a 4 byte divisor.

You seem to be expecting the remainder in ah. I believe you'll get what you want if you use

div   bl

since bl is a 1 byte divisor. For 1 byte divisors the result goes in al and the remainder in ah. See https://en.wikibooks.org/wiki/X86_Assembly/Arithmetic.

EDIT:

As some have mentioned, you must clear the destination for the remainder in advance, edx for the 4-byte case, and ah for the 1-byte case.

Codie CodeMonkey
  • 7,669
  • 2
  • 29
  • 45
  • From Intel 64 and IA-32 Architectures Software Developer’s Manual Volume 2: *DIV r/m32 [...] Unsigned divide EDX:EAX by r/m32, with result stored in EAX ← Quotient, EDX ← Remainder.* – EOF Aug 29 '16 at 20:37
  • I tried doing that, but now I get a `Floating Point Error` and the rest of the code does not execute. Again, testing on the case of numbers 4 and 2, so I don't see why there would be any floats involved. – Quantomic Aug 29 '16 at 20:53
  • As others have mentioned, you need to clear the high part of the dividend prior to the division. In the case of `div ebx` that would be `edx`, and in the case of `div bl` it would be `ah`. See _Intel® 64 and IA-32 Architectures Software Developer’s Manual_, which describes the `DIV` instruction and all other x86/x86-64 instructions. – Michael Aug 30 '16 at 08:42
  • Assuming I properly cleared the `ah` register (with `mov ah, 0h`), it's still not working. Although, I don't even see the need to clear the `ah` register because it's never set in the first place (unless the higher registers utilize it and my understanding is wrong). – Quantomic Aug 30 '16 at 08:52
  • It may be worth telling you that I defined `quot` in the .bss section as `quot resb 1`. – Quantomic Aug 30 '16 at 09:13
  • `ax` is made up of `al` and `ah`, and `eax` is made up of `ax` and 16 other bits. – Michael Aug 30 '16 at 09:27
  • I just realized my input numbers are two bytes, so I'm going to need to use the two byte DIV rule. One thing I still don't know is how to put the value of `num1` (the dividend) into both the `DX` and the `AX` registers. Can someone provide an explanation? – Quantomic Aug 30 '16 at 10:27
  • @CrAzYPiLoT: There isn't a separate signal for integer division exceptions. If it sends a signal at all, [POSIX requires it to be SIGFPE](http://stackoverflow.com/questions/37262572/on-which-platforms-does-integer-divide-by-zero-trigger-a-floating-point-exceptio). – Peter Cordes Aug 30 '16 at 23:41