Here is a division routine for dividing two 64-bit unsigned integers. I derived it by modifying some old 16-bit code for dividing 32-bit integers that I did several years ago for a Turbo-Pascal replacement library. If a 64-bit signed integer division is needed, appropriate shell code for this routine can easily be written.
; ; _ulldiv divides two unsigned long long numbers, the dividend and the divisor ; resulting in a quotient and a remainder. ; ; input: ; edx:eax = dividend ; ecx:ebx = divisor ; ; output: ; edx:eax = quotient of division of dividend by divisor ; ecx:ebx = remainder of division of dividend by divisor ; ; destroys: ; eflags ; PROC _ulldiv NEAR test ecx, ecx ; divisor > 2^32-1 ? jnz $big_divisor ; yes, divisor > 32^32-1 cmp edx, ebx ; only one division needed ? (ecx = 0) jb $one_div ; yes, one division sufficient mov ecx, eax ; save dividend-lo in ecx mov eax, edx ; get dividend-hi xor edx, edx ; zero extend it into edx:eax div ebx ; quotient-hi in eax xchg eax, ecx ; ecx = quotient-hi, eax =dividend-lo $one_div: div ebx ; eax = quotient-lo mov ebx, edx ; ebx = remainder-lo mov edx, ecx ; edx = quotient-hi(quotient in edx:eax) xor ecx, ecx ; ecx = remainder-hi (rem. in ecx:ebx) ret $big_divisor:push esi ; save temp push edi ; variables push edx ; save push eax ; dividend mov esi, ebx ; divisor now in mov edi, ecx ; edi:ebx and ecx:esi shr edx, 1 ; shift both rcr eax, 1 ; divisor and ror edi, 1 ; and dividend rcr ebx, 1 ; right by 1 bit bsr ecx, ecx ; ecx = number of remaining shifts shrd ebx, edi, CL ; scale down divisor and shrd eax, edx, CL ; dividend such that divisor shr edx, CL ; less than 2^32 (i.e. fits in ebx) rol edi, 1 ; restore original divisor (edi:esi) div ebx ; compute quotient pop ebx ; get dividend lo-word mov ecx, eax ; save quotient imul edi, eax ; quotient * divisor hi-word (low only) mul esi ; quotient * divisor lo-word add edx, edi ; edx:eax = quotient * divisor sub ebx, eax ; dividend-lo - (quot.*divisor)-lo mov eax, ecx ; get quotient pop ecx ; restore dividend hi-word sbb ecx, edx ; subtract divisor * quot. from dividend sbb edx, edx ; 0 if remainder > 0, else FFFFFFFFh and esi, edx ; nothing to add and edi, edx ; back if remainder positive add ebx, esi ; correct remaider adc ecx, edi ; and quotient if add eax, edx ; necessary xor edx, edx ; clear hi-word of quot (eax<=FFFFFFFFh) pop edi ; restore temp pop esi ; variables ret ENDP _ulldiv