上一节讲啦段寄存器具有属性特征,本节会讲到段描述符和段选择子的

上节讲了段寄存器有96位,其中只有16位是可见的(剩下的80位缓冲到CPU里面去了),这可见的16位就是段选择子

其中这16位分为3部分

0~1位:为RPL 称为请求特权级别,2个位就有4种权限  0  ,1,2,3  数字越大,权限越小反之

第2位:TL    当TL=0的时候去GDT(全局描述符表中去加载段描述符)  TL=1去LDT(局部描述符表,这个Windows没有使用)

3~15:    Index 索引这个值会作为下标去GDT表中找到对应的表项(32位系统下GDT表每项8个字节,每项位一个段描述符)

            加载这个段描述符。

Index指定我们加载的GDT表项,也就是指定加载的段描述符,很多人可能注意到了0~1位的请求特权级别RPL,

Index虽然作为索引能够让我们定位到对应的段描述符,并加载它,但是这个段描述符不一定加载成功,每个段描述符里有一个属性,它能指定想要加载我的段寄存器你必须拥有什么样的权限我才能被你加载,如果你没有这样的权限,那不好意思,我们不合适

(我们可以理解为,段描述符就是相亲的姑娘,有的要求男性必须有房有车,有的要求必须是富二代,当然也有的没有任何要求)

相亲的男士就可以看成段选择子,去相亲了(相当于找到了这个段描述符与),然后把自己的条件(RPL请求特权级别)与姑娘们要求对比,如果达不到要求,那拜拜加载段描述符失败,如果达到了要求那就可以试试了。

段描述符具有64位在GDT表中结构如下

P位:段描述符中高4字节中的15位P位是最重要的1位,如果P=0代表这个段描述符不用看了无效是个无效描述符

          P=1代表这个段描述符有效(如果P=0其它的所有操作比较啊都没有意义)

G位:是粒度G=0代表20位的Limit的单位是BYTE,G=1代表20位的Limit的单位是4KB一个页

        G=0或1只会决定能访问的大小,不会决定段的大小,只决定Limit的范围(而Limit决定你能访问段的大小)

D/B位:会在后面进行讲解比较复杂

DPL:在段描述符的高4字节的13-14位,表示段描述符特权级,只有想要加载这个段描述符的选择子的请求特权级别高于

        或者等于DPL才能加载这个段(也就是你达到了女方要求的条件了)RPL(权限大于)>=DPL只是条件之一,下一篇帖子

        段权限检查会给大家全面的讲述,加上实践检验

S位: S=0代表这个描述符是系统段描述符,S=1代表这个段描述符是代码段描述符或者数据段描述符

      GDT中的描述符分为两类一类是系统段描述符,另一种数据段描述符或者代码段

 

当S=1的时候参考下图

S=1 且TYPE域<8时代表这个段描述符是一个数据段

A位代表这个段有没有被访问过,访问过A=1,没有访问过A=0

W位:W=1代表这个段可读可写,W=0代表这个段只读

E位:扩展方向E=0代表向上扩展,E=1代表向下扩展

向上扩展:我们前面讲过一个段的访问范围是 Base到Base+Limit  所以0x3B         
FS的段只能访问一个页的数据,DS,CS,ES的能访问整个4GB,向上扩展代表这个段能访问的范围是 Base到Base+Limit

向下扩展:代表4GB空间除了Base到Base+Limit之间的空间不能访问,其他的所有空间都能访问,相当于就是向上扩展的取反

S=1 且TYPE域>=8时代表这个段描述符是一个代码段

A位代表这个段有没有被访问过,访问过A=1,没有访问过A=0

R位:R=0代表这个代码段可执行,R=1代表这个段可以执行可读

C位:C=0是非一致代码段  (这个在后面的帖子详细讲)

          C=1是一致代码段

 

段描述符的D:B位要分几种情况讨论(之所以要分为这些情况必须向下兼容)

1:对数据段不管是上下兼容还是向下兼容 

      D/B=1段上限为4GB

      D/B=0段上限为64KB           8086模式下采用段寄存器*16+偏移地址(16位)=寻址1MB

2:对代码段的影响                   如果代码段选择子加载到cs中了      

      D/B=1采用的是32位寻址的方式

      D/B=0才是16位的寻址方式            学过硬编码的朋友们应该知道硬编码67可以改变默认的寻址方式  不会改变D/B位

 3:对SS段的影响                    如果数据段描述符加载到了ss段寄存器中去了

     D/B=1                                 隐式堆栈访问指令 (PUSH  POP 
CALL)使用32位堆栈指针ESP

     D/B=0                                 隐式堆栈访问  (PUSH  POP  CALL)使用16位堆栈指针SP

如果是数据段描述符或者代码段描述

段描述符中高4字节的24-31位:作为Base的24-31位    高4字节的0-7位:作为Base的16-23位

段描述符中低4字节的16-31位:   作为Base的低16位   

段描述符中低4字节中的0-15位:作为Limit的低15位     段描述符高4字节中的16-19位作为Limit的16-19位

G位很重要如果G=0,则Limit的的20-31位全都填充0 单位是BYTE

如果G=1 Limit的20-31位全都填充0,单位是4KB(一个小页  4096字节) 

Atttibute就是段描述符的高四字节的8-23位,这个属性位按位控制段的一些属性

如果段描述符中的P=1  S=0,则是系统段描述符,此时根据TYPE的值分为以下几种系统段描述符

 

这篇帖子将的是段描述符的解析,段描述符顾名思义就是描述段的(比如数据段的可写,扩展,代码段的可写等等段的属性),系统描述符和数据段代码段有又不同(在后面会讲到),数据段和代码段将的差不多了,下一篇是段的权限检查,保护模式一定要围绕着段,页,段机制和页机制对内存的保护,需要了解到段页做了什么,以及如何保护,就能理解段页了理解保护模式了

 

 

技术
下载桌面版
GitHub
Gitee
SourceForge
百度网盘(提取码:draw)
云服务器优惠
华为云优惠券
腾讯云优惠券
阿里云优惠券
Vultr优惠券
站点信息
问题反馈
邮箱:[email protected]
吐槽一下
QQ群:766591547
关注微信