2010-12-26 7 views
2

호출 :NASM에서 LONGLONG RtlLargeIntegerDivide (LONGLONG, LONGLONG, LONGLONG *) (stdcall을) 나는 다음과 같은 함수를 호출하기 위해 노력하고있어

long long RtlLargeIntegerDivide(long long dividend, long long divisor, long long* pRemainder) 

어셈블리 코드 (NASM)에 있습니다. stdcall 호출 규칙을 사용하고 몫을 리턴합니다.

입력 : [EDX, EAX (배당), ECX, EBX (제수)

출력 : [EDX, EAX (몫), ECX, EBX (나머지 이러한 사양이다)

어떻게해야합니까? (내 주요 문제는 EBP와 ESP를 정확히 이해하지 못하고 어떻게 지역 변수와 관련되는지를 보여줍니다.)

(아니요, 숙제가 아닙니다. 래퍼 C 런타임 라이브러리를 구현하려고합니다.)

감사합니다.

답변

4

32 비트 모드에서는 EBP를 사용하지 않아도 로컬 변수에 액세스 할 수 있습니다. 이는 16 비트 시간에서 남은 컨벤션이며 어쨌든 우리를 걱정하지 않습니다.

ESP가 스택 포인터 인 것을 알고 있다고 생각합니다. ESP를 감소시킴으로써 지역 변수에 공간을 "할당"할 수 있습니다.

stdcall 호출 규칙은 인수 전달을 위해 스택을 사용합니다. 그들은 정상적인 순서로 스택에 있지만, 당신은 PUSH을 사용하는 경우 그것들을 뒤집 었다는 것을 의미합니다. 적분 리턴 값은 EAX (및 필요할 때 EDX)에 있습니다. 호출 된 함수는 스택에서 인수를 정리합니다.

그래서 다음 코드는 당신이 원하는 것을 수행해야합니다

sub ESP, 8; make room for remainder 
push ESP ; pass pointer to remainder as argument 
push ECX 
push EBX ; pass divisor argument 
push EDX 
push EAX ; pass dividend argument 
call RtlLargeIntegerDivide 
; quotient returned in EDX:EAX 
; so just load remainder from stack 
pop EBX 
pop ECX 

+0

아름다운 답 (속도를 들어, PUSH/POP 대신 MOV을 사용할 수 있습니다), 감사합니다! :) – Mehrdad

관련 문제