;============================================ ; Div64x64 (&divStruct) ; ; 64-bit by 64-bit successive-subtraction division. ; Quotient and remainder are 64 bits. ; ; On entry, ; EDX:EAX = dividend ; divisor in divStruct ; ; Returns: ; EDX:EAX = quotient ; remainder in divStruct ;============================================ Div64x64 PROC divStructPtr:DWORD LOCAL divisorLo:DWORD, divisorHi:DWORD, dividendLo:DWORD, dividendHi:DWORD LOCAL bitIndex:DWORD ; If dividend is zero, skip all this stuff, just return zero for quotient & remainder: MOV ECX, EAX OR ECX, EDX JNZ @F MOV EDX, divStructPtr MOV [EDX].DIVSTRUCT.remainderLo, 0 MOV [EDX].DIVSTRUCT.remainderHi, 0 XOR EAX, EAX XOR EDX, EDX RET @@: PUSH EBX PUSH ESI PUSH EDI MOV dividendLo, EAX MOV dividendHi, EDX MOV ECX, divStructPtr MOV EAX, [ECX].DIVSTRUCT.divisorLo MOV divisorLo, EAX MOV EAX, [ECX].DIVSTRUCT.divisorHi MOV divisorHi, EAX XOR ESI, ESI XOR EDI, EDI ;EDI:ESI = quotient XOR ECX, ECX XOR EBX, EBX ;EBX:ECX = remainder XOR EAX, EAX ;Clear bit carrier. MOV bitIndex, 63 ; Left-shift R: dvloop: SHLD EBX, ECX, 1 SHL ECX, 1 ; R(0) = N(i): PUSH ECX MOV EDX, 1 ;"Seed" for bitmask. MOV ECX, bitIndex CMP ECX, 32 JB doLow1 SUB ECX, 32 SHL EDX, CL ;EDX now is mask for the bit we want. TEST dividendHi, EDX ;Is N[i] set? JMP @F doLow1: SHL EDX, CL TEST dividendLo, EDX ;Is N[i] set? @@: SETNZ AL POP ECX AND ECX, DWORD PTR NOT 1 ;Clear bit[0]. OR ECX, EAX ;Set in bit[0] (or not). ; If R >= D: CMP EBX, divisorHi JB next JA @F ; Must be equal--need to compare low DWORDs: CMP ECX, divisorLo JB next ; R = R - D: @@: SUB ECX, divisorLo SBB EBX, divisorHi ; Q[i] = 1: PUSH ECX MOV EDX, 1 MOV ECX, bitIndex CMP ECX, 32 JB doLow2 SUB ECX, 32 SHL EDX, CL ;EDX now is mask for the bit we want. OR EDI, EDX JMP SHORT @F doLow2: SHL EDX, CL OR ESI, EDX @@: POP ECX next: DEC bitIndex JNS dvloop ;Make sure we travel through loop on 0. MOV EDX, divStructPtr MOV [EDX].DIVSTRUCT.remainderLo, ECX MOV [EDX].DIVSTRUCT.remainderHi, EBX MOV EAX, ESI MOV EDX, EDI POP EDI POP ESI POP EBX RET Div64x64 ENDP