GDT和 LDT 的区别
GDT(Global Descriptor Table)和LDT(Local Descriptor Table)是在x86架构中使用的两种描述符表,用于定义内存段的属性和访问权限。它们之间的主要区别在于作用域和使用方式。
GDT
GDT是全局描述附表,主要存放操作系统和各任务公用的描述符,如公用的数据和代码段描述符、各任务的TSS描述符和LDT描述符。(TSS是任务状态段,存放各个任务私有运行状态信息描述符)
LDT是局部描述符表,主要存放各个任务的私有描述符,如本任务的代码段描述符和数据段描述符等。
GDT是全局性的描述符表,它存储了系统中所有任务共享的段描述符。
GDT可以包含多个段描述符,每个段描述符定义了一个内存段的属性,例如基地址、大小、访问权限等。
GDT在系统启动时被加载到GDTR(GDT寄存器),全局有效,可由所有任务和进程共享。
GDT适用于操作系统内核代码、全局共享的库和驱动程序等。
GDT适用于全局共享的段,如内核代码和数据、全局共享的库和驱动程序等。由于GDT是全局有效的,它可以在整个系统中使用,可以被所有任务和进程访问。
GDTR
GDTR是一个长度为48bit的寄存器,内容为一个32位的基地址和一个16位的段限。其中32位的基址是指GDT在内存中的地址。
LDT
LDT是每个任务(进程)独有的描述符表,它存储了每个任务独有的段描述符。
每个任务都可以有自己的LDT,用于定义任务私有的内存段属性。
LDT在任务切换时切换,每个任务可以根据需要加载不同的LDT。
LDT适用于多任务操作系统中的用户进程,每个进程可以有自己独立的内存段定义。
LDT适用于多任务操作系统中的用户进程,每个进程可以有自己的私有段。每当任务切换时,可以切换LDT以确保每个任务只能访问自己的私有段。
LDTR
LDTR是局部描述符寄存器,由一个可见的16位寄存器(段选择子)和一个不可见的描述符寄存器组成(描述符寄存器实际上是一个不可见的高速缓冲区)。
比较
-
现代操作系统往往不使用LDT,而是使用分页机制来实现虚拟内存管理和内存保护。因此,在现代操作系统中,GDT的使用更为常见,而LDT的使用相对较少。
-
应为GDT中除了有段描述符之外还有LDT描述符,所以微处理器在GDT中寻址LDT时,也需要使用选择子,以保持与段描述符寻址的统一。在这里还要引入一个段选择子的概念。段选择子是一个寄存器,高13位用来指示描述符在描述符表中的索引号,低两位是表示使用描述符的特权级别;另外一位(T1)是GDT和LDT的信号量,如果T1=0,则使用GDTR,如果T1=1,则使用LDTR。选择子将被装入段寄存器中。系统中的段寄存器共有六个:CS、SS、DS、ES、FS和GS。当选择子被装入段寄存器时,微处理器会自动将其对应的描述符装入描述符寄存器。
系统任务切换时,LDT切换,而GDT不切换(因为真个系统只有一个GDT),这时新任务的LDT描述符的选择子就被装入到LDTR中。 -
任务切换过程中,各个相关寄存器的变化?
当 任务切换时,如果使用的是LDT,首先变化的是LDTR。段选择子被装入LDTR,同时LDT描述符自动被装入描述符寄存器。系统利用LDTR中的段选择 子来定位LDT描述符在GDT中的位置。这里我不明白的是LDTR中的LDT描述符和GDT中的描述符是什么关系?为什么要这样做呢?自动装入到LDTR 中的描述符到底是什么?从哪来?请高手指点! -
为什么要有一个GDTR,并且GDTR的结构和LDTR不一样呢?
这主要是因为系统只有一个GDT,而GDT的描述符有不能存放在GDT中(LDT的描述符都存放在GDT中),所以就需要一个GDTR来指示GDT在内存中的位置。因为GDTR是直接指示内存地址,而LDTR主要指示LDT描述符在GDT中的位置和属性,所以GDTR和LDTR的结构也不同。