bochs 中文文档 下载 App

x86-64 与 AMD64 支持——从 32 位到 64 位的关键扩展

什么是 x86-64

x86-64(AMD 叫 AMD64,Intel 叫 EM64T)是 x86 架构从 32 位扩展到 64 位的路线。与 Intel 自己的 Itanium(IA-64)不同,x86-64 是向后兼容的——能直接跑 32 位 x86 代码,也能跑新的 64 位代码。

Bochs 对 x86-64 的模拟实现了完整的 64 位模式行为,OS 开发者可以用 Bochs 调试 64 位内核。

编译开关

x86-64 支持默认关闭,编译时必须显式开启:

./configure --enable-x86-64

编译完在 bochsdbg 里运行 show feature 确认:

bochs:1> show feature
feature: x86-64

没开的话 Bochs 模拟的 CPU(哪怕 model=pentium4)也不会进 64 位模式。

bochsrc 里的 CPU model

开了 x86-64 编译开关后,bochsrc 里 CPU model 选 pentium4 或更高就会有 64 位能力:

cpu: model=pentium4, count=1, ips=15000000

Bochs 会自动在 CPUID 里暴露 EM64T 标志,操作系统就能检测到支持 64 位模式。

如果选 model=coreduo、model=nehalem 等更新的型号,还会额外暴露 SSE3、SSSE3、SSE4、VT-x 等扩展。

x86-64 关键变化

通用寄存器:8 个变 16 个

旧名(32 位)新名(64 位)
EAXRAX
EBXRBX
ECXRCX
EDXRDX
ESIRSI
EDIRDI
EBPRBP
ESPRSP
—R8 ~ R15(新增)

新增的 R8-R15 寄存器没有 32 位别名,但可以用 R8D-R15D(32 位低半)、R8W-R15W(16 位低半)、R8B-R15B(8 位低半)访问。Bochs 调试器的 info registers 会全部显示。

地址空间:32 位变 64 位

32 位下每个进程虚拟地址空间 4GB,内核和用户共享地址空间;x86-64 下:

Bochs 完整模拟这个地址空间分割。调试内核页表时 CR3 指向的 PML4 表、四个级别的页表遍历都和真实硬件一致。

REX 前缀

所有访问 R8-R15 或 64 位寄存器的指令都需要一个 REX 前缀(编码在 opcode 之前的 4 位标志)。这是 x86-64 引入的新机制,Bochs 的指令解码器完整实现了它。

OS 开发者在看 64 位反汇编时会频繁看到这个前缀。Bochs 的 u(disassemble)命令会正确把 REX 前缀解析出来,不会把它当作一条独立指令。

syscall / sysret

x86-64 引入了新的快速系统调用指令 syscall / sysret,替代了老的 int 0x80 / iret(int 0x80 在 64 位模式下仍然可用但慢得多)。

Bochs 正确模拟 syscall 行为:

调试器里在 syscall 上下断点可以追踪每一次系统调用。

FS/GS 段寄存器的角色变化

64 位模式下 CS/DS/ES/SS 段寄存器被"弱化"(变成"空选择子",段基址强制为 0、段限强制为最大值),但 FS 和 GS 被强化——内核可以用它们放 per-CPU 数据(Linux 里 GS 指向 per-CPU 区域)。

Bochs 正确模拟 FS/GS 的 64 位段基址——通过 wrmsr 指令写入 FS_BASE / GS_BASE MSR 来设置。

调试器里怎么看 64 位寄存器

在 bochsdbg 里:

bochs:1> info registers
CPU0:
rax=0000000000000000 rbx=0000000000000000 rcx=0000000000000000
rdx=0000000000000000 rsi=0000000000000000 rdi=0000000000000000
rbp=0000000000000000 rsp=0000000000000000
 r8=0000000000000000  r9=0000000000000000 r10=0000000000000000
r11=0000000000000000 r12=0000000000000000 r13=0000000000000000
r14=0000000000000000 r15=0000000000000000
rip=0000000000000000 eflags=00000002

64 位模式下所有寄存器都是 64 位宽,调试器显示时用 16 进制。

32 位和 64 位的互操作

Bochs 在 x86-64 模式下同时支持:

内核从传统模式切换到长模式的经典步骤(OS 开发者必过):打开 CR4.PAE → 打开 CR0.PG → 加载 PAE 页表 → 打开 EFER.LMA → 跳转清除预取队列。Bochs 完整支持这条路径,可以在每一步下断点验证寄存器状态。