(LDT的使用)
Posted 尚书左仆射
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了(LDT的使用)相关的知识,希望对你有一定的参考价值。
前面我们已经使用过GDT了,本节主要体验一下LDT的使用。
首先LDT也是描述符表,跟GDT的区别主要在于G(Global)和L(Local)上的不同。那么我们如何在代码中使用LDT呢?下面将给出示例。
使用LDT的主要代码框架如下:
[SECTION .gdt]
…
LABEL_DESC_LDT: Descriptor 0, LDTLen - 1, DA_LDT ; LDT
…
SelectorLDT equ LABEL_DESC_LDT - LABEL_GDT
…
[SECTION .s16]
…
; 初始化 LDT 在 GDT 中的描述符
xor eax, eax
mov ax, ds
shl eax, 4
add eax, LABEL_LDT
mov word [LABEL_DESC_LDT + 2], ax
shr eax, 16
mov byte [LABEL_DESC_LDT + 4], al
mov byte [LABEL_DESC_LDT + 7], ah
; 初始化 LDT 中的描述符
xor eax, eax
mov ax, ds
shl eax, 4
add eax, LABEL_CODE_A
mov word [LABEL_LDT_DESC_CODEA + 2], ax
shr eax, 16
mov byte [LABEL_LDT_DESC_CODEA + 4], al
mov byte [LABEL_LDT_DESC_CODEA + 7], ah
…
[SECTION .s32]; 32 位代码段. 由实模式跳入.
…
; Load LDT
mov ax, SelectorLDT
lldt ax
jmp SelectorLDTCodeA:0 ; 跳入局部任务
…
; LDT
[SECTION .ldt]
ALIGN 32
LABEL_LDT:
; 段基址 段界限 属性
LABEL_LDT_DESC_CODEA: Descriptor 0, CodeALen - 1, DA_C + DA_32 ; Code, 32 位
LDTLen equ $ - LABEL_LDT
; LDT 选择子
SelectorLDTCodeA equ LABEL_LDT_DESC_CODEA - LABEL_LDT + SA_TIL
; END of [SECTION .ldt]
; CodeA (LDT, 32 位代码段)
[SECTION .la]
ALIGN 32
[BITS 32]
LABEL_CODE_A:
mov ax, SelectorVideo
mov gs, ax ; 视频段选择子(目的)
mov edi, (80 * 12 + 0) * 2 ; 屏幕第 10 行, 第 0 列。
mov ah, 0Ch ; 0000: 黑底 1100: 红字
mov al, 'L'
mov [gs:edi], ax
; 准备经由16位代码段跳回实模式
jmp SelectorCode16:0
CodeALen equ $ - LABEL_CODE_A
; END of [SECTION .la]
代码的结构很清晰。我们先在GDT中增加了一个描述符来表示对应的LDT,然后定义了LDT选择子,后面又对描述符进行了初始化。另外我们在代码中还增加了两个节,其中一个是新的描述符表,即LDT;另一个是代码段,对应新增的LDT中的一个描述符。
其中有一段用于加载LDT,指令为lldt,对照它的兄弟lgdt我想大家就知道它的用途了。它负责加载ldtr寄存器,它的操作数是一个选择子,这个选择子对应的就是用来描述LDT的那个描述符。
LDT中的描述符和我们先前用的GDT中的描述符的差别在于后面又加了一个SA_TIL属性。该属性在pm.inc中定义如下:
SA_TIL EQU 4
根据选择子的结构我们可以知道,SA_TIL属性的作用就是将选择子中的TI位置为1。TI位为1时,操作系统会从当前LDT中去寻找相应的描述符。
LDT的使用总体来说并不复杂,我们可以总结一下使用LDT的流程。
1. 定义我们所需的LDT,指定相应的描述符。
2. 定义LDT中描述符对应的选择子。
3. 在GDT中添加LDT对应的描述符。
4. 为GDT中的LDT定义选择子。
5. 初始化LDT在GDT中的描述符。
6. 初始化LDT中定义的描述符。
7. 使用lldt加载LDT选择子指定的内容。
8. 用jmp等指令来运行相关的局部操作。
程序运行的流程像这样:首先根据GDT中LDT描述符对应的选择子将其载入到ldtr寄存器中;当我们在使用LDT中选择子的时候,由于其TI位为1,系统知道应该从ldtr所指的内存中(即指定的LDT中)查找相应的描述符;也可以将GDT和LDT之间的关系看成一个二级索引,GDT就是第一级索引,而LDT就是第二级索引,最后LDT选择子指向的描述符就是索引项。
以上是关于(LDT的使用)的主要内容,如果未能解决你的问题,请参考以下文章