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?
Why not just shift it right by one bit?
~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