Matt Tennant
Matt Tennant

Reputation: 33

Get the supported "bitness" of an x86 CPU when booted in 16-bit mode

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).

Upvotes: 2

Views: 360

Answers (1)

Martin Rosenau
Martin Rosenau

Reputation: 18523

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.

Upvotes: 1

Related Questions