【问题标题】:Calling LONGLONG RtlLargeIntegerDivide(LONGLONG, LONGLONG, LONGLONG*) in NASM (stdcall)Calling LONGLONG RtlLargeIntegerDivide(LONGLONG, LONGLONG, LONGLONG*) in NASM (stdcall)
【发布时间】:2011-05-30 21:21:46
【问题描述】:

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

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 运行时库。)

谢谢!

【问题讨论】:

    标签: winapi assembly nasm calling-convention stdcall


    【解决方案1】:

    在 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

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2012-05-11
      • 2020-05-18
      • 2016-04-01
      • 2019-06-28
      • 1970-01-01
      • 2021-10-30
      • 2022-12-26
      • 2022-12-01
      相关资源
      最近更新 更多