HALICERY

free-time coding, hardware dev, articles

Top
Home 8042 Blogs About
Home IntelEssential The 386: IA-32 Protected Mode IntelEssentialSelector

Last modified: Sun Jun 28 19:34:53 UTC+0200 2026 © A. Tarpai


The Descriptor look-up mechanism

The SELECTOR

15                     2 1 0
+---------------------+-+-+-+
| 8192 selector index |T|RPL|
+---------------------+-+-+-+

T - TABLE INDICATOR (T=1 Local)
RPL - REQUESTOR'S PRIVILEGE LEVEL

Higher 13-bit Selector index is the offset itself of 8-byte Descriptor structures. The CPU simply adds this 16-BIT OFFSET (with T- and RPL-bits zeroed) to the GDTR.BASE/LDTR.BASE stored on-chip to get the linear address of a descriptor to fetch:

                                            15                     2 1 0
                                            +---------------------+-+-+-+
                                            | 8192 selector index |T|RPL|
                                            +---------------------+-+-+-+
                                                        |
                                                        v
                                            15                          0
                                            +---------------------+-----+
                                            |                     |0 0 0|   16-BIT OFFSET
                                            +---------------------+-----+
                                                        |  LIMIT/ACCESS
                                                        |     CHECK
                                                        v
    31           23                                                     0
    +------------+------------------------------------------------------+
    |                 286 24-BIT/386 32-BIT GDTR.BASE/LDTR.BASE         |
+   +------------+------------------------------------------------------+
_____________________________________________________________________________________

    31           23                                                     0
    +------------+------------------------------------------------------+
    |         24-BIT/32-BIT LINEAR ADDRESS OF 8-BYTE DESCRIPTOR         |
    +------------+------------------------------------------------------+

GDTR.BASE/LDTR.BASE is a linear byte-address.

Segment Descriptor look-up

Without going into RPL/CPL/DPL. Assume all zero, the highest privilege.

When PE=1 in MSW and one of the SR is written, the 16-bit value is interpreted as a Selector:

Segment Descriptor look-up mechanism

              WRITE CS/DS/ES/SS..

               15            0
               +-------------+
               |  idx  |T|RPL|
               +-------------+
                       / \
                  T=0 /   \ T=1
                     /     \
                    /       \
              GDTR.LIMIT   LDTR.LIMIT
                CHECK        CHECK
                 /             \
                /               \
         GDTR.BASE             LDTR.BASE
              /                   \
             /                     \
           GDT                     LDT

    idx +------+            idx +------+
     0  |  --  |             0  |SEG De|
        +------+                +------+
     8  |SEG De|             8  |SEG De|
        +------+                +------+
    16  |SEG De|            16  |      |
        +------+                   ..
    24  |LDT De|                |      |
        +------+                +------+
    32  |      |                 max 64K
           ..
        |      |
        +------+
        |      |
        +------+
         max 64K

Note that there is no *null-selector* in the LD Table.

The null-selector

CPU never reads this 8-byte memory area in the GDT and there is no need to allocate memory space for it either (GDTR.BASE can safely address 8 bytes below the table).

T=0:
CPU expects and will look look up a Segment Descriptor in the Global Table (GDT) in memory. GDTR.BASE is in the on-chip GDT Register (GDTR). GDTR can be loaded only from memory, from 3 words using the LGDT [mem] instruction.

T=1:
CPU expects and will look look up a Segment Descriptor in the Local Table (LDT) in memory. LDTR.BASE is in the on-chip LDT Register (LDTR). LDTR is loaded from a "LDT" descriptor in the GD Table by writing a selector value into the LDT Register (LDTR) with the LLDT r/m16 instruction – or automatically on task-switch. The LDT Descriptor stores BASE-LIMIT.

Finally the CPU caches the valid Segment Descriptor (BASE-LIMIT-AR).

Interrupt Descriptor look-up

For Interrupt Gate-type Descriptors the mechanism is essentially the same:

Interrupt Descriptor look-up mechanism

         7      0
         +------+
         |Vector|
         +------+
           | <<3
           |
  15       |    0
  +-------------+
  |  idx     000|  16-BIT OFFSET
  +-------------+
           |
           |
           |
        IDTR.LIMIT
         CHECK
           |
        IDTR.BASE
           |
           |

          IDT

   idx +------+
    0  |      |  ---> handler entry point int 0
       +------+
    8  |      |  ---> handler entry point int 1
       +------+
   16  |      |
       +------+
   24  |      |
          ..
       |      |
       +------+
  2040 |      |  ---> handler entry point int 255
       +------+
        max 2K

The received 8-bit vector is a Selector (by shifting left by 3): CPU expects and will look look up a Gate-type Descriptor (Int/Trap/Task) in the Interrupt Descriptor Table (IDT) in memory. IDTR.BASE is in the on-chip IDT Register (IDTR). IDTR can be only loaded from 3 words in memory with the LIDT [mem] instruction.

The Descriptor stores the entry point for the interrupt handler. Privileges, types.. then transfer execution. Note there is no global/local here, only one table (max 2KB, interrupt vectors since 8086 are 8-bit). Int 0-31 are exceptions, reserved, raised by CPU. But fully possible to invoke one with eg. INT 7.