\r
EXTERN InternalMathDivRemU64x32:PROC\r
\r
+;------------------------------------------------------------------------------\r
+; UINT64\r
+; EFIAPI\r
+; InternalMathDivRemU64x64 (\r
+; IN UINT64 Dividend,\r
+; IN UINT64 Divisor,\r
+; OUT UINT64 *Remainder OPTIONAL\r
+; );\r
+;------------------------------------------------------------------------------\r
InternalMathDivRemU64x64 PROC\r
- mov ecx, [esp + 16]\r
+ mov ecx, [esp + 16] ; ecx <- divisor[32..63]\r
test ecx, ecx\r
- jnz _@DivRemU64x64\r
+ jnz _@DivRemU64x64 ; call _@DivRemU64x64 if Divisor > 2^32\r
mov ecx, [esp + 20]\r
jecxz @F\r
- and dword ptr [ecx + 4], 0\r
- mov [esp + 16], ecx\r
+ and dword ptr [ecx + 4], 0 ; zero high dword of remainder\r
+ mov [esp + 16], ecx ; set up stack frame to match DivRemU64x32\r
@@:\r
jmp InternalMathDivRemU64x32\r
InternalMathDivRemU64x64 ENDP\r
\r
_@DivRemU64x64 PROC USES ebx esi edi\r
mov edx, dword ptr [esp + 20]\r
- mov eax, dword ptr [esp + 16]\r
+ mov eax, dword ptr [esp + 16] ; edx:eax <- dividend\r
mov edi, edx\r
- mov esi, eax\r
- mov ebx, dword ptr [esp + 24]\r
+ mov esi, eax ; edi:esi <- dividend\r
+ mov ebx, dword ptr [esp + 24] ; ecx:ebx <- divisor\r
@@:\r
shr edx, 1\r
rcr eax, 1\r
shr ecx, 1\r
jnz @B\r
div ebx\r
- mov ebx, eax\r
- mov ecx, [esp + 28]\r
- mul dword ptr [esp + 24]\r
- imul ecx, ebx\r
- add edx, ecx\r
- mov ecx, dword ptr [esp + 32]\r
- jc @TooLarge\r
- cmp edi, edx\r
+ mov ebx, eax ; ebx <- quotient\r
+ mov ecx, [esp + 28] ; ecx <- high dword of divisor\r
+ mul dword ptr [esp + 24] ; edx:eax <- quotient * divisor[0..31]\r
+ imul ecx, ebx ; ecx <- quotient * divisor[32..63]\r
+ add edx, ecx ; edx <- (quotient * divisor)[32..63]\r
+ mov ecx, dword ptr [esp + 32] ; ecx <- addr for Remainder\r
+ jc @TooLarge ; product > 2^64\r
+ cmp edi, edx ; compare high 32 bits\r
ja @Correct\r
- jb @TooLarge\r
+ jb @TooLarge ; product > dividend\r
cmp esi, eax\r
- jae @Correct\r
+ jae @Correct ; product <= dividend\r
@TooLarge:\r
- dec ebx\r
- jecxz @Return\r
+ dec ebx ; adjust quotient by -1\r
+ jecxz @Return ; return if Remainder == NULL\r
sub eax, dword ptr [esp + 24]\r
- sbb edx, dword ptr [esp + 28]\r
+ sbb edx, dword ptr [esp + 28] ; edx:eax <- (quotient - 1) * divisor\r
@Correct:\r
jecxz @Return\r
sub esi, eax\r
- sbb edi, edx\r
+ sbb edi, edx ; edi:esi <- remainder\r
mov [ecx], esi\r
mov [ecx + 4], edi\r
@Return:\r
- mov eax, ebx\r
- xor edx, edx\r
+ mov eax, ebx ; eax <- quotient\r
+ xor edx, edx ; quotient is 32 bits long\r
ret\r
_@DivRemU64x64 ENDP\r
\r