操作系统实践(5)——关于LDT

LDT与GDT类似,为局部描述符表。使用LDT有几个步骤:
1.在GDT中加一个表项,并增加一个描述符,假设为SelectorLDT;
2.像配置GDT表那样,配置好LDT表自己的描述符,并设置好相应的ldt的选择子,选择子有一位标识是ldt还是gdt;
3.加载LDT,使用lldt指令;
4.直接jmp ldt里面的选择子。

跳转到LDT里的代码段,跟用GDT跳转代码段一样,都是通过
jmp Selector 的方式,关键之处在于Selector里面有一标志位,标志这个选择子是从LDT表中查找,还是从GDT表中查找。

关键代码:

[SECTION .gdt]
; GDT
;                            段基址,        段界限 , 属性
LABEL_GDT: Descriptor 0, 0, 0 ; 空描述符
LABEL_DESC_NORMAL: Descriptor 0, 0ffffh, DA_DRW ; Normal 描述符
......
LABEL_DESC_LDT: Descriptor 0, LDTLen - 1, DA_LDT ; LDT

; GDT 结束
; GDT 选择子
SelectorNormal          equ     LABEL_DESC_NORMAL       - LABEL_GDT
......
SelectorLDT             equ     LABEL_DESC_LDT          - LABEL_GDT

; END of [SECTION .gdt]

下面是LDT自己的描述符表

; 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]

上面的SA_TIL就是标识这个选择子是属于LDT的关键所在。

上面的SelectorLDTCodeA 对应的代码:

; 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

        jmp     $
CodeALen        equ     $ - LABEL_CODE_A
; END of [SECTION .la]

使用LDT:

        ; 初始化 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

        ; Load LDT
        mov     ax, SelectorLDT
        lldt    ax
        jmp     SelectorLDTCodeA:0      ; 跳入局部任务

你可能感兴趣的:(ASM,操作系统,ldt)