是否有关于如何布置全局描述符 Table 条目的约定?

Is there a convention for how Global Descriptor Table entries should be laid out?

操作系统是否有约定的约定来指定每个 table 索引应描述的内容?例如,在 Windows 系统上(如 here 所述),条目 4 描述了 32 位用户模式代码 (RPL = 3),条目 6 描述了 64 位用户模式代码。这是约定吗?其他条目呢?

x86-64 syscall/sysret 和 32 位 sysenter/sysexit,显然 do 关心GDT 条目的顺序:内核 CS、内核数据、用户 CS、用户数据的顺序。 (感谢@Brendan 的详细信息。)或者至少,syscall 将固定值加载到 CS 和 SS 内部状态:

SYSCALL loads the CS and SS selectors with values derived from bits 47:32 of the IA32_STAR MSR. However, the CS and SS descriptor caches are not loaded from the descriptors (in GDT or LDT) referenced by those selectors. Instead, the descriptor caches are loaded with fixed values. See the Operation section for details. It is the responsibility of OS software to ensure that the descriptors (in GDT or LDT) referenced by those selector values correspond to the fixed values loaded into the descriptor caches; the SYSCALL instruction does not ensure this correspondence.

除此之外,硬件无关紧要;如果您只使用像 int 0x80.
这样的遗留系统调用机制,那么任何对您有意义的模式都可以 AFAIK,没有跨操作系统的标准约定,但这不是我看过的东西。


条目可能在内核设置它们时通过缓存获取(例如在上下文切换时),因此将一起使用的条目放在同一个 64 字节缓存行中可能会有微小的优势。 (减少高速缓存未命中/占用空间的高速缓存行数。)特别是对于 32 位用户-space 如果您不能只为他们的 SS/DS/ES 使用空选择器 (0)。

但是如果整个 GDT 是 8 个条目或更少,则整个内容适合一个缓存行(如果您将开始对齐 64)。较旧的 CPUs(在 Pentium 4 / Core 2 之前)有 32 字节缓存行,但它们不支持 64 位模式,因此需要较少的 GDT 条目。

请注意,CPU 实际上永远不会访问索引 0,因此您可以将第一个“真实”GDT 条目和 lgdt 与该地址减去 8 对齐。(“null描述符”是一个特例。)