Page 1 of 1

Assembly Div Error

Posted: Sat Dec 15, 2007 12:21 pm
by matias_beretta
Hello, thanks for reading my post.

mov ax, di
mov bl, 2h
div bl

This gives me an "overflow" error. I can't understand why. Can you help me?

Posted: Sat Dec 15, 2007 12:41 pm
by Masterkiller
8 bit DIV divides AX by source and write the result in AL, the remainder in AX, that means the result should be less than 256 or it will overflow...

Example:
FFFFh / 2 = 7FFFh and remainder 1
7FFFh should goes in AL
1 goes in AH

Instead of that set BH to zero and divide by BX to get the result in AX and the remainder in DX.

thanks

Posted: Sat Dec 15, 2007 12:50 pm
by matias_beretta
thanks ;)

question

Posted: Sat Dec 15, 2007 3:38 pm
by matias_beretta
i doesn't work, lets suppose i want to divide 4000 by 2:

mov ax, 4000
mov bl, 2
div bl ERROR because 2000 > byte (al and ah)

so...

mov eax, 4000
mov bx, 2
div bx

also error: 4000 / 2 = 2000 < dword (eax)

i don't understand can you help me?

Posted: Sat Dec 15, 2007 4:06 pm
by Masterkiller
Hmm.. It seems correct, except that the result is stored in DX:AX (AX - result, DX - remainder). Actually I'm not so sure but I think that when divide by 16-bit source, CPU divide the value of DX:AX pair (Even in 32 Bit mode). And if the DX store bigger than 7FFFh value - you get error.
Why DX:AX pair? Because the result is stored in it and there is no way to access directly to the high 16-bits in EAX.

question

Posted: Sat Dec 15, 2007 4:10 pm
by matias_beretta
is the eax register available in real mode?

Question

Posted: Sat Dec 15, 2007 4:49 pm
by matias_beretta
The question is how to divide 4000 by 2 in assembly ;)

Posted: Sat Dec 15, 2007 5:48 pm
by Masterkiller

Code: Select all

MOV ax, 4000
MOV cx, 2
DIV cx
;ax -> Result
;dx -> Remainder
Pretty easy...
And also EAX may be available in 16-bit real-mode but maybe only for some instruction. For example OR eax, 1

Posted: Sat Dec 15, 2007 8:26 pm
by rd1101
Masterkiller wrote:

Code: Select all

MOV ax, 4000
MOV cx, 2
DIV cx
;ax -> Result
;dx -> Remainder
Pretty easy...
And also EAX may be available in 16-bit real-mode but maybe only for some instruction. For example OR eax, 1

If I remember correctly... (which is never guaranteed :-$ )...

As Masterkiller stated, the instruction "DIV cx" divides the implicit dx:ax by cx and leaves the result in ax, and the remainder in dx.

But don't forget to zero out dx... If dx:ax is too big, you will overflow (> 0x1FFFE, for cx = 2, I think)... DIV is one of those strange instruction formats that I'd recommend referring to an Intel manual or x86 reference when using, to help prevent headaches in the long run.

Code: Select all

;// dx:ax / cx
xor dx, dx
mov ax, 4000
mov cx, 2
div cx
;// ax = quotient, dx = remainder

Posted: Sat Dec 15, 2007 11:18 pm
by elderK
You want to divide something by two?
:P Why not just shift it right by one bit?
:P

~Z

Posted: Sun Dec 16, 2007 12:08 am
by Brendan
Hi,

For the sake of completeness, in real mode you can use all 32-bit operations (on 32-bit CPUs), including:

Code: Select all

    xor edx,edx
    mov eax,4000          ;edx:eax = number to divide
    mov ecx,2                ;ecx = divisor
    div ecx                     ;eax = result, edx = remainder
Cheers,

Brendan