ARM64EC混合代码:让Madeira iOS x86模拟器高速运行的秘密武器
【免费下载链接】MadeiraRun x86-64 Windows PC games on jailed iOS via FEX-Emu + Wine + DXMT项目地址: https://gitcode.com/GitHub_Trending/mad/Madeira
Madeira 是一个让x86-64 Windows PC 游戏在不越狱的 iPhone 上直接运行的开源实验项目,而它高速运行的核心正是ARM64EC 混合代码:Wine 系统层被编译为 ARM64EC 原生代码,直接跑在 Apple 芯片上,FEX-Emu 只需实时翻译游戏自身的 x86-64 指令,把模拟开销降到了最低。本文带你了解这套架构的原理、关键组件,以及 32 位游戏如何通过 WoW64 一并支持。
什么是 ARM64EC 混合代码?
ARM64EC 是微软在 Windows on ARM 中推出的一种混合(Hybrid)指令格式:
- 大部分函数体是原生 ARM64 指令,速度等同于本地代码;
- 少数需要与 x86-64 代码交互的入口,保留x64 兼容的调用约定("EC" = Emulation Compat);
- 结果是一个 DLL同时包含两种代码,ARM 侧原生调用、x64 侧兼容调用,各走各的路。
对模拟器项目来说,这是理想形态:系统库不用翻译,玩家代码才需要翻译。
为什么 Madeira 能跑得快
传统方案是把整个 Windows 用户态都翻译成 ARM 指令——包括大量游戏用不到的系统调用路径。Madeira 的做法是反其道而行:
| 层 | 运行方式 |
|---|---|
| Wine 11.4(ARM64EC 构建) | 系统 DLL 以原生 ARM64 代码直接执行,零翻译开销 |
FEX-Emu(xtajit64.dll) | 只翻译游戏自己的 x86-64 代码,JIT 成 ARM64 |
| 32 位程序 | WoW64 层原生执行,仅翻译 x86 指令 |
正如 README.md 中所述:"Wine 为 ARM64EC 构建,所以 Wine 本身原生运行,只有游戏自己的代码被翻译"。
混合系统如何协作
启动路径由 WineProcessBridge.m 决定:64 位游戏目标(如cube-x64、真实游戏)会自动加载arm64ec-windows包,其中的系统 DLL 都是 ARM64EC 混合模块,能与 FEX 翻译出的 x86-64 代码互相调用。
几个关键设计点:
- JIT 池双映射:所有执行代码来自同一块 RX/RW 双映射的 JIT 池,见 JITAllocator.h,ARM64EC 加载器打补丁镜像
.rdata时依赖这套机制; - ARM64EC 模块保持字节一致:FEX 的 ARM64EC 模块(
xtajit64.dll)与上游构建完全相同,每次 PR 都用反汇编校验,见 docs/WOW64.md 第 2 节; - 原生 DLL 农场地:app/Madeira/arm64ec-windows/ 下的每个文件都会被链接进 Wine 前缀(
system32/sysx64),模块在这里,游戏才能用上它,构建细节见 docs/BUILDING.md; - VC++ 运行时覆盖:微软官方 x64 运行时 DLL 会以符号链接形式覆盖 ARM64EC 内置实现,让游戏直接调用微软原版而非部分重实现。
32 位游戏:WoW64 再进一步
老游戏多为 32 位 x86。Madeira 完全复刻 Windows on ARM 的 WoW64 方案:wow64.dll、wow64win.dll作为原生 aarch64 代码运行,只有程序的 x86 代码交给 FEX 的 WOW64 模块(xtajit.dll)翻译。
这套设计要解决 iOS 特有的难题(4 GB__PAGEZERO硬限制、单一 Mach 任务内的伪进程隔离等),文档 docs/WOW64.md 给出了完整的约束分析、"guest window" 地址窗口设计与全部开关清单,是很好的进阶阅读材料。
原生 D3D12:x86 客端调用 ARM64 硬件
图形栈是混合代码收益最明显的地方。项目自带 madeira-d3d12/ 目录,实现了一个原生 Direct3D 12 运行时:
d3d12.dll与madeira_d3d12.dll均为IMAGE_FILE_MACHINE_ARM64ECPE 镜像,直接放在 app/Madeira/arm64ec-windows/ 中;- x86-64 客端游戏通过 ARM64EC 入口零翻译地调用它;
- DXIL 着色器在运行时用 Apple 的 Metal Shader Converter 转成 Metal,实测 M4 Max 上首次转换约1.0 ms、缓存命中0.4 ms(见 madeira-d3d12/README.md)。
也就是说:从游戏画一个三角形,到 Apple GPU 执行 Metal 着色器,中间几乎没有一条 x86 指令需要被翻译。
相关文档与源码入口
| 内容 | 路径 |
|---|---|
| WoW64 / 32 位游戏设计 | docs/WOW64.md |
| 从源码构建(含 ARM64EC 构建链) | docs/BUILDING.md |
| Wine 分支与 ARM64EC 移植提交记录 | docs/wine-lgpl-provenance.md |
| 原生 D3D12 实现说明 | madeira-d3d12/README.md |
| 64 位启动与包选择逻辑 | app/Madeira/WineProcessBridge.m |
| 64 位 ARM64EC DLL 农场地 | app/Madeira/arm64ec-windows/ |
| 32 位 DLL 农场地 | app/Madeira/i386-windows/ |
总结
ARM64EC 混合代码让 Madeira 实现了"能原生的绝不翻译":Wine 系统层、WoW64 桥接层和 D3D12 运行时全部以原生 ARM64 执行,FEX 的 JIT 火力集中翻译游戏本体。这套分层策略正是 iPhone 上跑 PC 游戏性能的关键所在 🚀。项目仍在快速迭代中,兼容性因游戏而异,建议关注 docs/ 目录下的文档了解最新进展。
【免费下载链接】MadeiraRun x86-64 Windows PC games on jailed iOS via FEX-Emu + Wine + DXMT项目地址: https://gitcode.com/GitHub_Trending/mad/Madeira
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考