IA-32处理器存储管理 实模式到保护模式 段式管理

IA-32 CPU的分段机制和分页机制构成存储管理单元,并从硬件上支持存储管理。

在保护方式下,IA-32处理器必须使用分段机制,无法禁止。

IA-32处理器通过分段机制由逻辑地址获得32位线性地址 ,如不采用分页机制,则32位线性地址就是32位物理地址 ; 如果允许分页,则32位线性地址就是虚拟地址 ,由分页机制转换成32位物理地址

 

 


段式管理:

一个程序常包含多个段....代码,数据,堆栈等

每个段需要:段基地址,段界限,(访问权限,描述符)


并且,段表本身也是一个特殊的段,由操作系统维护....(GLTR存储段表基址及长度)

由逻辑地址到线性地址的转换过程为:

逻辑地址 (由段选择器及偏移地址32位组成)------>线性地址...

//实际指令执行时,一条指令若要取某个操作数时,由偏移地址,段选择器名字(可能2^3即由三个bit标识)来得到段寄存器(ds,es,ss),然后由这个段寄存器查找相应的段描述符。??

段选择器(即找到的寄存器??) :由高13位索引域及TI(1位)、RPL(2位,特权级别)组成.. TI为0则寻找GDT,TI为1寻找LDT。  --》LD其实也在GDT中.. 

RPL为本次请求的特权级别。。。。。 意思是与GD中DPL还有些不同....

段描述符 :共8个字节,基址(4个字节),界限(20位),访问权(1字节),其它属性共4个字节。-->由高字节到低字节依次为:

      [基址31-24][G,D/B,0,AVL,界限19-16]     6

      [访问权字节][基址23-16                         ]     4

      [基地址23-0位                                          ]     2

      [界限15-0位                                               ]     0


G:粒度,段界限是1B还是4MB,如为4MB,则界限可达2^20*4M=2^32B,即4G的段长度。

D/B在可执行代码段中时为D位:指明默认为16位操作数和寻址方式(0),或32位操作数和寻址方式(1)

D/B:在向下扩展的数段的描述符中,为B位。指明上限为4GB(1)或64KB(0)。???

D/B:在描述堆栈段(由SS指向段),为B位。 B=1,隐式堆栈访问指令(push,pop,call)使用32位esp, B=0时用sp..

AVL,不使用,可给操作系统使用....

访问权限字节有:[P,DPL两bit,S,TYPE四bit]

P:是否在内存中,存在位.

DPL:描述符特权等级0~3

S:是数据/代码段(s=1)还是系统段/门段(s=0)描述符.......

TYPE:  4bit故有16种状态。。???

          当为数据段类型时0-7:

               0  只读,  1  只读、已访问, 2  读/写, 3 读/写、已访问, 4  只读、向下扩展, 5  只读、向下扩展、已访问 ,  6   读/写、向下扩展,  7  读/写、向下扩展、已访问

           当为代码段时8-F:相对于数据段,执行对应于读,读对应于写,一致代码段对应于向下扩展。

           当为系统段时:???

           1  可用286TSS,2    LDT(说明是局部描述符表),3  忙的286TSS(说明正在执行或扶起)

  4   286调用门(?), 5   任务门(?),  6   286中断门(?),  286陷阱门(?)

           9  可用386TSS,   B    忙的386TSS,  C   386调用门, E  386中断门, F  386陷阱门.

   

一致代码段中一致的意思是:

当转移目标的一致代码段特权更高时,当前的特权级会被延续下去。 

当                非                                         ,会引起常规保护错误,除非使用调用门或任务门。??

并且,如果目标代码的特权级低,无论一致与否,都不能call或jmp进去.....

并且,所有数据段都是非一致的,故不可能被低特权级的代码访问到。。。。。与代码段不同的是,数据段可被更高特权的代码访问到,而不用特定的门。。。

 

这也就是说 :

对于非一致代码,只有相同特权级之间可访问....

对于一致代码,只有特权级高的不能访问低的。。。。。。

对于数据段(总是非一致):只有特权级低的不能访问高的,同级以及向下都是可访问的....

   //故对于一个打分程序,学生的可在用户态,老师的程序可在核心态,老师可改学生的,而学生则。。。


实现:

; 在下列类型值命名中:
;       DA_  : Descriptor Attribute
;       D    : 数据段
;       C    : 代码段
;       S    : 系统段
;       R    : 只读
;       RW   : 读写
;       A    : 已访问

 

 

 

 

 

 

 

 

 

 

............................... ....................................................................................常量定义好像有问题!!!!

; 描述符类型
DA_32        EQU    4000h    ; 32 位段


DA_DPL0        EQU      00h    ; DPL = 0
DA_DPL1        EQU      20h    ; DPL = 1
DA_DPL2        EQU      40h    ; DPL = 2
DA_DPL3        EQU      60h    ; DPL = 3

; 存储段描述符类型
DA_DR        EQU    90h    ; 存在的只读数据段类型值
DA_DRW        EQU    92h    ; 存在的可读写数据段属性值
DA_DRWA        EQU    93h    ; 存在的已访问可读写数据段类型值
DA_C        EQU    98h    ; 存在的只执行代码段属性值
DA_CR        EQU    9Ah    ; 存在的可执行可读代码段属性值
DA_CCO        EQU    9Ch    ; 存在的只执行一致代码段属性值
DA_CCOR        EQU    9Eh    ; 存在的可执行可读一致代码段属性值

; 系统段描述符类型
DA_LDT        EQU      82h    ; 局部描述符表段类型值
DA_TaskGate    EQU      85h    ; 任务门类型值
DA_386TSS    EQU      89h    ; 可用 386 任务状态段类型值
DA_386CGate    EQU      8Ch    ; 386 调用门类型值
DA_386IGate    EQU      8Eh    ; 386 中断门类型值
DA_386TGate    EQU      8Fh    ; 386 陷阱门类型值

 

 



段描述符的宏定义如下:

参数1:基址

参数2:段界限

参数3:属性


%macro Descriptor 3
    dw    %2 & 0FFFFh                ; 段界限1       (0-15)
    dw    %1 & 0FFFFh                ; 段基址1       (0-15)
    db    (%1 >> 16) & 0FFh            ; 段基址2  (16-23)
    dw    ((%2 >> 8) & 0F00h) | (%3 & 0F0FFh)    ; 属性1 + 段界限2 + 属性2      界限为:16-19,把第访问权字节和G,D,AVL统一处理. 
    db    (%1 >> 24) & 0FFh            ; 段基址3   (24-31)
%endmacro ; 共 8 字节

 

 

 

 

l

另关于LDT....LDT在系统中可有多个,但是每个任务最多一个。。。 引用如下:

(Linux 只用到 GDT,而没有使用LDT。。。).

 

GDT 可以被放在内存的任何位置,那么当程序员通过段寄存器来引用一个段描述符时,CPU必须知道GDT的入口,也就是基地址放在哪里,所以 Intel的设计者门提供了一个寄存器GDTR用来存放GDT的入口地址,程序员将GDT设定在内存中某个位置之后,可以通过LGDT指令将GDT的入口 地址装入此积存器,从此以后,CPU就根据此积存器中的内容作为GDT的入口来访问GDT了。
GDT是Protected Mode所必须的数据结构,也是唯一的——不应该,也不可能有多个。另外,正象它的名字(Global Descriptor Table)所揭示的,它是全局可见的,对任何一个任务而言都是这样。
除 了GDT之外,IA-32还允许程序员构建与GDT类似的数据结构,它们被称作LDT(Local Descriptor Table),但与GDT不同的是,LDT在系统中可以存在多个,并且从LDT的名字可以得知,LDT不是全局可见的,它们只对引用它们的任务可见,每个 任务最多可以拥有一个LDT。另外,每一个LDT自身作为一个段存在,它们的段描述符被放在GDT中。
IA-32为LDT的入口地址也提供了 一个寄存器LDTR,因为在任何时刻只能有一个任务在运行,所以LDT寄存器全局也只需要有一个。如果一个任务拥有自身的LDT,那么当它需要引用自身的 LDT时,它需要通过LLDT将其LDT的段描述符装入此寄存器。LLDT指令与LGDT指令不同的时,LGDT指令的操作数是一个32-bit的内存地 址,这个内存地址处存放的是一个32-bit GDT的入口地址,以及16-bit的GDT Limit。而LLDT指令的操作数是一个16-bit的选择子,这个选择子主要内容是:被装入的LDT的段描述符在GDT中的索引值——这一点和刚才所 讨论的通过段积存器引用段的模式是一样的。



评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值