Chinaunix首页 | 论坛 | 博客
  • 博客访问: 1034260
  • 博文数量: 243
  • 博客积分: 3053
  • 博客等级: 中校
  • 技术积分: 2975
  • 用 户 组: 普通用户
  • 注册时间: 2009-05-02 21:11
文章分类

全部博文(243)

文章存档

2013年(2)

2012年(20)

2011年(5)

2010年(114)

2009年(102)

我的朋友

分类:

2010-11-29 17:40:01

这三个表是在内存中由操作系统或系统程序员所建,并不是固化在哪里,所以从理论上是可以被读写的。这三个表都是描述符表。描述符表是由若干个描述符组成,每个描述符占用8个字节的内存空间,每个描述符表内最多可以有8129个描述符。描述符是描述一个段的大小,地址及各种状态的。
一,保护模式存储器管理功能
386 CPU共有32位地址线,其物理存储器最大可达232字节,实模式下,远指针由segment
:offset组成,对应的物理存储器地址为segment*16+offset,即segment左移四位再加上off
set,因segment和offset限制在16位之内,实际的寻址范围最大可达220(即1M字节)。所以要
对VGA图形模式下的显示缓冲区进行读写只需用a000:offset这样的远指针即可。
保护模式下,远指针由selector:offset组成,selector称作选择器,不同的选择器指示
了不同的内存段,该内存段的实际物理地址,长度和权限,还需从一个特定的内存区域即描述
符表中查到。386 CPU能够设置一个全局描述符表和若干个局部描述符表,每个任务能够拥
有一个局部描述符表,但同一时刻只有活动任务的局部描述符表有效。386的段址寄存器已
经过扩展,由一个16位的寄存器和一个附加的64位寄存器组成,附加的64位寄存器称为描述
符寄存器,程序员无法直接访问。当执行MOV AX,selector/MOV DS,AX这样的指令时,CPU将
16位的selector的值存入DS寄存器的前一部分,然后依据selector的值在全局描述符表或局
部描述符表中找到对应描述符,装入DS附加的描述符寄存器。描述符表中包含若干个描述符
,每个描述符由8个字节组成,其中包含该内存段的物理起始地址、长度、访问权限等内容。
selector的位0~1为申请访问权限,位2为GDT(全局描述符表)和LDT(局部描述符表)的区分
位,位2为0时,描述符位于GDT中。位2为1时,描述符位于LDT中,位3~15共13位为描述符的索
引,将该13位乘以8,即为描述符离描述符表起始位置的偏移,所以描述符表中描述符的个数
最多为8129个。以后执行MOV DS:[offset],AX等访问内存的指令时,根据DS的描述符寄存器
中的长度部分即可判断所访问的内存是否超出该段长度,申请权限是否符合条件等等,如果
超出长度或权限级别不够则会产生保护错误(UAE),实际的物理存储器地址为DS描述寄存器
中的物理起始地址加上偏移offset,可见增加描述符寄存器是为了减少访问描述符表的次数
,以提高CPU的速度。系统初始化时会设置全局描述符表(GDT)和局部描述符表(LDT),全局描
述符表的位置存在全局描述符表寄存器(GDTR)中,该寄存器长度为48位,高32位是描述符表
的起始物理地址,低16位是描述符表长度。局部描述符表的位置存在局部描述符表寄存器(
LDTR)中,该寄存器和段址寄存器类似,也包括一个16位寄存器和一个64位的描述符寄存器,
各个任务的LDT也以描述符的形式登记在GDT中,任务切换时,将该描述符调入LDTR中,同样的
是选择器装入16位寄存器,选择器所指描述符装入LDTR的描述符寄存器中,以后可在LDT中登
记该任务的局部内存段。
可见,保护模式下,访问内存需要将该内存段登记在GDT或LDT中,然后使用selector:of
fset这样的指针就可以访问了。
描述符表有三种,分别为全局描述符表GDT、局部描述符表LDT和中断描述符表IDT。
 
1. 全局描述符表GDT:
全局描述符表在系统中只能有一个,且可以被每一个任务所共享.任何描述符都可以放在GDT中,但中断门和陷阱门放在GDT中是不会起作用的.能被多个任务共享的内存区就是通过GDT完成的,
2. 局部描述符表LDT:
局部描述符表在系统中可以有多个,通常情况下是与任务的数量保持对等,但任务可以没有局部描述符表.任务间不相干的部分也是通过LDT实现的.这里涉及到地址映射的问题.和GDT一样,中断门和陷阱门放在LDT中是不会起作用的.
3. 中断描述符表IDT:
和GDT一样,中断描述符表在系统最多只能有一个,中断描述符表内可以存放256个描述符,分别对应256个中断.因为每个描述符占用8个字节,所以IDT的长度可达2K.中断描述符表中可以有任务门、中断门、陷阱门三个门描述符,其它的描述符在中断描述符表中无意义。
4. 段选择子
在保护模式下,段寄存器的内容已不是段值,而称其为选择子.该选择子指示描述符在上面这三个表中的位置,所以说选择子即是索引值。
当我们把段选择子装入寄存器时不仅使该寄存器值,同时CPU将该选择子所对应的GDT或LDT中的描述符装入了不可见部分。这样只要我们不进行代码切换(不重新装入新的选择子)CPU就会不会对不可见部分存储的描述符进行更新,可以直接进行访问,加快了访问速度。一旦寄存器被重新赋值,不可见部分也将被重新赋值。
关于选择子的值是否连续
关于选择子的值,我认为不一定要连续。但是每个描述符的起始地址相对于第一个描述符(即空描述符)的首地址的偏移必须是8的倍数,即二进制最后三位为0。这样通过全局描述符表寄存器GDTR找到全局描述符表的首地址后,使用段选择子的高13位索引到正确的描述符表项(段选择子的高13位左移3位加上GDTR的值即为段选择子指定的段描述符的逻辑首地址)
也就是说在两个段选择符之间可以填充能被8整除个字节值。当然,如果有选择子指向了这些填充的字节,一般会出错,除非你有意填充一些恰当的数值,呵呵。
关于为什么LDT要放在GDT中
LDT中的描述符和GDT中的描述符除了选择子的bit3一个为0一个为1用于区分该描述符是在GDT中还是在LDT中外,描述符本身的结构完全一样。开始我考虑既然是这样,为什么要将LDT放在GDT中而不是像GDT那样找一个GDTR寄存器呢?
后来终于明白了原因--很简单,GDT表只有一个,是固定的;而LDT表每个任务就可以有一个,因此有多个,并且由于任务的个数在不断变化其数量也在不断变化。如果只有一个LDTR寄存器显然不能满足多个LDT的要求。因此INTEL的做法是把它放在放在GDT中
 
详细参照
保护模式软件体系结构
应用程序捆绑核心编程
 
 
阅读(10290) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~