一个操作系统的实现(4)-认识LDT
2016-05-23 18:44
295 查看
看到这里,你应该已经很了解GDT了,如果还不了解GDT。请看这篇文章:
LDT(Local Descriptor Table):从名字上面就可以看出来它与GDT(Gobal Descriptor Table)的区别。GDT是全局描述符表,LDT是局部描述符表(相对于GDT)。
下面仍然是从代码的角度讲解什么是LDT。主要讲解在上一节的基础上增加的代码。在文章的最后会附上所有代码。为了描述LDT,在上一节的基础上添加了如下代码:
现在来看上面的代码。
首先,
在GDT中增加了一个
然后,
增加了两个节,在上述代码的最后两段。分别是
接下来看16位代码段中的初始化代码,
这里的初始化代码对描述符进行初始化。包括两个部分,一个是
最后,在32位代码段中增加如下内容:
这里面有个
你看看上面的LDT的结构,与GDT结构是不是非常像。是的,LDT与GDT有两个最主要的差别,一个是上面所说LDT使用lldt加载的对象是选择子而GDT使用lgdt加载的对象是gdt的基地址和界限(通常用一个在内存中的结构体表示)。另外一个差别就是LDT的选择子
第2位是TI位,上一节课我也不清楚它用来干什么的。到这里再来解释它就很清晰了。
仔细观察上面LDT选择子与GDT选择子,你会发现:LDT的选择子比GDT的选择子多了一个
结合上图可知,SA_TIL将选择子
因此,当上面的代码运行到
本例中LDT中的代码比较简单,只是在屏幕上输入一个字符L。
不难想象,在[SECTION .s32]中打印完“In Protect Mode now.”这个字符串后,一个红色的字符L将会出现。程序运行结果如下:
现在,你对LDT应该有了大致的了解了吧。简单来说,他是一种描述符表,与GDT差不多,只不过它的选择子的TI位必须置1.在运用它时,需要先用lldt指令加载ldtr,lldt的操作数是GDT中用来描述LDT的描述符。
上面的例子中的LDT只有一个代码段。随着以后的逐渐深入,我们还可以在其中增加更多的段,比如数据段、堆栈段等。通过,我们可以把一个单独的任务所用到的所有东西封装在LDT中,这种思想是多任务处理的一个雏形。
下面是完整代码:
一个操作系统的实现(2)-认识保护模式,认识保护模式那篇文章的最后详细介绍了由16位寻址升级到32位寻址而引入的
GDT。
LDT(Local Descriptor Table):从名字上面就可以看出来它与GDT(Gobal Descriptor Table)的区别。GDT是全局描述符表,LDT是局部描述符表(相对于GDT)。
下面仍然是从代码的角度讲解什么是LDT。主要讲解在上一节的基础上增加的代码。在文章的最后会附上所有代码。为了描述LDT,在上一节的基础上添加了如下代码:
现在来看上面的代码。
首先,
在GDT中增加了一个
描述符和描述符对应的
选择子。
然后,
增加了两个节,在上述代码的最后两段。分别是
新的描述符表LDT和
代码段,这个代码段的描述符在LDT中。用来演示LDT的如何使用。
接下来看16位代码段中的初始化代码,
这里的初始化代码对描述符进行初始化。包括两个部分,一个是
初始化LDT在GDT中的描述符,另一个是
初始化LDT中的描述符。
最后,在32位代码段中增加如下内容:
这里面有个
lldt ax。它与lgdt类似,lgdt用来将gdt的基址(32位)与界限(16位)加载到gdtr中。类似地,lldt是将
ldt描述符的选择子加载到ldtr中。
你看看上面的LDT的结构,与GDT结构是不是非常像。是的,LDT与GDT有两个最主要的差别,一个是上面所说LDT使用lldt加载的对象是选择子而GDT使用lgdt加载的对象是gdt的基地址和界限(通常用一个在内存中的结构体表示)。另外一个差别就是LDT的选择子
TI位与GDT的选择子的TI位不同。还记的TI吗?它是选择子结构中的一位。不记得的话看下面的选择子结构:
15 | 14 | 13 | 12 | 11 | 10 | 9 | 8 | 7 | 6 | 5 | 4 | 3 | 2 | 1 | 0 |
描述符索引 | TI | RPL |
仔细观察上面LDT选择子与GDT选择子,你会发现:LDT的选择子比GDT的选择子多了一个
SA_TIL属性。在
pm.inc中找到它的定义如下:
结合上图可知,SA_TIL将选择子
SelectorLDTCodeA的TI位置为1。实际上,TI位便是用来区别GDT的选择子和LDT的选择子的关键所在。如果TI被置为1,系统将从局部描述符表LDT中读取描述符;如果TI位为0,系统将从全局描述符表GDT中读取描述符。
因此,当上面的代码运行到
jmp SelectorLDTCodeA:0处时,系统会从LDT中找到
LABEL_LDT_DESC_CODEA描述符,并跳转到相应的段中。
本例中LDT中的代码比较简单,只是在屏幕上输入一个字符L。
不难想象,在[SECTION .s32]中打印完“In Protect Mode now.”这个字符串后,一个红色的字符L将会出现。程序运行结果如下:
现在,你对LDT应该有了大致的了解了吧。简单来说,他是一种描述符表,与GDT差不多,只不过它的选择子的TI位必须置1.在运用它时,需要先用lldt指令加载ldtr,lldt的操作数是GDT中用来描述LDT的描述符。
上面的例子中的LDT只有一个代码段。随着以后的逐渐深入,我们还可以在其中增加更多的段,比如数据段、堆栈段等。通过,我们可以把一个单独的任务所用到的所有东西封装在LDT中,这种思想是多任务处理的一个雏形。
下面是完整代码:
相关文章推荐
- Ubuntu 默认壁纸历代记
- Ubuntu Remix Cinnamon 20.04 评测:Ubuntu 与 Cinnamon 的完美融合
- 关于Ubuntu 11.10启动提示waiting for the network configuration的问题
- 在 Ubuntu 桌面中使用文件和文件夹
- ubuntu下chrome无法同步问题解决
- Ubuntu Linux使用体验
- 使用 GNOME 优化工具自定义 Linux 桌面的 10 种方法
- 以Ubuntu 9.04为例 将工作环境迁移到 Linux
- VirtualBox虚拟机XP与宿主机Ubuntu互访共享文件夹
- 从USB安装Ubuntu Server 10.04.3 图文详解
- Ubuntu 15.04 正式版发布下载
- Linux-Ubuntu 10.04安装Cadence-ic610 方法总结图解
- 应用领航:盘点那些年我们一起追过的OS
- Ubuntu 12.04和Windows 7双系统安装图解
- Ubuntu /home下中文目录如何修改成英文?
- 开机出现:grub rescue的修复方法
- Ubuntu连接Android真机调试
- 你应该选择 Ubuntu 还是 Fedora?
- 100 个最佳 Ubuntu 应用(中)
- 看看我的Ubuntu Linux截图