GDTR、LDTR、IDTR 和 TR 寄存器的大小是多少?
What are the sizes of GDTR, LDTR, IDTR and TR registers?
我在网上查了很多,每次都只能找到GDT、LDT和IDT的大小。
这里我问的不是table的大小,而是寄存器
的大小
我知道GDTR是一个64位的寄存器,但对其他的一无所知
IDTR 和 GDTR 似乎各为 10 个字节。
IDTR 也可以指向虚拟地址 space 中的任何地方,所以显然它的基数也必须是 64 位的。 lidt
和 lgdt
采用相同的限制/基本结构格式,the pseudocode 表明在 64 位模式下它们是这样的:
GDTR(Limit) ← SRC[0:15];
GDTR(Base) ← SRC[16:79];
应将限制(最大字节偏移量)视为 GDTR / IDTR 的一部分。 documentation for sidt
也表示“store IDTR”,它存储的是具有 limit + base 的相同 2 + 8 字节结构。 (GDTR 在内部使用限制来检查段选择器,然后再在 GDT 中查找它们,因此如果超过限制,您使用 lgdt
的地址的 64k 以内的内存可用于其他用途。)
似乎 lidt
/ lgdt
没有检查 GDT/IDT 基址是否为规范地址。文档说他们 #GP(0)
如果内存地址是非规范形式。 但我认为这是在谈论达到 10 字节内存操作的寻址模式运行d,不是基址。
(如果无法获得 non-canonical address into the GDTR or IDTR, the CPU could internally store only the significant (or 57 with PML5),将大小降低到 6 + 2 = 8 字节。并将符号扩展回 64 位作为 sidt
/ sgdt
的一部分。但可能 是 可以通过 GDTR 往返任意 64 位值,只需确保 CPU 在你放置之前不需要将 GDT 用于任何事情在一个有效的地址!)
LDTR 包含段选择器和整个描述符
lldt
的文档表明如果没有错误:
LDTR(SegmentSelector) ← SRC;
LDTR(SegmentDescriptor) ← GDTSegmentDescriptor;
表示内部LDTR保持16位段选择符(实际ope运行d到ldtr
,例如ldtr ax
),以及加载选择的GDT进入并保持它。 GDT 条目是 8 个字节,但它可以将该条目解码为某种内部格式。 (可能不包括类型字段,它已经被检查并要求类型为 == LDT)
这意味着像DS或SS这样的段寄存器,如果你在运行lldt
之后改变了GDT的内容,你base/limit当时选择的条目运行 lldt
将继续申请。
TR 看起来与 LDTR 相似
同样,文档显示:
TaskRegister(SegmentSelector) ← SRC;
TaskRegister(SegmentDescriptor) ← TSSSegmentDescriptor;
与 LDTR 一样,您只能检索段选择器,而不能检索它存储的实际描述符。 str r/m16
and sldt r/m16
只写一个 16 位目标 ope运行d.
但是实际的内部寄存器需要保存整个段描述符,而不是用选择器重新索引当前的 GDT。
您可以随时查看 CPU 制造商所说的,英特尔® 64 和 IA-32 架构软件开发人员手册第 3 卷第 2.4 章,排序:
GDT 和 IDT:
- 基地址 32 位或 64 位(分别在保护模式和长模式下)
- 限制:16 位
- 总大小:48 或 80 位(4+2=6 字节或 8+2=10 字节)
LDT 和 TR:16 位,与所有其他段寄存器一样。
你也可以看看wiki.osdev.org,这是一个关于操作系统开发的wiki。其中,它有 GDT, IDT and LDT 个页面。
我在网上查了很多,每次都只能找到GDT、LDT和IDT的大小。
这里我问的不是table的大小,而是寄存器
的大小我知道GDTR是一个64位的寄存器,但对其他的一无所知
IDTR 和 GDTR 似乎各为 10 个字节。
IDTR 也可以指向虚拟地址 space 中的任何地方,所以显然它的基数也必须是 64 位的。 lidt
和 lgdt
采用相同的限制/基本结构格式,the pseudocode 表明在 64 位模式下它们是这样的:
GDTR(Limit) ← SRC[0:15];
GDTR(Base) ← SRC[16:79];
应将限制(最大字节偏移量)视为 GDTR / IDTR 的一部分。 documentation for sidt
也表示“store IDTR”,它存储的是具有 limit + base 的相同 2 + 8 字节结构。 (GDTR 在内部使用限制来检查段选择器,然后再在 GDT 中查找它们,因此如果超过限制,您使用 lgdt
的地址的 64k 以内的内存可用于其他用途。)
似乎 lidt
/ lgdt
没有检查 GDT/IDT 基址是否为规范地址。文档说他们 #GP(0)
如果内存地址是非规范形式。 但我认为这是在谈论达到 10 字节内存操作的寻址模式运行d,不是基址。
(如果无法获得 non-canonical address into the GDTR or IDTR, the CPU could internally store only the significant sidt
/ sgdt
的一部分。但可能 是 可以通过 GDTR 往返任意 64 位值,只需确保 CPU 在你放置之前不需要将 GDT 用于任何事情在一个有效的地址!)
LDTR 包含段选择器和整个描述符
lldt
的文档表明如果没有错误:
LDTR(SegmentSelector) ← SRC;
LDTR(SegmentDescriptor) ← GDTSegmentDescriptor;
表示内部LDTR保持16位段选择符(实际ope运行d到ldtr
,例如ldtr ax
),以及加载选择的GDT进入并保持它。 GDT 条目是 8 个字节,但它可以将该条目解码为某种内部格式。 (可能不包括类型字段,它已经被检查并要求类型为 == LDT)
这意味着像DS或SS这样的段寄存器,如果你在运行lldt
之后改变了GDT的内容,你base/limit当时选择的条目运行 lldt
将继续申请。
TR 看起来与 LDTR 相似
同样,文档显示:
TaskRegister(SegmentSelector) ← SRC;
TaskRegister(SegmentDescriptor) ← TSSSegmentDescriptor;
与 LDTR 一样,您只能检索段选择器,而不能检索它存储的实际描述符。 str r/m16
and sldt r/m16
只写一个 16 位目标 ope运行d.
但是实际的内部寄存器需要保存整个段描述符,而不是用选择器重新索引当前的 GDT。
您可以随时查看 CPU 制造商所说的,英特尔® 64 和 IA-32 架构软件开发人员手册第 3 卷第 2.4 章,排序:
GDT 和 IDT:
- 基地址 32 位或 64 位(分别在保护模式和长模式下)
- 限制:16 位
- 总大小:48 或 80 位(4+2=6 字节或 8+2=10 字节)
你也可以看看wiki.osdev.org,这是一个关于操作系统开发的wiki。其中,它有 GDT, IDT and LDT 个页面。