Hacker News new | ask | show | jobs
by atq2119 2817 days ago
I recall reading that it's not that those 12 bits are explicitly asserted, but rather that the CS descriptor after reset is in an "unreal mode". After all, x86 segment descriptors consist not just of their numeric value, but also of a base address, segment size, and privilege information.

So at reset, CS is set to a descriptor whose numeric value is 0xf000 and whose base address is 0xffff0000, or something to that effect. All the rest follows naturally -- there's no special case logic that asserts lines of the address bus until the first long jump, it's simply that the reset value of the CS descriptor is rather magical, and that long jumps by their nature load a new CS segment descriptor which isn't magical.

2 comments

Yes, initial CS descriptor has base FFFF0000 and limit 0000FFFF, and initial EIP is FFF0. Paging is disabled so first instruction is fetched from physical address FFFFFFF0. This has been true since the 386.

See 386 datasheet, page 20:

https://media.digikey.com/pdf/Data%20Sheets/Intel%20PDFs/Int...

The 8086/8088 is slightly different since it doesn't have protected mode; initial CS:IP is FFFF:0000 which gives a first address of FFFF0. The 286 is closer to the 386+ but its 24-bit address space means the first instruction comes from FFFFF0 instead.

this is interesting! i am not aware of how this logic is implemented, i.e. the logic of initial state where 12 most significant bits but thanks for enlightening
I looked it up:

https://software.intel.com/en-us/articles/intel-sdm#nine-vol...

Get volume 3A and read chapter 9.1.4 at pg 315. The text is quite readable:

  The address FFFFFFF0H is beyond the 1-MByte addressable range of the processor while in real-address mode. The
  processor is initialized to this starting address as follows. The CS register has two parts: the visible segment
  selector part and the hidden base address part. In real-address mode, the base address is normally formed by
  shifting the 16-bit segment selector value 4 bits to the left to produce a 20-bit base address. However, during a
  hardware reset, the segment selector in the CS register is loaded with F000H and the base address is loaded with
  FFFF0000H. The starting address is thus formed by adding the base address to the value in the EIP register (that
  is, FFFF0000 + FFF0H = FFFFFFF0H).
Any change to CS reverts this to normal real mode operation. So near jumps are OK, far jumps or interrupts are not.
Speaking of readability, here's a readable copy of that quote:

> The address FFFFFFF0H is beyond the 1-MByte addressable range of the processor while in real-address mode. The processor is initialized to this starting address as follows. The CS register has two parts: the visible segment selector part and the hidden base address part. In real-address mode, the base address is normally formed by shifting the 16-bit segment selector value 4 bits to the left to produce a 20-bit base address. However, during a hardware reset, the segment selector in the CS register is loaded with F000H and the base address is loaded with FFFF0000H. The starting address is thus formed by adding the base address to the value in the EIP register (that is, FFFF0000 + FFF0H = FFFFFFF0H).

(Don't use indentation to format a block quote, only use it for code listings.)

Practically, nearly all code I've seen pretty much immediately far jumps into 32-bit protected mode.