学习笔记:一个操作系统的实现--保护模式之基础知识

       在IA32下,CPU有两种工作模式:实模式和保护模式。和很多人一样,我开始学习汇编语言的时候所运行的模式是实模式。在此之前,我对保护模式有所了解,知道了保护模式的寻址方式等等,但是从未深入的了解过保护模式,根本不知道在汇编中怎么进入保护模式。如果你也和我一样,那么请随我来。

实模式与保护模式

        在实模式下,CPU只使用16位的寄存器、16位的数据总线以及20位的地址总线和1MB的寻址能力,其地址由段值和偏移组成。物理地址的计算公式为:

              物理地址 = 段值  *  16 + 偏移     其中 段值和偏移都是16位,一般表示为“段值:偏移”

    相信大家对实模式不再陌生,这里就用更多的篇幅说保护模式。

     在保护模式下,仍然用“段值:偏移”的形式表示,但是段值的意义发生了根本性的变化,虽然段值仍然由原来的16位CS、DS等段寄存器表示,但是它仅仅是一个索引,这个索引指向一个数据结构的表项,表项中详细定义了段的基地址、界限和属性。这个数据数据结构就是全局描述符表GDT(或者局部描述符表LDT),数据结构中的表项叫描述符。

描述符表--GDT、LDT和IDT

    描述符表,顾名思义就是由若干个描述符组成的表(之后将介绍描述符)。系统中有三种描述符表--GDT、LDT和IDT,下面一一介绍。

    1 全局描述符表GDT

    GDT在系统只有一个,保存所有任务共享的描述符,而且任何描述符都可以保存在GDT中,但是中断门和陷入门放在GDT中不起作用(因为这两种描述符由IDT保存)。因此,通过GDT可以实现多个任务的共享。

   与之对应,系统有全局描述符表寄存器GDTR。当执行lgdt [addr of gdt]时,将GDT的起始地址载入GDTR中。

   GDTR示意图如下:

GDTR示意图

GDTR示意图

    2 局部描述符表LDT

    每个任务都有可能有自己的LDT,因此系统中可能保存着多个LDT。LDT中保存各个任务私有的描述符,同理,中断门和陷入门放在LDT中不会起作用。通过LDT,实现了各任务间的隔离。

    同样的,系统中有局部描述符表寄存器LDTR,当执行lldt [selector of LDT]时,将根据selector的值在GDT中查找有关该LDT的信息,载入LDTR中。

    3 中断描述符表IDT

    与GDT一样,系统中只有一个IDT,IDT中可以存放256个描述符,分别对应256个中断。IDT中可以有任务门、中断门和陷入门,其他描述符放在IDT中没有意义。

    仍然和GDT类似,系统中有中断描述表寄存器IDTR,存放IDT的起始地址。所用的命令为lidt。

描述符

    前面提到了描述符表中存放在描述符,那描述符是什么东西呢?

    描述符就是具有描述作用的东西,其中保存了段的相关信息,分为代码段描述符和数据段描述符、系统段描述符以及门描述符,各种描述符的作用可以顾名思义,这里不再详述。

代码段和数据段描述符

代码段和数据段描述符

门描述符

门描述符

中断门和陷入门

中断门和陷入门

选择子

       说完了描述符,也说了保存描述符的描述符表。那程序是怎么从描述符表中找到描述符的呢?这就和选择子有关了(中断和陷入通过int的参数找到)。

       选择子的结构如下:

选择子结构

选择子结构

      选择子就是描述符在描述符表中的索引,前面说过每个描述符占用8个字节,因此低三位可以另用。

      下面举一个例子说明其中的原理。在保护模式下,执行jmp  seg:offset。那么,系统将seg值装入cs中,offset装入EIP中,同时根据S位决定在GDT还是在LDT中查找索引值为描述符索引的描述符,载入隐藏在CS之后的寄存器中。

       同理,调用中断时,通过int的参数在中断描述符表中查找中断门或者陷入门。

      好了,今天就到此为止吧,说的有点乱,将就着看吧。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值