이것은 _llmul
의 코드로, 질문에서 본 것이 유용했을 것입니다. 상관없이 _llmul
은 32 비트 컴퓨터에서 64 비트 정수 곱하기를 수행하는 도우미 함수입니다.
함수에 대한 소스 코드는 다음과 같습니다 :이 [ESP+16]:[ESP+12]
및 [ESP+4]:[ESP]
에서 발견에 두 PUSH
작업 후, 피연산자가 분명히 있다고한다
// 64 bit integer helper routines
//
// These functions always return the 64-bit result in EAX:EDX
// ------------------------------------------------------------------------------
// 64-bit signed multiply
// ------------------------------------------------------------------------------
//
// Param 1(EAX:EDX), Param 2([ESP+8]:[ESP+4]) ; before reg pushing
//
procedure __llmul;
asm
push edx
push eax
// Param2 : [ESP+16]:[ESP+12] (hi:lo)
// Param1 : [ESP+4]:[ESP] (hi:lo)
mov eax, [esp+16]
mul dword ptr [esp]
mov ecx, eax
mov eax, [esp+4]
mul dword ptr [esp+12]
add ecx, eax
mov eax, [esp]
mul dword ptr [esp+12]
add edx, ecx
pop ecx
pop ecx
ret 8
end;
.
[ESP+8]
에서 함수의 반송 주소를 찾을 수 있습니다.
전체 기능 설계는 MUL
연산이 32 비트 피연산자에서 작동 할 때 EDX:EAX
의 64 비트 결과를 반환한다는 사실에 의존합니다. 따라서이 함수는 본질적으로 2 개의 32 비트 자릿수으로 처리되는 피연산자에 대해 긴 곱셈을 수행합니다.
는 이제
H1:L1
및
H
이 높은 32 비트를 나타낸다
H2:L2
의해 피연산자를 나타내고하자 및
L
낮은 32 비트를 나타낸다. 그러면 처음 두 곱셈은
H1*L2
과
H2*L1
입니다.
EDX
에있는 결과의 높은 부분은 64 비트 결과에 맞지 않으므로 무시됩니다. 최종 곱셈은
L1*L2
이고 그 중 높은 부분은 처음 두 곱셈의 낮은 부분과 결합됩니다. 그리고
H1*H2
은 분명히 적합하지 않으므로 시도조차하지 않습니다. 이 함수는 오버플로를 무시합니다.
와우, 막연한 질문에 대한 대단한 답변입니다. –