ARM64EC
ARM64EC(Emulation Compatible,即「模拟兼容」)是微软为运行 Windows 11 的 Arm 设备引入的一种应用二进制接口(ABI)[1]。它允许同一个进程内同时存在以原生速度运行的 Arm64 指令代码和运行在模拟层中的 x64 代码,从而让开发者不必一次性重编译整个应用及其依赖,就能逐步把 x64 程序迁移到 Arm 原生运行,兼顾性能与兼容性。
定义
ARM64EC 是面向在 Arm 设备上运行 Windows 11 的应用程序的一种应用二进制接口,名称中的 EC 为 Emulation Compatible 的缩写,意为「模拟兼容」[1]。它既是微软为 Windows 11 引入的一项平台特性,也是编译器与链接器可生成的一类目标格式,使用它需要配合 Windows 11 软件开发工具包,在 Arm 版 Windows 10 上并不提供[1]。
按照微软的说明,ARM64EC 是一套完整的、一等公民式的 ABI,而非仅用于兼容的补丁;以 ARM64EC 构建的应用可以包含 x64 代码,也可以完全不包含。在进程和模块两个层级上,ARM64EC 与 x64 都可以按需混用,其中 ARM64EC 部分以原生速度执行,而 x64 部分由 Windows 11 自带模拟层执行[1]。
原理
ARM64EC 的互操作能力来自其遵循 x64 的软件约定。该 ABI 在调用约定、栈使用方式、数据结构布局以及预处理器定义等方面与 x64 保持一致,从而保证同一进程内的 ARM64EC 代码与 x64 代码可以相互调用[1]。与之相对,ARM64EC 代码与以 Arm64 构建的代码并不兼容,因为后者使用另一套软件约定[1]。
由于约定不同,混合调用需要额外的转换机制。在 ARM64EC 中,部分函数需要生成进入转换块(entry thunk)和退出转换块(exit thunk)来完成 x64 与 ARM64 之间的切换,间接调用需要经过调用检查例程,控制流保护和栈检查所用函数也与 Arm64 不同[2]。微软文档列出的模拟辅助例程包括负责调用 x64 目标的 __os_arm64x_dispatch_call_no_redirect、负责返回 x64 调用方的 __os_arm64x_dispatch_ret,以及处理调用与间接调用的 __os_arm64x_check_call、__os_arm64x_check_icall 等,这些指针在磁盘上为空,加载时由加载器指向 x64 模拟器例程[3]。
在可加载关系上,规则可以概括为:x64 或 ARM64EC 进程既能加载 x64 二进制,也能加载 ARM64EC 二进制,而 Arm64 进程只能加载 Arm64 二进制;两种架构都能加载同时包含 x64 与 Arm64 代码的 Arm64X 二进制[1]。编译期存在类似的约束:ARM64EC 二进制可以链接 x64 库和 ARM64EC 库,但不能链接 Arm64 库[1]。
发展历程
微软于 2021 年 6 月 28 日在 Windows 开发者博客上正式公布 ARM64EC,并将它定位为在 Arm 架构上为 Windows 11 构建应用的途径之一;当时可配合预览版的 Visual Studio 工具与 Windows 11 Insider SDK 使用。同一篇公告披露,微软已使用 ARM64EC 重新构建了 Windows 11 on Arm 操作系统自身的二进制文件,使 x64 应用所加载的系统代码以原生速度运行;Office 团队也在面向 Arm 的 64 位 Office 中采用该技术,以便原有的 x64 插件可以继续工作。
该 ABI 随后被逐步纳入开发者工具链。Rust 语言以 arm64ec-pc-windows-msvc 作为目标平台,其支持依赖 LLVM 18 及以上版本,LLVM 18.1.0 加入对 Arm64EC 的初步支持,18.1.2 修正了导入库生成,18.1.4 修正了部分内建函数在链接时的问题;使用该目标需要安装含「ARM64/ARM64EC 生成工具」组件的 Visual Studio 2022 或更高版本以及 Windows 11 SDK[2]。此外,Arm 官方也提供介绍 ARM64EC 的技术资料,将其描述为允许在同一进程内混合 Arm64 与 x64 代码模块的 ABI[4]。
应用
该接口的主要用途是让已有的 x64 应用以渐进方式获得原生性能。开发者可以先挑出最耗 CPU 的模块或最耗时的部分,把它们由 x64 重新编译为 ARM64EC,其余部分继续以模拟方式运行,之后再逐步扩大重编译的范围,最终得到完全原生的 ARM64EC 应用[1]。这种方式解决了以往移植必须整体完成、否则用户无法获得收益的问题,并使得依赖不受自身控制的第三方 x64 组件的项目也能在 Windows on Arm 上构建应用。
对于进程内存在插件生态的程序,ARM64EC 尤为适用:应用主体以 ARM64EC 构建以获得原生速度,同时继续加载并使用 x64 插件。在面向 Arm 的 Windows 系统中,操作系统自身的多数系统代码也以 ARM64EC 编译,因此 x64 应用调用系统接口时无需自身感知,即可让这部分代码原生执行[1]。工具层面,C 代码可通过面向 Arm 的 MSVC 或 Clang 以 /arm64EC 编译并以 /MACHINE:ARM64EC 链接[2]。
局限
ARM64EC 的兼容范围有明确边界。它只保证与 x64 的互操作,与 Arm64 代码互不兼容,因此不能与 Arm64 库或 Arm64 二进制混用;在依赖选择上,使用 ARM64EC 重建应用时可以使用 ARM64EC 版依赖,也可以退而使用 x64 版依赖,但不能使用 Arm64 版依赖[1]。进程中被保留为 x64 的部分仍运行在模拟层,无法获得原生性能,只有逐步改用 ARM64EC 才能改善[1]。
平台与工具链层面也存在限制。该特性属于 Windows 11 功能,需要 Windows 11 SDK,在 Arm 版 Windows 10 上不可用[1]。由于 ARM64EC 只使用 AArch64 寄存器的一个子集、采用与 AArch64 不同的名字修饰方案并要求为部分函数生成转换块,已有的 AArch64 汇编只有部分可以在 ARM64EC 下复用[2]。
运行时行为上也有一些需要特别注意之处。ARM64EC 应用无法通过 VirtualAlloc 分配可执行页或用于运行时注入汇编,因为该 API 返回的是面向 x64 指令的页面,要获得面向 Arm64 指令的页面需改用带 MEM_EXTENDED_PARAMETER_EC_CODE 标志的 VirtualAlloc2;经 HeapCreate 与 HeapAlloc 分配的可执行内存同样只能执行 x64 指令[5]。此外,在 Arm 64 位 Windows 下由完全模拟的进程或部分模拟的 ARM64EC 进程调用 GetNativeSystemInfo 时,返回的处理器架构为 AMD64 而非 ARM64,以保持与被模拟二进制的兼容性[5]。
参见
-
Windows 11 —— ARM64EC 是其面向 Arm 设备提供的一项平台特性。
-
指令集架构 —— 决定应用二进制接口与代码兼容性的基础概念。
-
二进制兼容性 —— ARM64EC 试图在 x64 与 Arm64 之间建立的关系。
-
模拟器 —— x64 代码在 Arm 设备上执行所依赖的机制。
-
Visual Studio —— 构建 ARM64EC 目标所需的开发工具之一。
-
LLVM —— 支持生成 ARM64EC 目标的编译器后端。
参考资料
- Arm64EC for Windows 11 apps on Arm [引用日期2026-10-14]
- arm64ec-pc-windows-msvc [引用日期2026-10-14]
- title: "Overview of ARM64EC ABI conventions" [引用日期2026-10-14]
- Arm64EC - ABI for Mixing x64 and Arm64 [引用日期2026-10-14]
- Arm64EC [引用日期2026-10-14]