什么是ARM本机代码调用约定?

时间:2013-05-04 14:27:18

标签: c++ winapi windows-runtime arm calling-convention

我在Visual Studio C ++使用的ARM调用约定上找不到任何关于Windows RT的文档。 Microsoft是否使用ARM的AAPCS

如果Microsoft在ARM上使用AAPCS / EABI for Windows RT,它是否也使用ARM's C++ ABI(来自Itanium C ++ ABI)?甚至可能是ARM exception handling ABI

ARM RT在ARM上使用的调用约定是否与其他(嵌入式)ARM Windows变体使用的调用约定不同?

是否有可靠的方法通过预定义的编译器宏检测ARM上的Windows RT?

更新:添加了有关C ++ ABI的问题。

2 个答案:

答案 0 :(得分:8)

与Windows CE(使用原始APCS又称旧ABI)不同,ARM上的Windows RT使用EABI。更具体地说,使用浮点寄存器传递浮点数据和8字节堆栈/参数对齐的变体。

如果我采取以下功能:

int g(float x) {
  return x;
}

使用VS2012的ARM编译器编译它,我得到以下程序集:

|g| PROC
    vcvt.s32.f32 s0,s0
    vmov        r0,s0
    bx          lr
    ENDP  ; |g|

您可以看到它正在使用S0而不是R0作为参数。

VS2008中的一个(可用于定位较旧的Windows CE版本)产生:

str     lr, [sp,#-4]!
ldr     r3, =__imp___stoi
ldr     r3, [r3]
mov     lr, pc
bx      r3
ldr     pc, [sp],#4

此代码调用辅助函数来执行转换。

Windows Compact 7附带的Windows CE编译器支持旧的调用约定(MS称为“cdecl”)和EABI。请参阅What's New in Platform Builder 7

编辑:刚才注意到你添加了一个关于C ++的问题。 Microsoft不使用Itanium风格的C ++ ABI,因为它们的实现早于它。您可以在我的OpenRCE文章(12)和后续Recon presentation中了解Microsoft的实现。另请参阅设计师Jan Gray的原始描述:PDF

答案 1 :(得分:3)

我只能回答2 nd 问题。

  

ARM RT在ARM上使用的调用约定是否与其他(嵌入式)ARM Windows变体使用的调用约定不同?

实际上有三个概念应该被理解。一个是 ARM过程调用标准,另一个是语言ABI ,第三个是系统调用约定。简而言之, ARM过程调用标准描述了在序言/尾声中使用寄存器。 语言ABI 描述了语言变量的传递方式。即, double long long this 指针,dynamic_cast<>等。首先需要将汇编程序与编译器,编译器互操作性需要2 nd 。 3 rd 是OS调用的方式。

ARM过程调用标准

apcs.txt文档有助于理解一些ARM变体。根据四种不同的选择,有16种变体。

  1. 32位vs 26位PC - 所有2000后版本都将使用32位。
  2. 堆栈限制检查 - 可能重新表述为MMU或没有MMU。
  3. 浮点 - 大约在2005年之后支持大多数CPU。
  4. 重入与非重入 - 纯粹的软件选择;共享库?
  5. 因此,虽然有16种理论变化,但对于使用MMU的现代系统,只有两种。 Debian ARM hard float wiki提供了一些Linux / gcc发行版的信息。我猜想Window RT正在使用硬浮动,因为他们不想支付性能价格来支持过时的硬件。最后,很难想到Window RT中不会出现共享库 DLL 支持。所以 ARM Procedure Call Standard 似乎与 Linux hard float ABI相同。

    'C / C ++'ABI

    AAPCS定义了语言如何将高级函数/方法映射到低级细节。名称修改确保符号具有规范名称,以便可以进行跨工具链接。 AAPCS 工具理论上应该互操作,但支持库和其他系统级接口可能会出现问题。

    OABI / EABI

    Embedded ARM wiki提供了有关此标准的一些信息。使用MMU的操作系统将使用一些调用从用户模式转换为系统模式。通常,这些只是功能,不是编译器的一部分。但是,您当然可以找到一些使用 OABI 约定的ARM系统。由于微软是ARM游戏的后期,他们要么使用 EABI ,要么发明了新的东西。例如,使用 gcc linux hard-float 编译器调用malloc()将无法正常工作,因为系统调用将完全不同。通常,您必须使用-nostdlib进行编译并创建自己的 C库

    我已经google了一下,以便在Visual C ++上找到具体内容。

    所以要回答你的2 nd 问题,有很多编译器/系统会产生类似的序言/结语。如果Visual C ++使用 AAPCS ,则它可以与其他 AAPCS 编译器互操作。您可能必须创建自定义库以使另一个编译器调用 Windows RT 系统调用。其他问题应该在手册中回答。

    修改: GCC's ARM -mabi选择 ABI aapcs-linux AAPCS / EABI apcs-gnu 是定义prologue/epilogue和参数的 OABI 映射。编译器配置选择目标OS和指令/后端/ CPU类型;所以我们有不同名称的编译器,如arm-linux-eabi-gcc,arm-linux-gnueabi-gcc`等。