2

我正在尝试调用以下函数:

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

1 回答 1

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

(为了速度,您可以使用MOV代替PUSH/ POP

于 2010-12-26T22:18:38.850 回答