0

我在网上查了很多,每次都只能找到GDT、LDT和IDT的尺寸。

这里我不是在问表的大小,而是在问寄存器的大小

我知道 GDTR 是一个 64 位寄存器,但对其他寄存器一无所知。

4

2 回答 2

1

您可以随时查看 CPU 制造商所说的内容:Intel® 64 and IA-32 Architectures Software Developer's Manual Volume 3 Chapter 2.4

排序:GDT 和 IDT:32 位或 64 位(分别在保护模式和长模式下)基地址 + 16 位限制 = 48 位 LDT 和 TR:16 位,与其他所有段寄存器一样。

你也可以看看 wiki.osdev.org,它是一个关于操作系统开发的 wiki。除其他外,它还有GDTIDTLDT页面。

于 2021-06-10T11:41:57.427 回答
0

IDTR 和 GDTR 似乎各有 10 个字节。

IDTR 还可以指向虚拟地址空间中的任何位置,因此显然它的基址也必须是 64 位的。 lidtlgdt采用相同的限制/基本结构格式,伪代码显示在 64 位模式下它们会:

                    GDTR(Limit) ← SRC[0:15];
                    GDTR(Base) ← SRC[16:79];

限制(最大字节偏移)应被视为 GDTR / IDTR 的一部分。的文档sidt还说“存储 IDTR”,它存储的是相同的 2 + 8 字节结构,具有限制 + 基数。(GDTR 在内部使用限制来检查段选择器,然后在 GDT 中查找它们,因此lgdt如果超过限制,您使用的地址的 64k 内的内存可以用于其他用途。)

似乎lidt/lgdt不检查 GDT/IDT 基址是否为规范地址。文档说他们#GP(0) 如果内存地址是非规范形式。但我认为这是关于达到 10 字节内存操作数的寻址模式,而不是基地址。

(如果无法在 GDTR 或 IDTR中获取非规范地址,CPU 可以在内部仅存储有效的48 位(或PML5的 57 位),从而将大小降低到 6 + 2 = 8 字节。并且将符号扩展回 64 位作为sidt/的一部分sgdt。但可能可以通过 GDTR 往返任意 64 位值,只需确保 CPU 在放置之前不需要使用 GDT在一个有效的地址!)


LDTR 包含一个段选择器和一个完整的描述符

的文档lldt表明如果没有错误:

    LDTR(SegmentSelector) ← SRC;
    LDTR(SegmentDescriptor) ← GDTSegmentDescriptor;

这表明内部 LDTR 保留 16 位段选择器(实际操作数ldtr,例如ldtr ax),以及加载选定的 GDT 条目并保留它。GDT 条目是 8 个字节,但它可以将该条目解码为某种内部格式。(可能不包括 type 字段,该字段已被检查并要求为 type == LDT)

这意味着与 DS 或 SS 等段寄存器一样,如果您在运行后更改 GDT 内容,则lldt在您运行时所选条目的基数/限制lldt将继续适用。

TR 看起来类似于 LDTR

同样,文档显示:

TaskRegister(SegmentSelector) ← SRC;
TaskRegister(SegmentDescriptor) ← TSSSegmentDescriptor;

与 LDTR 一样,您只能检索段选择器,而不是它存储的实际描述符。str r/m16并且sldt r/m16只写一个 16 位的目标操作数。

但是实际的内部寄存器需要保存整个段描述符,而不是使用选择器重新索引当前 GDT。

于 2021-06-10T09:16:12.507 回答