现代INTEL CPU都有保护模式,实模式这两种CPU运行模式。当CPU加电,CPU初始化时就运行在是模式下,然后现代操作系统会从实模式跳转到保护模式!
为什么需要保护模式?
在最开始编程的汇编时代,程序员的工作就是读懂处理器指令,然后用这些指令来写程序完成工作!一个程序员要写一个程序,这个程序包括了驱动CPU,驱动内存,驱动磁盘等所有的代码,否则就是一颗裸CPU无法运行!后来每一个程序员都觉得这些驱动过程几乎一样,所以就开始构写操作系统,然操作系统来干这些事情!操作系统(这里指的是最原始的操作系统,其功能只完成一个,比如完成计算器功能)写完之后,后一代的程序员要写程序,还是要读懂CPU指令,只是不需要再从头到会驱动所有硬件了!操作系统后来走向商业化,一些程序员写的操作系统拿出来卖,然后其他程序员在操作系统的基础之上来写程序!这个时候就遇到一个问题!因为操作系统的编写所使用的工具(CPU指令)和那些程序员所使用的工具(CPU指令)都是一样的!而且水平也几乎差不多,所以这个时候的程序员就有能力直接修改操作系统的某个指令(操做系统加载在内存中,那个时候程序员可以通过指令直接修改内存里任何位置的任何数据,从而导致修改了原始操作系统本身),来完成自己所需要的任务(想一想现在的程序员有几个有能力通过汇编直接去修改windows内核呢)!起初,这些修改非常合理。随着计算机的操作系统的发展,原始操作系统功能逐渐增加,所程序员水平的下降,程序员随意修改操作系统指令,就会导致操作系统的崩溃,这种崩溃就如滚雪球一般越来越多,越来越普遍,所以必须要启用一种机制让非系统程序员不能随意更改操作系统的指令!这个机制就是保护模式
保护模式是如何起到保护作用的呢?
你想想,如果你是INTEL CPU设计师,出现这个问题时,你要如何来设计让其他程序员不能在内存中随意修改你的代码这种保护机制?
我能想到最简单的方式就是,不允许其他程序员访问操作系统内核的内存:将操作系统加载到内存地位,每当用户一个指令需要访问内存时,就判断当前访问的地址是否在操作系统的内存范围内,如果是就报错,否则读取内存!如果你也是这样想,那么恭喜你,可以去INTEL当CPU构架师,当上总经理,出任CEO,打败高富帅,迎娶白富美,走上人生的巅峰。你的操作系统内存范围在INTEL中有个专有名词叫做 段 !!!在CPU级别的编程中,程序是由 段 构成。你的一整条内存,被切割成不同的 段 。每一个段有自己的属性和权限!INTEL 80286 CPU对于程序段的权限有四个等级 0、1、2、3!数字越大,权限越小(请重复读一千遍,再继续阅读下文)!通常你的操作系统就是权限最高的等级0。普通程序段处于等级3。INTEL 代码段有个DPL属性,可以让你来定义你的程序段的等级
现在你要计算2的20次方是多少,你在你的操作系统下,就需要自己的写这个算法的实现,别人用你的系统时也需要去实现这个功能!重构的思想在你脑袋里胡鹏乱撞。你为什么不把这种算法公开给其他程序员使用呢?为什么要浪费精力去重新写算法呢?但是你的操作系统代码不允许任何人访问,这又是一个问题!为了解决这个问题INTEL 给代码段增加了一个属性:代码是否一致
代码一致:允许代码段等级相同和代码段等级较低的代码访问
代码非一致:只有代码段等级相同可以访问
所以就只需要将你的幂计算的数学实现代码段设置为代码一致,就可以让权限较低的代码段访问了!
等级怎么跳转?
每个代码段都一个DPL,CPU当前所要执行的指令cs:ip的DPL是多少呢?当然就是指令所在段的DLP!假设cs:ip的指令属于代码段1,而即将要执行的指令是jmp 代码段2:偏移。那这个时候CPU怎么运行?代码段2有一个DPL,代码段1也有一个DPL,这个时候CPU当然要比较目前的代码段1!实际上每次代码段跳转之后,就会将代码段的DPL记录在CS寄存器的低2位,这个2位被称为CPL。也就是说CPL实际上就是DPL(代码段被加载后DPL的另一个名字,如果代码段没有被加载,说一个段的CPL没有任何意义)。但是这里有一个例外:如果要跳转的代码段是一致代码段,跳转过后CPL不会修改为一致代码段的CPL,而是保持上一个段的CPL
CPL和DPL如何比较?
说到比较,就得有一个比较对象和比较规则,比较目的,不同对象之间的比较意义不是很大——手机比大象小、猩猩比美女黑。。
比较对象:代码段的权限。各自对对应的代码段的权限
比较目的:权限大小。比较各自代码段对应的权限大小。
比较规则:因为代码段有很多种(代码段的种类通常是由代码段的属性定义)!所以对于不同的代码段,DPL有不同的意义!也就代表了不同的比较规则。皇帝的DPL和太监的DPL肯定代表不同的意义。下面来看一下各种代码段的DPL定义
- 数据段、调用门、TTS的DPL:最低权限——CPL的权限比DPL的权利更大!县长最低需要的权利值(省长或省长以上的官才能够提出意见)
- 一致代码段、非一致代码段(通过调用门访问):最高权限——CPL的权利比DPL的权利小!(你就是总统也必须没有权利干涉我州的事情)
- 非一致代码段(不通过调用门访问):同级权限——(我是省长,你也必须是省长)!
什么又是RPL?
网上说RPL是程序员一个意图,就是程序在编写时,程序员一厢情愿的希望某个代码段是哪个等级!但是实际在运行过程中,CPU还是要看代码段本身的CPL等级!如果RPL等级更低,就用更低的权限跳转到目标段,如果更高,就用CPL的权限跳转到目标段!我不太理解这样做有什么意义,希望有人知道的,能指点我,谢谢!