Author Topic: Simple word division doesn't work (divide overflow)  (Read 8613 times)

Offline isywum

  • Jr. Member
  • *
  • Posts: 38
Simple word division doesn't work (divide overflow)
« on: February 22, 2012, 01:53:37 PM »
Hi,

I have another problem with assembly.
This is my code.
Code: [Select]
org 0x100
start:
xor ax, ax
xor bx, bx
xor cx, cx
xor dx, dx
mov ax, 200
mov dx, 100
div dx
cmp ax, 2
je correct
jmp _end

correct:
mov si, _c
lodsb
mov bx, 0x07
mov ah, 0x0E
int 0x10
jmp _end

wrong:
mov si, _w
lodsb
mov bx, 0x07
mov ah, 0x0E
int 0x10
jmp _end

_end:
mov ah, 0x0
int 0x16
mov ah, 0x4C
int 0x21

_c db "c", 13, 10, 0
_w db "w", 13, 10, 0
There aren't any errors or warnigs but the application just shows: Divide overflow.

Thanks in advance!

Offline Frank Kotler

  • NASM Developer
  • Hero Member
  • *****
  • Posts: 2667
  • Country: us
Re: Simple word division doesn't work (divide overflow)
« Reply #1 on: February 22, 2012, 03:22:40 PM »
A 16-bit "div" divides dx:ax by a 16-bit register (or a 16-bit memory location). In other words, it divides a 32-bit number by a 16-bit number and gives a 16-bit result. (one of those instructions where the operands aren't all "showing"). If the result won't fit in ax, it causes a "divide overflow exception" (a CPU exception). The OS/emulator you're using does a good job reporting this! Dos used to say "divide by zero error" (no I didn't!), and Linux says "floating point exception" (floating point?!?!?). Highly confusing!

This will happen if the value in dx, before the "div" is equal to or greater than the value you're dividing by. So "div dx" is never going to work! I don't know why it's even a legal instruction... but it is. Use some other register, and I think it'll work.

Unless you intend to divide some number bigger than 64k, you want zero in dx before the "div". After the "div", the remainder is in dx, so if you're doing this in a loop you want to zero dx just before the "div", every time. Most people (almost everyone, it seems) run into this when they try the "display a number" routine. If they "add dx, '0'" to convert the number to a character before storing it, they get this exception. If they leave it for later, they just get incorrect results. A very common error!

Best,
Frank


Offline isywum

  • Jr. Member
  • *
  • Posts: 38
Re: Simple word division doesn't work (divide overflow)
« Reply #2 on: February 22, 2012, 04:46:29 PM »
Hi,

thanks for your reply! Unfortunatley it doesn't work if I use another register. This is just a test file, I have the same problem in my little OS, but there isn't displayed any error. Thanks god I still have Windows 7 32-bit. :)
Do you have another idea why it doesn't work (if I use bl instead of bx it works, but I need 16-bit registers)?

Thank you!

Offline Frank Kotler

  • NASM Developer
  • Hero Member
  • *****
  • Posts: 2667
  • Country: us
Re: Simple word division doesn't work (divide overflow)
« Reply #3 on: February 22, 2012, 06:04:55 PM »
Ummm... no, I don't know why it wouldn't work if you use bx. Like so?

Code: [Select]
org 0x100
start:
xor ax, ax
xor bx, bx
xor cx, cx
mov ax, 200
mov bx, 100
xor dx, dx
div bx
cmp ax, 2
je correct
; jmp _end
        jmp wrong ; no?

correct:
mov si, _c
lodsb
mov bx, 0x07
mov ah, 0x0E
int 0x10
jmp _end

wrong:
mov si, _w
lodsb
mov bx, 0x07
mov ah, 0x0E
int 0x10
jmp _end

_end:
mov ah, 0x0
int 0x16
mov ah, 0x4C
int 0x21

_c db "c", 13, 10, 0
_w db "w", 13, 10, 0

I haven't tested this, but it really "ought" to work!

If you use bl instead of bx, you've got a slightly different situation - "div" divides ax by bl (or other 8-bit register or memory) - quotient in al, remainder in ah. (doesn't care what's in dx, in this case). If the value in ah is equal or greater than bl, you'd get that same exception. ("div ah" would never work, for the same reason "div dx" would never work)...

Are you sure you've got dx zeroed before the "div"?

Best,
Frank


Offline isywum

  • Jr. Member
  • *
  • Posts: 38
Re: Simple word division doesn't work (divide overflow)
« Reply #4 on: February 22, 2012, 06:28:14 PM »
Yes, it works! :)
Thank you!! Now I get it. :)
Your replies are always great!