描述符寄存器是什么?

3
我知道什么是段寄存器。它们保存段选择器(描述符表中的索引+特权级别+本地或全局表),还有一个隐藏的部分,也称为“描述符缓存”。我也了解全局和本地描述符表以及描述符本身。然而,在第95页,卷3A(IA-32e模式下的段加载指令一章)中,Intel 64和IA-32处理器软件开发者手册提到了描述符寄存器,这是我第一次听说。

处理器检查所有线性地址引用是否处于规范形式,而不是执行限制检查。模式切换不会更改段寄存器或相关的描述符寄存器。在64位模式执行期间,除非执行显式的段加载,否则这些寄存器也不会被更改。

你们中有人能解释一下描述符寄存器吗?SS、ES、DS、CS、Es、FS和GS都是段寄存器,全局和本地描述符表中的每个条目都称为描述符。那描述符寄存器是什么呢?

我在谷歌上做了一些调查,但没有找到答案。


@MichaelPetch:“这些是隐藏/私有寄存器…”更具体地说,是“段寄存器”的一个隐藏部分。正如英特尔软件开发手册在前一页(94而不是95)所说:每个段寄存器都有一个“可见”部分和一个“隐藏”部分。(隐藏部分有时被称为“描述符缓存”或“影子寄存器”。) - Adrian
顺便说一下,我喜欢你的回答。你介意把它发布为实际答案而不是评论吗?我会接受并点赞它。 - Adrian
@MichaelPetch 等一下。为什么英特尔手册说每个段寄存器都有一个“可见”部分和一个“隐藏”部分,如果隐藏部分不在段寄存器中而是在描述符缓存寄存器中?难道描述符缓存寄存器不是段寄存器的一部分吗? - Adrian
2个回答

4
描述符寄存器通常被称为描述符缓存。在内存操作数中使用段寄存器时,不是每次从全局或局部描述符表(GDT / LDT)中读取适当的描述符,而是仅在加载段寄存器时才从GDT / LDT中读取描述符。(请注意,所有内存操作数都使用段寄存器,无论是隐式还是显式的,因此如果不按照这种方式工作,CPU将会慢得多。)
这个副作用是,可能会出现描述符缓存与加载在段寄存器中的当前选择器值不同步的情况。例如,如果使用LGDT指令更改GDT的地址,则不会更新描述符缓存,并且仍包含来自旧GDT的描述符值。
同样的事情发生在切换模式时,例如从实模式切换到保护模式,或者从保护模式切换到长模式(Intel称之为IA-32e模式)。从实模式切换到保护模式后,描述符缓存仍具有旧实模式基址、限制和访问权限。这很重要,因为段寄存器也仍然包含它们的实模式值,这些值在保护模式下不太可能有效。特别是,它允许获取CS:EIP处的下一条指令,即使CS包含无效选择器。CS描述符缓存仍然包含有效值,指向模式更改之前的同一位置。
从保护模式切换到长模式的转换类似,但在长模式下忽略了描述符缓存中的大多数值。除了FS和GS以外,所有段都使用固定基址0,并且不执行限制检查。这意味着切换到长模式的代码应该使用一个具有基址0的代码段,以便有效的CS基址不会改变。

2
基址/限制等内容在下一次mov ds,whatever之前是固定的,这允许像虚幻模式https://wiki.osdev.org/Unreal_Mode这样的东西,在这种情况下,您可以切换回限制>64k的实模式,并且通常基址=0。(平面4G)。
英特尔将段描述符高速缓存描述为寄存器。 这只是术语问题。
事实上,“寄存器”是更好的思考方式,因为“缓存”意味着让它与其缓存的东西(GDT或LDT条目)不同步是不好的。
通常的术语是“描述符缓存”,但它不是一个连续的缓存,并且仅旨在在写入段寄存器时更改,而不是在GDT中的内存中。 (并且不更新以反映段寄存器的解释更改,例如实模式与受保护模式之间的区别。)

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接