Hacker News new | past | comments | ask | show | jobs | submit login

> Since there are six 16-bit segment registers in the 386, I suspect these are the segment registers and two mystery registers.

I'm no expert...but I'd guess the 2 mystery registers are for scratch use by the microcode. When executing CALL, INT, etc. in protected mode, a '386 chip can easily burn 200-300 clocks on just that one assembly instruction. Lord knows how many corner cases there might be, when various things go wrong mid-instruction.




Yes, that's very possible that the mystery registers are scratch registers. But there are lots of other possibilities too.


A related idea - if the circuitry around all 8 (16-bit registers) is the same...I'd wonder if the '386 might actually have 8 segment registers - 6 user-accessible, and 2 more reserved for the microcode. The latter mostly used when navigating some of the more "interesting" states transitions which the '386's paging / protection / segmentation architecture allows.


The microcode hardly needs the segment selector registers. It uses the descriptor cache which includes the base, limit and access rights of the 6 segments + GDTR, IDTR, LDTR and TR. The descriptor cache is update by the MOV to segment and L{GDT,IDT,LDT,TR} instructions.


I would put my bet on LDTR and TR. They are read and written with different instructions but they are 16 bit and closely related to segment registers (they index into the GDT).


That seems the most likely to me as well, since they also have a 16 bit selector field that has to be stored.

The 286 already had 8 "segment registers" internally: ES, CS, SS, DS, GDT, LDT, IDT & TSS. Only the first four are directly accessible by the program, but to the microcode they should all be more or less identical.

Besides the layout of the saved CPU state in memory, another clue to this is that for exceptions involving both "normal" and "system" segment registers, an error code gets stored in one of the internal registers, indicating which segment caused it. The only way to read it out in software is by executing the undocumented STOREALL instruction (F1 0F 04) immediately after the reset from a triple-fault shutdown.

The codes that appear in this register are:

     6CFFh GDT
     6DFFh LDT
     6EFFh IDT
     6FFFh TSS
     70FFh ES
     73FFh DS
CS and SS should be 71h / 72h, however exceptions involving these segments seem to take a different microcode path that overwrites that register with the access rights for CS.

I have written about this here: https://rep-lodsb.mataroa.blog/blog/the-286s-internal-regist...

And this article shows the bus cycles done by LOADALL on the 386, note that it also loads 10 internal registers:

http://www.rcollins.org/articles/loadall/tspec_a3_doc.html


Right, the 386 has 10 internal segment descriptor caches but only 8 segment selector registers. The 286 had 8 and 6 respectively.

But wait, HIMEM.SYS used LOADALL to avoid going into protected mode and back?!? When you thought you knew everything (which I absolutely don't, but I knew it used big real mode on the 386 and I totally didn't expect LOADALL).

> More useful is the ability to load any arbitrary base address for the segment registers without entering protected mode. Some versions of Microsoft's HIMEM.SYS did this to copy data between real and extended memory.

It is also explained at https://www.os2museum.com/wp/himem-sys-unreal-mode-and-loada...




Consider applying for YC's Spring batch! Applications are open till Feb 11.

Guidelines | FAQ | Lists | API | Security | Legal | Apply to YC | Contact

Search: