Intel Memory-Management Registers

前言

本文继续翻译 Intel vol3 chapter 2 :2.4章节,有些英文单词翻译成中文别扭的我会保留英文,不翻译。

一、Memory-Management Registers

处理器提供四个内存管理寄存器(GDTR、LDTR、IDTR 和 TR),它们指定控制分段内存管理的数据结构的位置,如下图所示,并为加载和存储这些寄存器提供了特殊的指令。
在这里插入图片描述

1.1 Global Descriptor Table Register (GDTR)

GDTR 寄存器保存 GDT 的基地址(保护模式下为 32 位;IA-32e 模式下为 64 位)和 16 位表limit。 基地址指定 GDT 字节 0 的线性地址; 表limit指定表中的字节数。

LGDT 和 SGDT 指令分别加载和存储 GDTR 寄存器。 在处理器上电或复位时,基地址设置为默认值 0,limit设置为 0FFFFH(即limit的16位全部设置为1)。 作为保护模式操作的处理器初始化过程的一部分,必须将新的基地址加载到 GDTR 中。

1.2 Local Descriptor Table Register (LDTR)

LDTR 寄存器保存 LDT 的 16 位段选择子、基地址(保护模式下为 32 位;IA-32e 模式下为 64 位)、段limit和描述符属性。 基地址指定LDT段字节0的线性地址; 段limit指定段中的字节数。

LLDT 和 SLDT 指令分别加载和存储 LDTR 寄存器的段选择子部分。 包含 LDT 的段必须在 GDT 中有段描述符。 当 LLDT 指令在 LDTR 中加载段选择子时:LDT 描述符中的基地址、limit和描述符属性会自动加载到 LDTR 中。

当发生任务切换时,LDTR 会自动加载新任务的 LDT 的段选择子和描述符。 在将新的 LDT 信息写入寄存器之前,不会自动保存 LDTR 的内容。

在处理器上电或复位时,段选择子和基地址设置为默认值 0,limit设置为 0FFFFH。

1.3 IDTR Interrupt Descriptor Table Register

IDTR 寄存器保存 IDT 的基地址(保护模式下为 32 位;IA-32e 模式下为 64 位)和 16 位表limit。 基地址指定IDT字节0的线性地址; 表limit指定表中的字节数。

扫描二维码关注公众号,回复: 14367786 查看本文章

LIDT 和 SIDT 指令分别加载和存储 IDTR 寄存器。 在处理器上电或复位时,基地址设置为默认值 0,limit设置为 0FFFFH。 然后可以在处理器初始化过程中更改寄存器中的基地址和 limit。

1.4 Task Register (TR)

任务寄存器保存当前任务的 TSS 的 16 位段选择子、基地址(保护模式下为 32 位;IA-32e 模式下为 64 位)、段limit和描述符属性。 选择子引用 GDT 中的 TSS 描述符。 基地址指定TSS字节0的线性地址; 段limit指定 TSS 中的字节数。

LTR 和 STR 指令分别加载和存储任务寄存器的段选择子部分。 当 LTR 指令在任务寄存器中加载段选择子时,来自 TSS 描述符的基地址、limit和描述符属性会自动加载到任务寄存器中。 在处理器上电或复位时,基地址设置为默认值 0,limit 设置为 0FFFFH。

当发生任务切换时,任务寄存器会自动加载新任务的 TSS 的段选择子和描述符。 在将新的 TSS 信息写入寄存器之前,不会自动保存任务寄存器的内容。

二、Instruction

下文出现的两个术语:
operating-system software (操作系统软件) : 在Linux 中 即 CPL = 0,内核态。
application programs(应用程序) :在Linux 中 即 CPL = 3,用户态。

2.1 LGDT/LIDT Instruction Description

在这里插入图片描述

将源操作数中的值加载到GDTR或IDTR。 源操作数指定一个 6 字节的内存位置,其中包含GDT或IDT的基地址(线性地址)和limit(以字节为单位的表大小)。如果操作数大小属性为 32 位,则将 16 位limit(6 字节数据操作数的低 2 字节)和 32 位基地址(数据操作数的高 4 字节)加载到寄存器中。如果操作数大小属性为 16 位,则加载 16 位limit(低 2 个字节)和 24 位基地址(第三、第四和第五个字节)。这里不使用操作数的高位字节,GDTR或IDTR中基地址的高位字节用零填充。

LGDT 和 LIDT 指令仅用于操作系统软件; 它们不在应用程序中使用。它们是在保护模式下直接加载线性地址(即不是段相对地址)和limit 的惟一指令。它们通常在 real-address mode下执行,以允许处理器在切换到 protected mode 之前进行初始化。

在 64 位模式下,指令的操作数大小固定为 8+2 字节(一个 8 字节的基地址和一个 2 字节的limit)。

2.2 SGDT Instruction Description

在这里插入图片描述
将GDTR 的内容存储在目标操作数中。 目标操作数指定内存位置。

在legacy或兼容模式下,目标操作数是一个 6 字节的内存位置。 如果操作数大小属性为 16 位,则 limit存储在低 2 字节中,24 位基地址存储在字节 3-5 中,字节 6 填充零。 如果操作数大小属性为 32 位,则寄存器的 16 位 limit字段存储在内存位置的低 2 字节中,32 位基地址存储在高 4 字节中。

In IA-32e mode,操作数大小固定为 8+2 字节。 该指令存储一个 8 字节的基地址和一个 2 字节的limit。

SGDT 仅对操作系统软件有用。 但是,如果 CR4.UMIP = 0,它可以在应用程序中使用而不会产生异常。

2.3 SIDT Instruction Description

在这里插入图片描述
将IDTR 的内容存储在目标操作数中。 目标操作数指定一个 6 字节的内存位置。

在非 64 位模式下,如果操作数大小属性为 32 位,则寄存器的 16 位 limit 字段存储在内存位置的低 2 个字节中,32 位基地址存储在高位 4字节。 如果操作数大小属性为 16 位,则 limit 存储在低 2 个字节中,24 位基地址存储在第三、第四和第五个字节中,第六个字节用 0 填充。

在 64 位模式下,操作数大小固定为 8+2 字节。 该指令存储 8 字节基地址和 2 字节limit 值。

2.4 LLDT Instruction Description

在这里插入图片描述

将源操作数加载到LDTR的段选择子字段中。 源操作数(通用寄存器或内存位置)包含指向表LDT 的段选择子。 在 LDTR 中加载段选择子后,处理器使用段选择子在全局描述符表 (GDT) 中定位 LDT 的段描述符。 然后它将 LDT 的段限制和基地址从段描述符加载到 LDTR 中。 段寄存器 DS、ES、SS、FS、GS 和 CS 不受此指令影响,当前任务的TSS中的 LDTR 字段也不受此影响。

如果源操作数的位 2-15 为 0,则 LDTR 被标记为无效,并且 LLDT 指令completes silently。 但是,所有后续对 LDT 中描述符的引用(LAR、VERR、VERW 或 LSL 指令除外)都会导致一般保护异常 (#GP)。

操作数大小属性对此指令没有影响。

LLDT 指令用于操作系统软件; 它不应该在应用程序中使用。 该指令只能在保护模式或 64 位模式下执行。

在 64 位模式下,操作数大小固定为 16 位。

2.5 SLDT Instruction Description

在这里插入图片描述
将来自 LDTR 的段选择子存储在目标操作数中。 目标操作数可以是通用寄存器或内存位置。 与该指令一起存储的段选择子指向当前 LDT 的段描述符(位于 GDT 中)。 该指令只能在保护模式下执行。

在 IA-32e 模式之外,当目标操作数是 32 位寄存器时,16 位段选择器被复制到寄存器的低 16 位中。 对于 Pentium 4、Intel Xeon 和 P6 系列处理器,寄存器的高 16 位被清除。 对于 Pentium、Intel486 和 Intel386 处理器,它们是未定义的。当目标操作数是内存位置时,无论操作数大小如何,段选择子都会作为 16-bit quantity 写入内存。

在兼容模式下,当目标操作数是 32 位寄存器时,16 位段选择符被复制到寄存器的低 16 位中。 寄存器的高 16 位被清除。 当目标操作数是内存位置时,段选择子以 16-bit quantity 写入内存,而不管操作数大小。

在 64 位模式下,使用 REX.R 形式的 REX 前缀允许访问其他寄存器 (R8-R15)。 使用 64 位寄存器的 SLDT 的行为是将 16 位选择子进行零扩展并将其存储在寄存器中。 如果目标是内存且操作数大小为 64,则 SLDT 会将 16 位选择子作为16-bit quantity写入内存,而不管操作数大小。

2.6 LTR Instruction Description

在这里插入图片描述
将源操作数加载到任务寄存器的段选择子字段中。 源操作数(通用寄存器或内存位置)包含指向任务状态段 (TSS) 的段选择子。 在将段选择子加载到任务寄存器中之后,处理器使用段选择子在全局描述符表 (GDT) 中定位 TSS 的段描述符。 然后它将段limit和 TSS 的基地址从段描述符加载到任务寄存器中。任务寄存器指向的任务被标记为busy,但不会发生对任务的切换。

LTR 指令用于操作系统软件; 它不应该在应用程序中使用。 只能在CPL为0时在保护模式下执行。它通常用于初始化代码中,以建立要执行的第一个任务。

操作数大小 属性对此指令没有影响。

在 64 位模式下,操作数大小仍固定为 16 位。 该指令引用一个 16 字节描述符来加载 64 位基地址。

2.7 STR Instruction Description

在这里插入图片描述
将来自 TR 的段选择子存储在目标操作数中。 目标操作数可以是通用寄存器或内存位置。 与该指令一起存储的段选择子指向当前运行任务的 TSS。

当目的操作数是 32 位寄存器时,16 位段选择子被复制到寄存器的低 16 位,寄存器的高 16 位被清零。 当目标操作数是内存位置时,无论操作数大小如何,段选择子都会以 16-bit quantity 写入内存。

在 64 位模式下,操作是相同的。 内存操作数的大小固定为 16 位。 In register stores, the 2-byte TR is zero extended if stored to a 64-bit register.

备注:上面的意思是32位模式和 64 位模式 下该指令执行的操作是一样的。

STR 指令仅在操作系统软件中有用。 它只能在保护模式下执行。

总结

Intel vol3 chapter 2 :2.5 翻译结束,我加入了相应指令( Intel vol2)的翻译。

猜你喜欢

转载自blog.csdn.net/weixin_45030965/article/details/124916874