我在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的问题。
答案 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文章(1,2)和后续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调用的方式。
apcs.txt文档有助于理解一些ARM变体。根据四种不同的选择,有16种变体。
因此,虽然有16种理论变化,但对于使用MMU的现代系统,只有两种。 Debian ARM hard float wiki提供了一些Linux / gcc发行版的信息。我猜想Window RT正在使用硬浮动,因为他们不想支付性能价格来支持过时的硬件。最后,很难想到Window RT中不会出现共享库或 DLL 支持。所以 ARM Procedure Call Standard 似乎与 Linux hard float ABI相同。
AAPCS定义了语言如何将高级函数/方法映射到低级细节。名称修改确保符号具有规范名称,以便可以进行跨工具链接。 AAPCS 工具理论上应该互操作,但支持库和其他系统级接口可能会出现问题。
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`等。