X86 为什么中断描述符表(IDT)中的偏移位被分成两个字段?

X86 为什么中断描述符表(IDT)中的偏移位被分成两个字段?,x86,cpu-architecture,X86,Cpu Architecture,对于IA-32体系结构,IDT条目具有以下格式: 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

对于IA-32体系结构,IDT条目具有以下格式:

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
};

为什么
offset_1
offset_2
是分开的?是为了向后兼容吗?

与8086 IVT(中断向量表)项向后兼容。这些由16位PC值和16位CS值组成,与IDT条目的前两个字段完全相同。

字段的不寻常布局可以追溯到需要保持386保护模式与80286保护模式向上兼容。如果386需要更大的字段,这些字段就会扩展到286上未使用的空间。这导致了你现在看到的相当混乱的安排

这很有用,因为在早期,在386个系统上运行286个操作系统是很常见的

在iAPX 286操作系统编写器指南中,您甚至可以在图2.6门描述符中看到标记为“为iAPX 386保留的字段必须为零”的字段


注:IDT条目只是描述符条目的一个特例。

这种“兼容性”对软件有用吗?可能对于条目0,否则不同的宽度意味着不同的索引。或者这更可能只是硬件设计的产物,并且重用从固定偏移量获取新CS值的硬件?主要是为了最小化所需的硬件量——80386必须同时支持16位和32位模式,但两种模式都只有一个中断控制器……从IVT/IDT获取数据的是CPU内部,尽管如此,在从PIC(或从内部源)发现哪个中断号被触发后,8086中初始化IVT的软件仍然不能直接用于初始化80386体系结构中的IDT,因为条目的大小不同?解码IDT条目的硬件可能非常简单,因此我怀疑减少硬件是以这种方式设计IDT的唯一目的。哦,286 16位保护模式是否使用了8086样式的条目+填充?286实模式当然与8086兼容。8086有32位条目,286将其扩展为64位,其中一些保留字段必须为零。哦,这可能会有所帮助:但实模式IVT格式仍然向后兼容8086,直到今天在现代x86实模式下使用32位
seg:off
entries()。286只能在286保护模式下不同,而不能在实模式下不同。因此,我的关键点是,您的答案可能应该是,您正在谈论的是286的16位保护模式下的IDT(这在现代x86上通常不使用)。这是有道理的,他们会使用2次方大小的条目,而不需要全部。他们说“为386保留”而不是“保留”,这真是太好了,很好的发现。