同一款游戏,为什么要分 ARM64 和 x64 版本?
在 PortGames 找到一款想玩的游戏后,你可能会看到面向不同设备的几个项目。为什么原来的游戏文件不能直接拿过来用?CPU 指令集,是其中一道需要跨过的门槛。
作者 zing · 发布于 · 来源核对
同样的游戏内容,为什么还要重新做程序?
假设一款游戏已有 Windows/x64 版本,现在想让它在 ARM64 设备上运行。地图、贴图等数据可能继续使用,但游戏程序里已经编译好的机器指令,是按原处理器的规则生成的。换一种 CPU,这些指令通常不能原样执行。
项目有源代码时,开发者可以为新目标重新编译,并适配所需接口;只有现成程序时,也可能借助二进制转译与其他兼容实现。这是同一款游戏会出现不同移植或兼容路线的一个原因。
这里的 ARM64、x64,主要在区分指令集架构(ISA):CPU 能识别哪些机器指令、每条指令做什么,以及程序能使用哪些寄存器。寄存器是 CPU 运算时直接使用的小块存储。
微架构则是芯片内部怎样解码、调度和执行这些指令。同一种指令集可以有不同的芯片实现,所以两个项目都写“支持 ARM64”,并不能据此推断它们在不同机型上的速度相同。软件是否能运行和具体跑得怎样,是两个需要分别回答的问题。
移植时,ARM64 与 x64 到底换了什么规则?
这里比较的是当下常见的两套 64 位指令集:ARM64 通常对应 AArch64,使用 A64 指令;x64 通常指 x86-64,也叫 AMD64。 “x86”也可以泛指整个家族,安装包里的“x86”则经常特指 32 位版本,不能和 x64 一概混用。
| 比较项 | ARM64 / AArch64 | x64 / x86-64 |
|---|---|---|
| 指令怎样编码 | A64 每条指令固定为 4 字节 | 指令长度可变,为 1~15 字节 |
| 运算时怎样访问数据 | 常规算术主要操作寄存器,访问内存使用加载/存储指令 | 许多运算指令可以带内存操作数 |
| 程序看到的规则 | 自己的指令编码、寄存器和执行规则 | 另一套编码、寄存器和执行规则 |
两边都能做加法、循环和读取数据,差别在于怎样把这些要求写成机器能执行的指令。即使只想“把一个数加 1”,汇编写法也不同:
x86-64(Intel 写法): ADD RAX, 1
AArch64: ADD X0, X0, #1
这只演示数值加 1;两条指令对标志位(记录零值、进位等运算状态)的影响并不完全相同,不能把它们当成完整的一对一替换规则。CPU 实际读取的是二进制编码,也不是这些方便人阅读的文字。
还有一个常见误会:64 位并不表示每条指令都长 64 位。A64 使用 64 位通用寄存器,却采用 32 位的指令编码。编码长度本身也不能直接推出速度或耗电,芯片实现、制造工艺和工作负载同样重要。
没有原生版本时,转译替游戏解决了哪一步?
转译器可以先理解原游戏程序的指令效果,再生成目标 CPU 能执行的代码。这叫二进制转译,不要求手里有游戏源码。它为现成程序跨过 CPU 指令差异提供了一条路线。
例如,在 ARM64 设备上运行一段 x86-64 程序时,动态转译器通常会读取一段原代码,解析它的操作,生成相应的 ARM64 代码,再交给真实 CPU 执行。原程序的寄存器值、内存访问和分支结果需要正确保持;实现同一种效果,可能用到多条目标指令或辅助函数。
已经转换好的代码还可以放进缓存。在代码与相关状态仍适用时,再次执行这段逻辑就能复用结果,不必每次重新转换。微软对 Windows on Arm 的说明、QEMU 的转译文档都描述了代码块转换与复用机制。
实际执行的始终是目标 CPU 自己支持的指令。 “跨架构运行”来自软件把行为转换正确,不是 ARM CPU 突然学会直接解码所有 x86 指令。
同为 ARM64,为什么 Mac 版也不能直接装到手机?
CPU 指令只是其中一层。游戏还要创建窗口、绘制画面、播放声音和读取操作,这些工作会调用操作系统与图形接口。即便两台设备都使用 ARM64,也不意味着它们接受相同的程序文件、系统调用或操作方式。
例如,一个 Windows 游戏即使解决了 x64 到 ARM64 的指令转换,也不会因此自动变成 Android 游戏;Mac 与 iPhone 的程序也不能只凭“都是 ARM64”就互换。原生移植需要适配目标系统,兼容方案则可能还要提供系统或图形接口的转换。Wine 的 Windows API 实现就是这类接口兼容工作的一个例子,它与 CPU 指令转译需要分开理解。
因此,PortGames里的“原作来自”和“在哪玩”是两个维度。原作来自 PC,并不表示项目一定面向 Windows;项目列出 ARM64,也不能代替具体系统、机型与运行记录。相同指令集解决的是一部分兼容条件,不是整款游戏的运行保证。
这也是阅读移植资料时需要保留设备条件的原因:指令集说明程序面向的计算规则,系统与图形支持说明它接得上哪些接口,运行记录才描述某个设备、版本和场景下已经观察到的结果。
Arm · Instruction set architecture and microarchitecture · Arm · A64 Instruction Set Architecture Guide · Intel · X86 Encoder Decoder User Guide · Intel · Architecture and instruction manuals · QEMU · Translator internals · QEMU · System call translation · Microsoft · How emulation works on Arm · Microsoft · ARM64 ABI conventions · Wine · Windows API implementation
资料依据
- Arm · Instruction set architecture and microarchitecture
- Arm · A64 Instruction Set Architecture Guide
- Intel · X86 Encoder Decoder User Guide
- Intel · Architecture and instruction manuals
- QEMU · Translator internals
- QEMU · System call translation
- Microsoft · How emulation works on Arm
- Microsoft · ARM64 ABI conventions
- Wine · Windows API implementation