问题
I am developing an x86 bootloader and have come across this problem (which I guess should be pretty straightforward, but so far I haven't been able to solve): I want to detect the bitness of the CPU host (e.g. if it's 16bit-only, or supports 32bit or 64bit).
I have used the CPUID instruction, but it was introduced with 486 so doesn't help for detecting 16-bit-only vs. a 386-compatible CPU that supports 32-bit protected mode (or 32-bit operand-size in real mode with prefixes).
回答1:
Checking for 32-bits (see http://www.rcollins.org/ddj/Sep96/Sep96.html):
- 16-bit CPUs without protected mode (8088/8086/80186) will always have the upper 4 bits (15-12) of the flags register set when doing
pushf
- 80286 will always have the upper 4 bits clear on
pushf
(when running in real mode) - CPUs supporting 32-bit allow modifying the upper 4 bits in real mode using
popf
(however all 4 bits should have the same value - all set or all clear)
By using pushf
, popf
and modifying the data on the stack you check if it is possible to modify the upper 4 bits; if yes, it must be a 32-bit CPU.
Checking for CPUID
:
- Ensure the CPU supports 32-bit (see above)
- Switch to 32-bits mode
- Check if bit 21 of EFLAGS can be modified (set and cleared); if the value of that bit is not fixed (it can be changed from 0 to 1 or vice versa) the
cpuid
instruction is supported.
来源:https://stackoverflow.com/questions/47715574/get-the-supported-bitness-of-an-x86-cpu-when-booted-in-16-bit-mode