2
votes

I'm trying to call the following function:

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

in assembly code (NASM). It uses the stdcall calling convention, and it returns the quotient. These are the specifications:

Input: [EDX,EAX] (dividend), [ECX,EBX] (divisor)

Output: [EDX,EAX] (quotient), [ECX,EBX] (remainder)

How do I go about doing this? (My main problem is not exactly understanding EBP and ESP, and how they relate to local variables.)

(And no, this isn't homework; I'm trying to implement a wrapper C run-time library.)

Thank you!

1

1 Answers

4
votes

In 32 bit mode you don't have to use EBP to access local variables at all, that is just a convention remnant from 16 bit times and doesn't concern us now anyway.

ESP is your stack pointer, I assume you know that. You can "allocate" space for your local variables by decrementing ESP.

stdcall calling convention uses the stack for argument passing. They are in normal order when on the stack, but if you are using PUSH that means you push them reversed. Integral return values are in EAX (and EDX when necessary). The called function cleans up the arguments from the stack.

So the following code should do what you want:

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

(For speed, you can use MOV instead of PUSH/POP)