在 16 位模式下启动时获取 x86 CPU 支持的 "bitness"
Get the supported "bitness" of an x86 CPU when booted in 16-bit mode
我正在开发一个 x86 引导加载程序并且遇到了这个问题(我想这应该很简单,但到目前为止我还没有能够解决):我想检测 CPU 主机(例如,如果它仅支持 16 位,或支持 32 位或 64 位)。
我使用了 CPUID 指令,但它是在 486 中引入的,因此对于检测仅 16 位与支持 32- 的 386 兼容 CPU 没有帮助位保护模式(或带前缀的实模式中的 32 位操作数大小)。
检查 32 位(参见 http://www.rcollins.org/ddj/Sep96/Sep96.html):
- 16 位 CPUs 无保护模式 (8088/8086/80186) 在执行
pushf
[= 时将始终设置标志寄存器的高 4 位 (15-12) 32=]
- 80286 将始终在
pushf
上清除高 4 位(当 运行 处于实模式时)
- CPUs 支持 32 位允许在实模式下使用
popf
修改高 4 位(但是所有 4 位应具有相同的值 - 全部设置或全部清除)
通过使用 pushf
、popf
并修改堆栈中的数据,您检查是否可以修改高 4 位;如果是,则必须是 32 位 CPU.
正在检查 CPUID
:
- 确保 CPU 支持 32 位(见上文)
- 切换到 32 位模式
- 检查 EFLAGS 的第 21 位是否可以修改(设置和清除);如果该位的值不固定(可以从 0 更改为 1,反之亦然),则支持
cpuid
指令。
我正在开发一个 x86 引导加载程序并且遇到了这个问题(我想这应该很简单,但到目前为止我还没有能够解决):我想检测 CPU 主机(例如,如果它仅支持 16 位,或支持 32 位或 64 位)。
我使用了 CPUID 指令,但它是在 486 中引入的,因此对于检测仅 16 位与支持 32- 的 386 兼容 CPU 没有帮助位保护模式(或带前缀的实模式中的 32 位操作数大小)。
检查 32 位(参见 http://www.rcollins.org/ddj/Sep96/Sep96.html):
- 16 位 CPUs 无保护模式 (8088/8086/80186) 在执行
pushf
[= 时将始终设置标志寄存器的高 4 位 (15-12) 32=] - 80286 将始终在
pushf
上清除高 4 位(当 运行 处于实模式时) - CPUs 支持 32 位允许在实模式下使用
popf
修改高 4 位(但是所有 4 位应具有相同的值 - 全部设置或全部清除)
通过使用 pushf
、popf
并修改堆栈中的数据,您检查是否可以修改高 4 位;如果是,则必须是 32 位 CPU.
正在检查 CPUID
:
- 确保 CPU 支持 32 位(见上文)
- 切换到 32 位模式
- 检查 EFLAGS 的第 21 位是否可以修改(设置和清除);如果该位的值不固定(可以从 0 更改为 1,反之亦然),则支持
cpuid
指令。