GDT、LDT、IDTR、TR

1、现在内存管理系统都是基于页式管理的, 段式管理说白了可有可无, 那是Intel老古董阶段留下来的遗毒, 以至于Intel的硬件构架白白地复杂了. Linux kernel直接让段式管理透明.

2.全局描述符表GDT(Global Descriptor Table)在整个系统中,全局描述符表GDT只有一张(一个处理器对应一个GDT),GDT可以被放在内存的任何位置,但CPU必须知道GDT的入口,也就是基地址放在哪里,Intel的设计者门提供了一个寄存器GDTR用来存放GDT的入口地址,程序员将GDT设定在内存中某个位置之后,可以通过LGDT指令将GDT的入口地址装入此寄存器,从此以后,CPU就根据此寄存器中的内容作为GDT的入口来访问GDT了。GDTR中存放的是GDT在内存中的基地址和其表长界限。

基地址指定GDT表中字节0在线性地址空间中的地址,表长度指明GDT表的字节长度值。指令LGDT和SGDT分别用于加载和保存GDTR寄存器的内容。在机器刚加电或处理器复位后,基地址被默认地设置为0,而长度值被设置成0xFFFF。在保护模式初始化过程中必须给GDTR加载一个新值。

3、局部描述符表LDT(Local Descriptor Table)局部描述符表可以有若干张,每个任务可以有一张。我们可以这样理解GDT和LDT:GDT为一级描述符表,LDT为二级描述符表。LDT和GDT从本质上说是相同的,只是LDT嵌套在GDT之中。LDTR记录局部描述符表的起始位置,与GDTR不同,LDTR的内容是一个段选择子。由于LDT本身同样是一段内存,也是一个段,所以它也有个描述符描述它,这个描述符就存储在GDT中,对应这个表述符也会有一个选择子,LDTR装载的就是这样一个选择子。LDTR可以在程序中随时改变,通过使用lldt指令

由于每个进程都有自己的一套程序段、数据段、堆栈段,有了局部描述符表则可以将每个进程的程序段、数据段、堆栈段封装在一起,只要改变LDTR就可以实现对不同进程的段进行访问。

当进行任务切换时,处理器会把新任务LDT的段选择符和段描述符自动地加载进LDTR中。在机器加电或处理器复位后,段选择符和基地址被默认地设置为0,而段长度被设置成0xFFFF。

除了GDTR、LDTR外还有IDTR和TR

(1)中断描述符表寄存器IDTR

与GDTR的作用类似,IDTR寄存器用于存放中断描述符表IDT的32位线性基地址和16位表长度值。指令LIDT和SIDT分别用于加载和保存IDTR寄存器的内容。在机器刚加电或处理器复位后,基地址被默认地设置为0,而长度值被设置成0xFFFF。

(2)任务寄存器TR

TR用于寻址一个特殊的任务状态段(Task State Segment,TSS)。TSS中包含着当前执行任务的重要信息。

TR寄存器用于存放当前任务TSS段的16位段选择符、32位基地址、16位段长度和描述符属性值。它引用GDT表中的一个TSS类型的描述符。指令LTR和STR分别用于加载和保存TR寄存器的段选择符部分。当使用LTR指令把选择符加载进任务寄存器时,TSS描述符中的段基地址、段限长度以及描述符属性会被自动加载到任务寄存器中。当执行任务切换时,处理器会把新任务的TSS的段选择符和段描述符自动加载进任务寄存器TR中。

### 定义 - **GDT(全局描述符表)**:在整个系统中,全局描述符表GDT只有一张(一个处理器对应一个GDT),它是存放段描述符的数组,这些描述符用于定义内存段,多个程序都可以在GDT中定义自己的段描述符,是公用的、全局可见的。GDT可以被放在内存的任何位置,需要用专门的寄存器GDTR(Global Descriptor Table Register)指引CPU找到GDT [^2][^3]。 - **LDT(局部描述符表)**:LDT中的描述符和GDT中的描述符除了选择子的bit3一个为0一个为1用于区分该描述符是在GDT中还是在LDT中外,描述符本身的结构完全一样。LDT用于描述每个任务自己的局部地址空间,不同的任务可以有不同的LDT [^1]。 ### 作用 - **GDT**:提供了一种机制来管理系统中所有任务都可能使用的段,比如操作系统的代码段、数据段等。通过GDT,CPU可以准确地定位和访问这些段,实现对内存的分段管理,保证系统的安全性和稳定性 [^2][^3]。 - **LDT**:每个任务可以有自己独立的LDT,用于描述该任务私有的内存段,这样可以实现任务之间的隔离,不同任务的局部地址空间相互独立,避免任务之间的相互干扰 [^1]。 ### 原理 - **GDT**:CPU需要知道GDT的入口,也就是基地址放在哪里,Intel提供了一个寄存器GDTR用来存放GDT的入口地址。GDTR是48位的寄存器,低16位存放GDT界限,剩余32位存放GDT起始地址。程序员将GDT设定在内存中某个位置之后,可以通过LGDT指令将GDT的入口地址装入此寄存器,从此以后,CPU就根据此寄存器中的内容作为GDT的入口来访问GDT。段选择子作为索引在GDT中查找对应的段描述符,从而确定段的基地址、界限和访问权限等信息 [^2][^3]。 - **LDT**:LDT的使用依赖于GDT,在GDT中有一个专门的描述符指向LDT。当任务需要访问其局部地址空间时,CPU通过GDT中的这个描述符找到对应的LDT,然后再从LDT中获取所需的段描述符 [^1]。 以下是一个简单的GDT定义示例: ```asm GDT: ; Descriptor 0 is not used dw 0 dw 0 dw 0 dw 0 ; Descriptor 1: kernel code segment dw 0xFFFF ; bytes 0 and 1 of segment size dw 0x0000 ; bytes 0 and 1 of segment base address db 0x00 ; byte 2 of segment base address db 0x9A ; present, DPL=0, non-system, code, non-conforming, ; readable, not accessed db 0xCF ; granularity=page, 32 bit code, upper nibble of size db 0x00 ; byte 3 of segment base address ; Descriptor 2: kernel data and stack segment ; NOTE: what Intel calls an "expand-up" segment ; actually means that the stack will grow DOWN, ; towards lower memory. So, we can use this descriptor ; for both data and stack references. dw 0xFFFF ; bytes 0 and 1 of segment size dw 0x0000 ; bytes 0 and 1 of segment base address db 0x00 ; byte 2 of segment base address db 0x92 ; present, DPL=0, non-system, data, expand-up, ; writable, not accessed db 0xCF ; granularity=page, big, upper nibble of size db 0x00 ; byte 3 of segment base address ```
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值