2013-08-05 2 views
2

저는 어셈블리와 메모리 관련 재료로 초보자입니다. 우리가 reg 내에서 int64 값을 가질 때 mov 연산자가 어떻게 변하는가? 내 말은 문자열이 아니라 정수라는 뜻입니다. 어쩌면 그것은 내 바보 같지만 이해가 안됩니다! 예를 들어이 코드는 무엇을합니까? "esp"에 int64 값이 있다고 가정합니다.어셈블리 및 64 비트 정수 - 파스칼 (delphi 6)에서 생성 하시겠습니까?

push  edx 
push  eax 
mov  eax,dword ptr [esp+$10] 
mul  eax,dword ptr [esp] 
mov  ecx,eax 
mov  eax,dword ptr [esp+$04] 
mul  eax,dword ptr [esp+$0C] 
add  ecx,eax 
mov  eax,dword ptr [esp] 
mul  eax,dword ptr [esp+$0C] 
add  edx,ecx 
pop  ecx 
pop  ecx 
ret  8 

int64는 8 바이트이지만 esp + 10!

답변

5

이것은 _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:L1H이 높은 32 비트를 나타낸다 H2:L2 의해 피연산자를 나타내고하자 및 L 낮은 32 비트를 나타낸다. 그러면 처음 두 곱셈은 H1*L2H2*L1입니다. EDX에있는 결과의 높은 부분은 64 비트 결과에 맞지 않으므로 무시됩니다. 최종 곱셈은 L1*L2이고 그 중 높은 부분은 처음 두 곱셈의 낮은 부분과 결합됩니다. 그리고 H1*H2은 분명히 적합하지 않으므로 시도조차하지 않습니다. 이 함수는 오버플로를 무시합니다.

+0

와우, 막연한 질문에 대한 대단한 답변입니다. –

관련 문제