bochs 中文文档 下载 App

CPU 指令集模拟——从 386 到 x86-64 每代覆盖哪些特性

Bochs 的 CPU 模型设计哲学

Bochs 的 CPU 不是一个"黑盒"——它内部有完整的指令解码器、微指令执行器、寄存器文件、特权级切换逻辑、TLB、预取队列。这种细粒度建模带来了巨大的开销,但换来了:

指令集覆盖情况

Bochs 模拟的指令集扩展按 CPU model 自动选择启用。

基础集(所有 model 都有)

MMX(Pentium 及以上)

8 个 MMX 寄存器(mm0-mm7,别名 FPU 栈),支持:

SSE(Pentium III 及以上)

8 个 XMM 寄存器(xmm0-xmm7):

SSE2(Pentium 4 及以上)

在 SSE 基础上扩展:

SSE3 / SSSE3 / SSE4.x / AVX / AVX2 / AVX-512

后续版本逐步支持,Bochs 会根据 model 自动启用。AVX 引入 16 个 YMM 寄存器(256 位),AVX-512 引入 32 个 ZMM 寄存器(512 位)。

x86-64(AMD64 / EM64T)

32 位模式基础上的扩展,核心变化:

注意:x86-64 支持需要编译时 --enable-x86-64 开关,bochsrc 里 CPU model 选 pentium4 或更高就会打开。

特权级模型

Bochs 正确实现了 x86 的四个特权级(CPL 0 ~ 3):

CPL典型使用特权
0内核(Ring 0)全部指令、全部 I/O、全部寄存器
1/2旧式 OS 使用部分特权指令
3用户态(Ring 3)普通指令,访问受限

特权级切换通过:

Bochs 调试器可以观察到每一次特权级切换——在 bochsdbg 里设置 watchpoint 跟踪 CR3 变化就能跟踪进程/内核切换。

编译时未实现指令

某些非常新的指令集扩展(如 AMX、AVX-512 VPTERNLOG)在 Bochs 里可能是 stub——遇到时会触发 #UD(invalid opcode)异常。OS 开发时如果内核触发了这个异常,检查:

  1. bochsrc 里的 CPU model 是不是太旧了?(换成 alderlake 或更新)
  2. 编译时有没有开对应的扩展?(如 --enable-avx)
  3. Bochs 版本是不是太旧了?(检查 Bochs 3.x 的 change log)

可以在 bochsrc 里加 cpu: ... exception_on_unimplemented=1 让 Bochs 遇到未实现指令时抛出可诊断异常而不是静默跳过。

和真实硬件的差异

Bochs 是模拟,不是完美复刻。有几个已知的行为差异:

对 OS 内核开发来说这些差异不重要——内核不依赖指令延迟,只依赖架构行为。对逆向工程和精确性能分析来说可能有影响。