操作系统实践之第二章(LDT的使用)
2016-11-15 20:27
99 查看
前面我们已经使用过GDT了,本节主要体验一下LDT的使用。
首先LDT也是描述符表,跟GDT的区别主要在于G(Global)和L(Local)上的不同。那么我们如何在代码中使用LDT呢?下面将给出示例。
使用LDT的主要代码框架如下:
代码的结构很清晰。我们先在GDT中增加了一个描述符来表示对应的LDT,然后定义了LDT选择子,后面又对描述符进行了初始化。另外我们在代码中还增加了两个节,其中一个是新的描述符表,即LDT;另一个是代码段,对应新增的LDT中的一个描述符。
其中有一段用于加载LDT,指令为lldt,对照它的兄弟lgdt我想大家就知道它的用途了。它负责加载ldtr寄存器,它的操作数是一个选择子,这个选择子对应的就是用来描述LDT的那个描述符。
LDT中的描述符和我们先前用的GDT中的描述符的差别在于后面又加了一个SA_TIL属性。该属性在pm.inc中定义如下:
根据选择子的结构我们可以知道,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也是描述符表,跟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选择子指向的描述符就是索引项。
相关文章推荐
- 《一步一步写嵌入式操作系统——ARM编程方法与实践》(第一章、第二章)读书笔记
- <自己动手写操作系统>第三章——pmtest3源码解析:使用LDT
- 一次恢复操作系统的失败之旅:使用主盘对从盘进行独立系统安装过程实践——OneKey7.3.1
- ubuntu中实践操作系统第二章系统调用与课件不同之处
- 操作系统实践之第二章(特权级变换*理论篇)
- 操作系统实践之第二章(保护模式下的分段寻址)
- 操作系统实践之第二章(中断和异常)
- 操作系统实践之使用Makefile
- 操作系统实践之第二章(实验环境升级)
- 操作系统实践之第二章(分页机制)
- 操作系统实践之第二章(实模式和保护模式)
- 操作系统实践之第二章(页目录表切换)
- 操作系统实验工具使用实践(一)
- 操作系统实践(5)——关于LDT
- 操作系统实践之第二章(特权级变换*实战篇)
- Castle实践9-在Castle IOC容器中使用AspectSharp(全面剖析AspectSharp Facility)
- 学习使用groovy (1)(翻译稿之第二章:闭包)
- 使用ADO.NET 的最佳实践(zz)
- 推荐一本关于操作系统实践的好书
- 数据访问:使用 ADO.NET 的最佳实践(ADO.NET 技术文档)