我们在工作中,公司都给员工配有员工卡,此员工卡就是员工身份的“标签”,用它来出入公司、食堂就餐等。给公司创造价值的是员工的生产力,不是员工卡,员工卡只是公司人事部门管理员工的一种手段而已。

现在说计算机,既然是用特权级来维护计算机世界的和平,那总该给每个被管理的对象加个特权“标签”,也就是说cpu得知道谁的特权高谁的特权低,这样才能辨识出是否有低特权级的程序越级访问高特权级资源的违法行为。

员工的标签体现在工卡,计算机特权级的标签体现DPL,CPL和RPL,下面咱们围绕这几个概念展开讨论。

先看看访问者的特权标签在哪里。

最初我们刚接触保护模式的时候,最先感受到的区别是,访问内存不像在实模式下那么自由、直接啦,在保护模式下有了段描述符,访问内存得先经过它才行,它的作用是通过各种属性描述一段内存区域,该描述符就相当该内存区域的“身份证”。

前情提要,x86访问内存的机制是“段基址:偏移地址”,无论是实模式还是保护模式,都要遵循此方式。在实模式下,段基址直接写在段寄存器中,而在保护模式下,段寄存器中的不再是段基址,而是段选择子,通过该选择子从GDT或LDT中找到相应的段描述符,从该描述符中获取段的起始地址。大伙儿还记得选择子的结构吧,第0~1位是RPL字段,第2位是TI位,第3~15位是段描述符索引,好啦,回忆到此为止。咱们要关注的就是RPL字段,它就是请求特权级,后面讲RPL的时候咱们会细说。请求特权级中的“请求”是个动词,只有具备“能动性”的访问者才能做出动作。

话说回来了,谁是访问者?计算机中,具备“能动性”的只有计算机指令,只有指令才具备访问、请求其它资源的能力,指令便是资源的请求者。指令“请求”、“访问”其它资源的能力等级便称之为请求特权级,指令是存放在代码段中,所以,就用代码段寄存器CS中选择子的RPL位表示代码请求别人资源能力的等级。代码段寄存器CS和指令指针寄存器EIP中指向的指令便是当前在处理器中正在运行的代码,所以,位于CS寄存器中选择子低2位的值不仅称为请求特权级,又称为处理器的当前特权级,也就是说处理器的当前特权级是CS.RPL。

处理器的当前特权级的真实面目是什么?

在cpu运行的是指令,其运行过程中的指令总会属于某个代码段,该代码段的特权级(也就是代码段描述符中的DPL)便是当前cpu所处的特权级,这个特权级称为当前特权级,即CPL(Current Privilege Level),它表示处理器正在执行的代码的特权级别。除一致性代码段外(后面会说),转移后的目标代码据段的DPL是将来处理器的当前特权级CPL。

指令最终是用处理器执行的,执行到不同特权的代码,处理器的特权级就换到不同的等级。所以,当前特权级实际上是指处理器当前所处的特权级,是指处理器的特权角色,更形象一点地说,是指cpu当前在计算机世界中的特权地位。再次提醒大伙儿,在任意时刻,当前特权级CPL保存在CS中选择子中的RPL部分。

当前特权级是存储在CS.RPL中,谁为代码段寄存器CS赋值的呢? 要回答上面的问题,得先搞清楚处理器的当前特权级为什么会变化。

当前正在运行的代码所在的代码段的特权级DPL就是处理器的当前特权级,当处理器从一个特权级的代码段转移到另一个特权级的代码段上执行时,由于两个代码段的特权级不一样,处理器当前的特权身份起了变化,这就是当前特权级CPL改变的原因。好像说的有点神秘,其实就是使用了那些能够改变程序执行流的指令如int、call等,这样就使CS和EIP的值改变,从而使处理器执行到了不同特权级的代码。不过,特权转移可不是随便进行的,处理器要检查特权变换的条件,这里咱们暂不讨论条件是什么,因为它需要过会儿结合RPL一块说,等小弟把RPL给大伙儿说清楚了再解释这个“条件”不迟。当处理器特权级检查的条件通过后,新代码段的DPL就变成了处理器的CPL,也就是目标代码段描述符的DPL将保存在代码段寄存器CS中的RPL位。

总之,代码是资源的请求者,代码段寄存器CS所指向的是处理器中当前运行的指令,所以代码段寄存器CS中选择子的RPL位称为当前特权级CPL,这是再合理不过的事了。

RPL变成了CPL,似乎有点晕是吗?其实只是代码段寄存器CS中的RPL是CPL,其它段寄存器中选择子的RPL与CPL无关,因为CPL是针对具有“能动性”的访问者(执行者)来说的,代码是执行者,它表示访问的请求者,所以CPL只存放在代码段寄存器CS中低2位的RPL中。

以上几段内容想表达的就是处理器的当前特权级CPL为什么放在CS.RPL中,CPL和CS.RPL有什么关系,不信您再回头看一遍^_^。

大多数情况下,处理器都是在“访问者”访问“受访者”时进行特权检查,访问者(某个代码段)的特权就是当前特权级CPL,在进行特权检查时,都会以CPL为基础,说到这里,不禁我要自问一下,既然CPL就是目标代码段的DPL,那处理器总该有个初始CPL吧。答案是肯定的,特权级是保护模式下的概念,处理器进入保护模式后才有的当前特权级,让我们回忆下处理器是怎么进入保护模式的,也许答案自然就揭晓啦。

在这之前,我和大家说过,MBR从BIOS接过接力棒的时候,它已经处于0特权级啦,其实这么说不太合适,毕竟在保护模式下才有特权级,而MBR是运行在实模式下,还谈不上特权级。BIOS将控制权交给MBR,是用一个远跳转指令实现的,即jmp 0:0x7c00,也就是说进入MBR后,段寄存器CS会被替换为0,如果此时把CS看作是选择子的话,RPL的值为0,也就是说“相当于”处于0特权级,段寄存器CS为0的情况一直持续到在loader中进入保护模式之后的第一条指令:流水线刷新跳转。该跳转语句如图

一步步编写操作系统 54 CPL和DPL入门1相关推荐

  1. 一步步编写操作系统 55 CPL和DPL入门2

    接上节. 图中第132行的jmp指令,段选择子为SELECTOR_CODE,其RPL的值为RPL0,RPL0定义在include/boot.inc中,其值为0.选择子的索引部分值为1,表示对应GDT中 ...

  2. 一步步编写操作系统 71 直接操作显卡,编写自己的打印函数71-74

    一直以来,我们在往屏幕上输出文本时,要么利用bios中断,要么利用系统调用,这些都是依赖别人的方法.咱们还用过一个稍微有点独立的方法,就是直接写显存,但这貌似又没什么含量.如今我们要写一个打印函数了, ...

  3. 一步步编写操作系统 69 汇编语言和c语言共同协作 70

    由于有了上一节的铺垫,本节的内容相对较少,这里给大家准备了两个小文件来实例演示汇编语言和c语言相互调用. 会两种不同语言的人,只是掌握了同一件事物的两种表达方式.人在学习一种新语言时,潜意识里是建立了 ...

  4. 一步步编写操作系统 62 函数调用约定

    由于我们要将c语言和汇编语言结合编程啦,所以一定会存在汇编代码和c代码相互调用的问题,有些事情还是要提前交待给大家的,本节就是要给大家说下函数调用规约中的那些事儿. 函数调用约定是什么? 调用约定,c ...

  5. 一步步编写操作系统 58 门、调用门与RPL序 3

    接前文: 并不是任何当前特权级都可以使用门结构, 在使用门结构之前,处理器要例行公事做特权级检查,参与检查的不只是CPL和DPL,还有RPL,为了说清楚这个检查过程,咱们得先介绍下RPL. RPL,即 ...

  6. 一步步编写操作系统 57 门、调用门与RPL序 2

    接上文: 提供了4种门的原因是,它们都有各自的应用环境,但它们都是用来实现从低特权级的代码段转向高特权级的代码段,咱们这里也只讨论有关特权级的功用: 1.调用门 call和jmp指令后接调用门选择子为 ...

  7. 一步步编写操作系统 60 cpu的IO特权级2 什么是驱动程序

    用户程序可以在由操作系统加载时通过指定整个eflags设置,操作系统如何设置自己的IOPL呢,即使内核IOPL为0也得写进去eflags寄存器中才生效.可惜的是,没有直接读写eflags寄存器的指令, ...

  8. 一步步编写操作系统 59 cpu的IO特权级1

    在保护模式下,处理器中的"阶级"不仅体现在数据和代码的访问,还体现在指令中. 一方面将指令分级的原因是,有些指令的执行对计算机有着严重的影响,它们只有在0特权级下被执行,因此被称为 ...

  9. 一步步编写操作系统 34 内核利用bios中断获取物理内存大小

    接上文,另一个获取内存容量的方法是bios 0x15中断的子功能0xE801. 此方法虽然简单,但功能也不强大,最大只能识别4G内存,不过这对咱们32位地址总线足够了.稍微有点不便的是,此方法检测到的 ...

最新文章

  1. python 调用c++ 传输图片
  2. 【C 语言】二级指针案例 ( 字符串切割 | 返回 二维数组 作为结果 )
  3. Spring Cloud生态的配置服务器最全对比贴
  4. SVM的发展和研究热点
  5. ip route / ip rule /iptables 配置策略路由
  6. 2008秋-计算机软件基础-第三章- 二叉排序树
  7. javadocx转换成html_使用Java将Word转为Html或txt[转]
  8. 通达信zig函数的python实现
  9. [编程语言]C陷阱与缺陷
  10. 泛微平台ecology8.0二进制文件流下载对接接口
  11. cad灯具图标_灯具在CAD中怎么表示出来 都代表哪种灯 谢谢
  12. 使用kmean进行图像分割 使用CRFs进行分割后处理
  13. 银行股的分红是不是比利率要高,投十万银行股一年分红有多少啊?
  14. AcWing 95. 费解的开关 (递归位运算 详解)
  15. 使用Intent协议在webview中跳转三方app
  16. 苹果手机通话怎么录音?通话录音的详细教程!
  17. 高效下载Google Drive中的大量文件
  18. JAVA程序设计:救生艇(LeetCode:881)
  19. 常见的一些威胁情报分析平台
  20. python-二维码的生成与识别

热门文章

  1. 十万个为什么 —— 为什么一个数的 0 次方只能是 1
  2. BFS HDOJ 1242 Rescue
  3. 生命、生活:同样重要
  4. java 面板 选择颜色_[代码全屏查看]-java颜色选择器
  5. java 私有变量访问_Java - 访问私有实例变量
  6. mysql 查询两张表结构相同的数据库_利用反射处理多个表结构相同的数据的查询和数据库表的关联...
  7. opencv rect画旋转矩形_在opencv c中绘制旋转的矩形
  8. 1282B1. K for the Price of One (Easy Version)
  9. python 文件状态_Python:如何访问文件的状态
  10. mysql多源复制 知乎_MySQL多主一从(多源复制)同步配置