第5天 结构体、文字显示与GDT/IDT初始化

来源:互联网 发布:试述关系数据库的特点 编辑:程序博客网 时间:2024/05/19 17:06

1、分段

GDT,IDT都是与CPU有关的设定。为了让操作系统能够使用32位模式,需要对CPU做各种设定。

在汇编语言中,有一个指令叫做org。它指定了程序要装载的地址,而当CPU读到这段地址时,程序便会运行。现在的操作系统能同时运行多个程序,但如果出现内存的使用范围重叠了怎么办?必须让某个程序放弃执行,同时报出一个“内存冲突”的错误。但实际上是有某种方法能解决这个问题的。这个方法就是分段。

所谓分段,打个比方说,就是按照自己喜欢的方式,将合计4GB的内存分成很多块,每一块的起始地址都看作0来处理。有了这个功能,任何程序都可以先写上org 0。这样的块就称为段。当然,还有一种分页的方法。

分段的时候,使用的还是16位中的段寄存器ds。在16位模式时,地址是通过ds * 16 + offset来计算的。那么在32位模式下,已经不是这样来计算了,而是offset加上ds所表示的段地的起始地址来表示。按这种分段方法,为了表示一个段,我们需要有以下信息:

(1)段的大小

(2)段的起始地址

(3)段的管理属性(禁止写入,禁止执行,系统专用等)

CPU用8个字节的数据来表示这些信息。但是,我们知道,ds只是16位的,根本放不入这些信息。怎么办呢?我们可以先有一个段号,存放在段寄存器里,然后预告设定好段号与段的对应关系。段号我们就用0 ~ 8191这些数,ds是16位,能够处理的数范围是0 ~ 65535,但由于CPU设计上的原因,段寄存器的低3位不能使用,因此,能够使用的只有13位,所以,刚好能处理0 ~ 8191这些数。

因为能处理8192个段,设定这多么段就需要8192 * 8 = 64kb的空间。CPU无法存储这么大的数据,那么就需要将它们放入内存。这64KB的数据就称为GDT。

2、GDT

GDT,即global segment descriptor table,翻译成全局段号记录表。将这些数据整齐地排列在内存的某个地方,然后将内存的起始地址和有效设定个数放在CPU内被称作GDTR的特殊寄存器中,设定就完成了。在GDTR寄存器中,低16位是段上限,即GDT的有效字节数 - 1,高32位代表GDT的开始地址。

说到底,分段与CPU的内部机制有关。