3.2.3节:特权级

转载 2016年08月31日 16:19:25

原来看第3.2.3节的时候,感觉很难的。为什么会感觉难呢? 因为这一节谈到的特权级别关系比较复杂,不容易弄清楚。这次重看一次这一节后,进行了一点小结,这才感觉比较清楚了。
      这一节的主要内容可以用下面这个表格来描述。

目标代码段

Jmp指令

Call指令

直接调用

通过调用门

一致码段

CPL>=DPL,不检查RPL

可以跳转到相同或者更高特权级别执行

CPL<=DPL_G,RPL<=DPL_G

CPL>=DPL

访问调用门的规则同访问数据段,即调用门只能被特权级别不低于其DPL(DPL_G)的代码访问。可以跳转到相同或者更高特权级别执行。

非一致码段

RPL<=CPL=DPL

只能跳转到同特权级别的代码段

 

1.  三种特权级别

CPL:当前特权级别。当前正在运行的代码所处的特权级别,保存在CS和SS的低2位中。

DPL:描述符特权级别,即段描述符中DPL字段的值,是与描述符相关的特权级别。

RPL:请求特权级别,即用于访问代码、数据或者堆栈的段选择子低2位的值。

注意特权级别的表示:有0至3这4个特权级别,0级最高,3级最低,即数字大则特权级别低。表中CPL、RPL、DPL等都是代表数字的。

2. 一致码段和非一致码段

(1)一致码段:无论采用哪种方式跳转到一致码段,CPL都不改变(不变化为目标代码段的DPL),也即在加载目标代码段选择子时,只加载高14位,表示CPL的低2位保持不变。

(2)非一致码段:无论采用哪种方式跳转到非一致码段,CPL都发生改变,也即在加载目标代码段选择子时,将整个选择子放入到CS中。

“一致”的意思就是:代码段被调用执行时不使用自己的描述符的DPL,而采用调用者特权级别,CS的低2位保持不变,与调用者特权级别保持一致。

是不是一致码段由描述符中的相应位标志确定(参看47到49页的表格)。

3. Jmp与Call

Jmp指令仅仅进行执行流程的跳转,不会保存返回地址。

Call指令在进行流程跳转前会保存返回地址,以便在跳转目标代码中可以使用ret指令返回到call指令的下一条指令处继续执行。执行段内跳转时,只保存EIP;如果是段间跳转,还保存CS。

对于使用Call指令(无论是直接调用还是通过调用门)进行的跳转,如果跳转后特权级别将发生改变(总是从低到高,从上述第2点知道,只有跳转到非一致码段时才会发生特权级别变化),则执行call指令前必须准备好任务状态段TSS。跳转过程是:(1)保存调用者的SS和ESP到被调用者堆栈中(2)调用参数先保存在调用者堆栈中,然后被复制到被调用者堆栈中(3)当前CS和EIP被保存到被调用者堆栈中。在通过call进行的有特权级别变化的跳转中,堆栈会发生切换,这时要保存当前堆栈指针(SS:ESP),而当前指令指针(CS:EIP)保存到新的堆栈(被调用者堆栈)中,这是与没有特权级别变化的跳转不同的。没有特权级别变化时,不需要保存SS:ESP,不存在调用参数的复制,不存在堆栈切换。

4. ret和retf

这两个指令的功能都是调用返回。

(1) ret在返回时只从堆栈中取得EIP;retf中的字母f表示far,即段间转移返回,要从堆栈中取得EIP和CS。

(2)两个指令都可以带参数,表示发生过程调用时参数的个数,返回时需要从堆栈中退出相应个数的参数

(3)恢复CS时,如果发现将发生特权级别变化(当前CS的低2位不等于从堆栈中取得的新的CS值的低2位。从上述第2点知道,只有跳转到非一致码段时才会发生特权级别变化,那么,也只有从非一致码段返回时才会发生特权级别返回),则还要从调用者堆栈中取得ESP和SS恢复到相应寄存器中,也即恢复调用者堆栈。

5. 任务状态段TSS

为避免相互干扰,要求不同特权级别的代码运行时使用不同的堆栈,也就是在特权级别发生改变时必须切换堆栈段。0、1、2特权级别的堆栈指针保存在TSS中,在跳转到相应级别时从TSS中取出相应的堆栈指针进行堆栈切换。因为只有从低特权级别跳转到高特权级别时才需要从TSS中取得新的堆栈指针,所以TSS中不存在最低特权级别3的堆栈指针。

 

综上所述,所有的复杂只有一点:仅仅在通过调用门从低特权级别跳转到高特权级别的非一致码段时,才会发生CPL改变,才需要先准备好TSS,才会发生堆栈切换(在调用前从TSS中取得新的堆栈指针;调用返回时从被调用者堆栈中取得原堆栈指针进行恢复)。

CPL、RPL、DPL的区别


CPL(Current   Privilege   Level) 当前(代码)特权级。在保护模式下,CS寄存器、SS寄存器中分别存放着代码段、堆栈段的选择子。CPL在CS、SS的第0、1位(第0位到15位)中。CPL一般情下等于所装载的段的特权级。对于一致代码段来说,CPL不会随着所装载的段的特权级而改变。

DPL(Descriptor   Privilege   Level) 描述符特权级在每个存储段(数据段、代码段、堆栈段)描述符、门(调用门、任务门、中断门、陷阱门)描述符、任务状态段(TSS)描述符的第5个字节(第0字节到第7字节)的第5、6位(第0位到第7位)中。DPL主要用来与CPL比较,来确定当前代码是否能够访问相应的段。

RPL(Request   Privilege   Level) 选择子特权级,在每个选择子的第0、1位(第0位到15位)中。RPL主要用来改写CPL,当进行段访问的时候,取CPL和RPL中数值大的一个(即取权限小的一个)。如:CPL为0,要访问的调用门DPL为2,但是选择子的RPL为3,此时不可以访问调用门。

没有特权级变换的进程调度示例

  • 2009年12月02日 09:28
  • 348KB
  • 下载

任务和特权级保护(三)——《x86汇编语言:从实模式到保护模式》读书笔记34

任务和特权级保护(三)——《x86汇编语言:从实模式到保护模式》读书笔记34...

当我们谈论开机的时候我们在谈论些什么(三)——特权级(未完成)

注:本文所有说到特权级大小的地方都是指的数字。本文阐述了两部分内容: 1、一致代码段和非一致代码段 2、怎么设置特权级特权级这部分比较绕,说起来并没有很多东西,但是需要整理整理。一、一致代码段和非...
  • sium__
  • sium__
  • 2015年12月07日 21:36
  • 381

特权级1——RPL、DPL、CPL .

保护模式中最重要的一个思想就是通过分级把代码隔离了起来,不同的代码在不同的级别,使大多数情况下都只和同级代码发生关系。Intel的80286以上的cpu可以识別4个特权级(或特权层) ,0级到3级。数...

代码段间转移控制时的特权级检查(JMP/CALL)——《x86汇编语言:从实模式到保护模式》读书笔记28

代码段间转移控制时的特权级检查(JMP或者CALL指令)在保护模式下,JMP或CALL指令可以用以下四种方法之一来引用另外一个代码段: 1. 目标操作数含有目标代码段的段选择子和偏移 2. 目标操...

特权级--ring0到ring3

内核要和用户程序分开,内核一定要安全,不能被用户程序干涉,但是有时候用户程序也需要读取内核的某些数据,怎么办呢?x86就引入了访问特权等级(0-3)的机制,x86 cpu共有4个特权级 level0 ...
  • bfboys
  • bfboys
  • 2016年09月03日 10:19
  • 132

自己动手写操作系统 降入ring3特权级

;进入ring3 push SelectorStack3 push TopOfStack3 push SelectorCodeRing3 push 0 retf

不同特权级代码段之间的跳转(CPL DPL RPL之间的关系)

1、特权级 2、一致代码段和非一致代码段 3、DPL、RPL、CPL分别代表的含义,存储在什么位置,以及它们之间的关系 4、不同特权级数据段之间的访问规则 5、不同特权级代码段之间的转移 6...

jmp,call,ret,特权级转移,进程调度

jmp,call,ret,特权级转移,进程调度 ①jmp是不负责任的调度,不保存任何信息,不考虑会回头。跳过去就什么也不管了。 ②call,保存eip等,以便程序重新跳回。ret是call的逆过程...

专注于操作系统18之完整的特权级转换

在上一篇文章中,我们已经能从ring0级进入到ring3级,在这里我们将再加上从ring3级到ring0级。从ring3级到ring0级这需要使用在第十四篇文章中提到的调用门来实现。即在进入ring3...
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:3.2.3节:特权级
举报原因:
原因补充:

(最多只允许输入30个字)