3.2.3节:特权级
来源:互联网 发布:英国大学 档次 知乎 编辑:程序博客网 时间:2024/06/08 17:42
原来看第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,此时不可以访问调用门。
- 3.2.3节:特权级
- 特权级3(调用门)
- 【PM复习】特权级(3)
- 特权级3(调用门)
- 特权级3——调用门
- 特权级0的代码到特权级3代码的转移之IRET指令
- 特权级转移总结
- 特权级1
- 特权级转换
- CPU特权级保护
- 特权级概述
- 特权级的意味
- 特权级保护
- 特权级保护
- 5-特权级
- 分段模式和特权级
- 特权级之间的转换
- 一致代码于特权级
- JS最新的身份证验证代码
- 234. Palindrome Linked List
- Redis: Jedis中publish/subscribe 使用
- Liblinphone 3.9.1中文--Modules--Controlling network parameters (ports, mtu...)
- 游戏开发之单位
- 3.2.3节:特权级
- php对象赋值
- 【Linux】tar文件安装
- etcd 集群搭建及常用场景分析
- Ogre源码编译步骤
- H.264分层结构:VCL、NAL
- Weli的Android学习日记 0.1控件抖动效果
- String 类别中已经提供了将基本数据型态转换
- 软件工程中英对照术语表