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

arm, c++, calling-convention, winapi, windows-runtime

Solution

Unlike Windows CE (which uses original APCS aka Old ABI), Windows RT on ARM uses EABI. More specifically, the variant which uses floating-point registers to pass floating-point data and 8-byte stack/argument alignment.

If I take the following function:

int g(float x) {
  return x;
}

and compile it with VS2012's ARM compiler, I get the following assembly:

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

You can see that it's using `S0` and not `R0` for the argument.

The one from VS2008 (which can be used to target older Windows CE versions) produces this:

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

This code is calling a helper function to perform the conversion.

The Windows CE compiler shipped with Windows Compact 7 supports both the old calling convention (called "cdecl" by MS) and EABI. See What's New in Platform Builder 7.

EDIT: just now noticed you added a question about C++. Microsoft does not use Itanium-style C++ ABI, since their implementation predates it. You can read about Microsoft's implementation in my OpenRCE articles (1, 2) and the follow-up Recon presentation. See also the original description from the designer Jan Gray: PDF.

Problem

I couldn't find any documentation on the Windows RT on ARM calling convention used by Visual Studio C++. Is Microsoft using ARM's AAPCS? If Microsoft is using the AAPCS/EABI for Windows RT on ARM, is it also using ARM's C++ ABI (which is derived from the Itanium C++ ABI)? Maybe even the ARM exception handling ABI? Does the calling convention used by Windows RT on ARM differ from that used by other (embedded) ARM Windows variants? Is there a reliable way to detect Windows RT on ARM through predefined compiler macros? Update: Added the question regarding the C++ ABI.

Original source

Related problems