操作系统是否有一个约定的约定,指定每个表索引应该描述什么?例如,在 Windows 系统上(如此处所述),条目 4 描述了32 位用户模式代码 ( RPL = 3
),条目 6 描述了 64 位用户模式代码。这是一个约定吗?其他条目呢?
1 回答
x86-64 syscall
/sysret
和 32 位sysenter
/sysexit
显然确实关心 GDT 条目的顺序:内核 CS、内核数据、用户 CS、用户数据的顺序。(感谢@Brendan 提供的详细信息。)或者至少,syscall
将固定值加载到 CS 和 SS 内部状态中:
SYSCALL 使用来自 IA32_STAR MSR 的位 47:32 的值加载 CS 和 SS 选择器。但是,CS 和 SS 描述符缓存不是从那些选择器引用的描述符(在 GDT 或 LDT 中)加载的。相反,描述符缓存加载固定值。有关详细信息,请参阅操作部分。操作系统软件有责任确保这些选择器值引用的描述符(在 GDT 或 LDT 中)对应于加载到描述符缓存中的固定值;SYSCALL 指令不能确保这种对应。
除此之外,硬件不在乎。如果您只使用遗留系统调用机制(如int 0x80
.
AFAIK,跨操作系统没有标准约定,但这不是我看过的东西。
当内核设置条目时(例如在上下文切换时),条目可能通过缓存获取,因此将一起使用的条目放在同一个 64 字节缓存行中可能会有一个微小的优势。(减少缓存未命中/占用的缓存行数。)尤其是对于 32 位用户空间,如果您不能仅将空选择器 ( 0
) 用于其 SS/DS/ES。
但是如果整个 GDT 是 8 个或更少的条目,则整个内容都适合一个缓存行(如果您将开头对齐 64)。较旧的 CPU(在 Pentium 4 / Core 2 之前)有 32 字节的缓存线,但不支持 64 位模式,因此需要的 GDT 条目更少。
请注意,CPU 永远不会真正访问索引 0,因此您可以将第一个“真实”GDT 条目lgdt
与该地址减去 8 对齐。(“空描述符”是一种特殊情况。)