4

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

如果微软在 ARM 上使用 AAPCS/EABI for Windows RT,它是否也在使用ARM 的 C++ ABI(它源自安腾 C++ ABI)?甚至可能是ARM 异常处理 ABI

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

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

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

4

2 回答 2

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。请参阅Platform Builder 7 中的新增功能

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

于 2013-05-06T10:37:01.690 回答
3

我只能回答第二个问题。

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

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

ARM 过程调用标准

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

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

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

'C/C++' ABI

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

OABI/EABI

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

我用谷歌搜索了一些关于 Visual C++ 的细节。

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

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

于 2013-05-04T16:11:33.127 回答