ARM64EC
ARM64EC is a new ABI that appeared with Windows 11.
It allows to mix x64 and arm64 code in the same process.
Porting applications to Arm64 using the Arm64EC ABI: https://www.youtube.com/watch?v=HmI6ip4o9as
Understanding Arm64EC ABI and assembly code
Setup
To be able to compile code targeting ARM64EC, you need to install:
VS2019 or 2022
Windows 11 SDK (version >= 22000): Windows SDK - Windows app development
To install the SDK, you can install it through VS installer.
Note: If you use Insider Preview Win11 VM, SDK install will fail saying its not compatible with current Windows version. If this, you must install the SDK manually via the link above.
Compile
To compile an arm64ec object, you need flag: /arm64EC
(case matters!)
To link if, you need flag: /machine:arm64ec
or /machine:arm64x
(expose both arm64 and arm64ec interfaces).
There is no way to mix x86 code with any other architecture, it would have no meaning.
Run
This bash script will compile a single binary with two objects:
x64.c: compiled in x64
main.c: compiled in arm64ec
#!/usr/bin/env bash
set -euo pipefail
vcvars='C:\"Program Files"\"Microsoft Visual Studio"\2022\Community\VC\Auxiliary\Build\vcvarsall.bat'
x64()
{
cmd.exe /c "call $vcvars x64 & $*"
}
arm64()
{
cmd.exe /c "call $vcvars x86_arm64 & $*"
}
show_arch()
{
local bin=$1
local arch=$(x64 dumpbin.exe /headers $bin |& grep machine)
echo "arch for $bin: $arch"
}
line()
{
echo "--------------------"
}
check_winsdk_available()
{
# you need windows 11 sdk, else link will fail
# LINK : fatal error LNK1104: cannot open file 'softintrin.lib'
local found=$(find '/c/Program Files (x86)/' | grep '/softintrin.lib$')
if [ "$found" == "" ]; then
echo "you need windows 11 sdk (22000) installed"
exit 1
fi
}
cat > main.c << EOF
#include <stdio.h>
extern char* secret_from_x64(int* res);
int main()
{
int secret = 0;
char* msg = secret_from_x64(&secret);
printf("%s: %d\n", msg, secret);
}
EOF
cat > x64.c << EOF
char* secret_from_x64(int* res)
{
*res = 42;
return "sent from x64";
}
EOF
check_winsdk_available
arm64 cl.exe main.c /c /arm64EC # this flag enables this new ABI
line
x64 cl.exe x64.c /c
# link
# machine:arm64x expose both arm64 and arm64ec abi
# machine:arm64ec expose only arm64ec abi
line
arm64 link.exe main.obj x64.obj /machine:arm64ec
line
show_arch main.obj
show_arch x64.obj
show_arch main.exe
line
./main.exe
Output
--------------------
arch for main.obj: A641 machine (ARM64EC)
arch for x64.obj: 8664 machine (x64)
arch for main.exe: 8664 machine (x64) (ARM64X)
--------------------
sent from x64: 42