在nasm(stdcall)中称呼很长的rtllargeintegerdivide(long,long,long long*)
-
13-10-2019 - |
题
我正在尝试调用以下功能:
long long RtlLargeIntegerDivide(long long dividend, long long divisor, long long* pRemainder)
在组装代码(NASM)中。它使用stdcall调用约定,并返回商。这些是规格:
输入:[EDX,EAX](股息),[ECX,EBX](Divisor)
输出:[EDX,EAX](商),[ECX,EBX](剩余)
我该怎么做? (我的主要问题不是完全了解EBP和ESP,以及它们与本地变量的关系。)
(不,这不是作业;我正在尝试实现包装库crun-time库。)
谢谢!
解决方案
在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
)
不隶属于 StackOverflow