NASM: Dividing large number with small one
NASM manual says on DIV
:
- For DIV r/m32, EDX:EAX is divided by the given operand; the quotient is stored in EAX and the remainder in EDX.
What if EDX:EAX
is a large number around 259 and the divider is 3
? The quotient clearly cannot fit into EAX
. Let's say I do not care about the remainder. I would like to have a best practice for doing the division.
Thinking about dividing the upper and lower 32 bits in separate steps. I think I could figure out some ugly result, but I would be interested in a good one. With a quick check for the case when EAX
is likely to hold the quotient thus avoiding the complicated magic.
Solution: drhirsch's answer converted to NASM syntax:
; this divides edx:eax by ebx, even if the result is bigger than 2^32.
; result is in edx:eax, ecx,esi are used as spare registers
mov ecx, eax 开发者_运维问答 ;save lower 32 bit
mov eax, edx
xor edx, edx ;now edx:eax contains 0:hi32
div ebx
mov esi, eax ;hi 32 bit of result, save to esi
mov eax, ecx ;now edx:eax contains r:lo32, where r is the remainder
div ebx
mov edx, esi ;restore hi32
This code is untested. It should calculate (d*2^32 + a)/b:
;this divides edx:eax by ebx, even if the result is bigger than 2^32.
;result is in edx:eax, ecx,esi are used as spare registers
;AT&T syntax.
mov %eax, %ecx ;save lower 32 bit
mov %edx, %eax
xor %edx, %edx ;now edx:eax contains 0:hi32
div %ebx
mov %eax, %esi ;hi 32 bit of result
mov %ecx, %eax ;now edx:eax contains r:lo32, where r is the remainder
div %ebx
mov %esi, %edx ;restore hi32
精彩评论