Windows RT在ARM上的本机代码调用约定是什么?

What is the Windows RT on ARM native code calling convention?

本文关键字:调用 约定 是什么 本机代码 RT ARM Windows      更新时间:2023-10-16

我找不到任何关于Visual Studio c++使用的Windows RT on ARM调用约定的文档。微软是否在使用ARM的AAPCS?

如果微软在ARM上使用Windows RT的AAPCS/EABI,它是否也使用ARM的c++ ABI(派生自Itanium c++ ABI)?甚至ARM异常处理ABI?

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

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

更新:增加了关于c++ ABI的问题。

与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。参见Platform Builder 7的新功能。

EDIT:刚才注意到你加了一个关于c++的问题。微软没有使用itanium风格的c++ ABI,因为他们的实现早于itanium。您可以在我的OpenRCE文章(1、2)和后续的Recon演示中了解微软的实现。参见设计师Jan Gray的原始描述:PDF.

我只能回答2的问题。

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

实际上有三个概念应该被理解。一个是ARM过程调用标准,另一个是语言ABI,第三个是系统调用约定。简单地说,ARM过程调用标准描述了寄存器在序言/尾声中的使用。语言ABI描述如何传递语言变量。例如,一个double,一个long longthis指针,dynamic_cast<>等等。第一个是汇编器与编译器之间的接口,2是编译器互操作性所需要的。3是操作系统调用的方式。

ARM过程调用标准

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

  1. 32位vs 26位PC -所有2000年以后的版本将使用32位。
  2. 堆栈限制检查-可能被重新表述为MMU或无MMU。
  3. 浮点-大约在2005年之后在大多数CPU上支持。
  4. 可重入vs不可重入—纯软件选择;共享库吗?

因此,虽然理论上有16种变化,但对于使用MMU的现代系统来说,只有两种。Debian ARM硬浮动wiki提供了一些Linux/gcc发行版的信息。我猜windows RT正在使用硬浮点,因为他们不想为支持过时的硬件而付出性能代价。最后,很难想象在windows rt中不存在共享库DLL支持。因此ARM过程调用标准似乎与Linux硬浮点数 ABI相同。

C/c++的ABI

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

OABI/EABI

嵌入式ARM wiki给出了这个标准的一些信息。使用MMU的操作系统将使用一些调用从用户模式转换到系统模式。一般来说,这些都是独有的特性,而不是编译器的一部分。但是,您肯定可以找到一些使用OABI约定的ARM系统。由于微软在ARM游戏中落后,他们要么使用EABI,要么发明一些新的东西。例如,使用gcc linux hard-float编译器调用malloc()将无法工作,因为系统调用将完全不同。一般来说,你必须使用-nostdlib进行编译,并创建自己的 c库

我在谷歌上搜索了一些关于Visual c++的细节。

  • MSDN在ARM Windows CE
  • SO ARM调用约定

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

Edit: GCC的ARM -mabi选择ABIAAPCS -linuxAAPCS/EABIapcs-gnuOABI定义序言/尾声和参数映射。编译器配置选择目标操作系统和指令/后端/CPU类型;所以我们有不同名称的编译器,如arm-linux-eabi-gcc, arm-linux-gnueabi-gcc '等。