【问题标题】:Retrieve arguments of a x64 masm assembly procedure检索 x64 masm 装配过程的参数
【发布时间】:2013-11-20 17:40:46
【问题描述】:

我有一个带有签名的函数:

extern "C" int foo(int a, int b, int c, int d, int e);

实际上是用汇编语言编写的。

使用 ml(32 位),使用标准调用约定,您几乎可以编写

.code
foo PROC a: DWORD, b: DWORD ,c: DWORD, d: DWORD, e: DWORD

     mov eax, d
     mov ebx, e

并开始使用这些标签来访问您的论点

对于 ml64(64 位),fastcall 是唯一可用的约定。我可以毫无问题地访问存储在寄存器中的第一个参数,但访问堆栈中的参数(在此示例中为e)时出现问题:我尝试过

.code
foo PROC a: DWORD, b: DWORD ,c: DWORD, d: DWORD, e: DWORD

.code
foo PROC  e: DWORD

e 中的值是垃圾。

我发现如果我直接使用堆栈地址就可以找到值。

.code
foo PROC  e: DWORD

     mov eax, r9                  ; d
     mov ebx, DWORD PTR[rbp + 48] ; e

还有其他方法吗?

【问题讨论】:

    标签: c++ visual-studio-2010 assembly 64-bit masm


    【解决方案1】:

    文档解释了一切...在 Windows 中,前四个整数参数在寄存器 RCXRDXR8R9 中传递,浮点在 XMM0XMM1、@987654327 中传递@,XMM3,任何超过四个参数的参数都在阴影空间上方的堆栈上传递。对于 Unix 类型的操作系统,它有点不同。

    所以,你的例子是正确的 - mov ebx, DWORD PTR[rbp + 48] ; e

    阴影空间 = 32 + 保存的 rbp = 40 + 第 5 个参数 = 48

    【讨论】:

      【解决方案2】:

      给定

      extern "C" int foo(int a, int b, int c, int d, int e);
      

      我发现Visual Studio 2010 不保存基本指针RBP if

      .code
      foo PROC
      

      但是如果保存基指针

      .code
      foo PROC  e: DWORD
      

      更高版本 (vs2015) 不允许使用第二个代码。

      There is an optional optimization in x64 systems where RBP is not used(很难找到)。它说:

      %rbp 的常规用法作为堆栈帧的帧指针 可以通过使用 %rsp (堆栈指针)索引到 堆栈帧。这种技术在序言中节省了两条指令, 结语并制作一个额外的通用寄存器 (%rbp) 可用。

      因此,foo PROC e: DWORD 可能无法编译(vs2015),或者foo PROC 崩溃,因为 RBP 为空。

      获取堆栈参数的正确方法是使用RSP 堆栈指针

      RBP = RSP + 8 * num_saved_reg
      

      其中num_saved_reg 是PROC 指令中指定的寄存器数量。所以当rbp不保存时(否则加8)

      PROC -> DWORD PTR[rsp + 40]
      PROC use RDI -> DWORD PTR[rsp + 40 + 8]
      PROC use RDI RSI RBX -> DWORD PTR[rsp + 40 + 24]
      

      【讨论】:

      • 当您调用另一个函数时,您的答案就会出现问题;这将破坏堆栈指针,您将获得堆栈异常。如果你从不调用另一个函数,它应该工作,但不要引用我的话,保存和恢复堆栈指针是最安全的。
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2021-11-02
      • 1970-01-01
      • 1970-01-01
      • 2012-11-14
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多