2

For the IA-32 architecture, an IDT entry has the following format:

struct IDTDescr {
   uint16_t offset_1; // offset bits 0..15
   uint16_t selector; // a code segment selector in GDT or LDT
   uint8_t zero;      // unused, set to 0
   uint8_t type_attr; // type and attributes, see below
   uint16_t offset_2; // offset bits 16..31
};

Why are offset_1 and offset_2 separated? Is it for the backward compatibility?

Harold H.
  • 57
  • 5

2 Answers2

3

Backwards compatibility with 8086 IVT (Interrupt vector table) entries. These consist of a 16-bit PC value and a 16-bit CS value -- exactly the same as the first two fields of the IDT entry.

Chris Dodd
  • 119,907
  • 13
  • 134
  • 226
  • 1
    Is that "compatibility" useful to software in any way? Maybe for entry 0, otherwise the different width means a different index. Or is this more likely just an artifact of the hardware design, and reusing hardware that fetches a new CS value from a fixed offset? – Peter Cordes Oct 04 '18 at 08:29
  • Mostly to minimize the amount of hardware needed -- the 80386 had to support both 16- and 32-bit mode, but only had one interrupt controller for both... – Chris Dodd Oct 04 '18 at 15:00
  • It's the CPU internals that fetch data from the IVT / IDT, though, after finding out from the PIC (or from an internal source) which interrupt number was raised. – Peter Cordes Oct 04 '18 at 16:19
  • So the software to initialize IVT in 8086 still cannot be directly used to initialize IDT in 80386 architecture, as the entry has a different size? The hardware to decode IDT entry could be quite simple, so I doubt reducing hardware is the only purpose of designing IDT in this way. – Harold H. Oct 04 '18 at 19:05
2

The unusual layout of fields can be traced to the need to keep the 386 protected mode upwardly compatible with the 80286 protected mode. Where the 386 needed larger fields, these grew into unused space on the 286. This results in the rather chaotic arrangement you now see,

This was useful since, early on, it was common to run 286 operating systems on 386 systems.

In the iAPX 286 Operating Systems Writers Guide you even see in Figure 2.6 Gate Descriptor there are fields marked as "Reserved for iAPX 386 Must be zero"

PS: IDT entries are just a special case of a descriptor entry.

Peter Camilleri
  • 1,882
  • 15
  • 17
  • Oh, did 286 16-bit protected mode use 8086-style entries + padding? 286 real mode was of course compatible with 8086. – Peter Cordes Oct 05 '18 at 18:23
  • The 8086 had 32 bit entries, The 286 expanded this to 64 bits with some reserved fields that had to be zero. – Peter Camilleri Oct 05 '18 at 18:43
  • Oh this might help: http://bitsavers.trailing-edge.com/components/intel/80286/121960-001_iAPX_286_Operating_Systems_Writers_Guide_1983.pdf – Peter Camilleri Oct 05 '18 at 18:45
  • But the real mode IVT format is still backward-compat with 8086, using 32-bit `seg:off` entries (https://wiki.osdev.org/IVT) to this day on modern x86 in real mode. 286 can only be different in 286 protected mode, not in real mode. So my key point is that your answer should probably say that you're talking about the IDT in 286's 16-bit protected mode (which is not normally used on modern x86). It makes sense that they'd use a power-of-2 size for an entry, and not need all of it. Neat that they say "reserved for 386" instead of just "reserved", nice find. – Peter Cordes Oct 05 '18 at 18:54