访问不同的数据段和代码段会产生特权级检查。
CPL—当前执行任务或程序的特权级,在CS和SS段寄存器的0、1位保存。正常情况下CPL与取指令的代码段特权级相同,当程序跳转到不同特权级的代码段时,CPL会随着改变。但是,处理器在访问不同特权级的一致代码段时,CPL不会改变。一致代码段可以被数值上大于等于其DPL的一致代码段访问。(一致代码段,CPL>=DPL(数值>=,相反地,特权级变低),当时CPL不会变)
DPL—要访问的门或段的特权级,保存在段或门描述符的DPL字段中。当执行的代码段试图访问门或段时,需要比较目的门或段的DPL与当前代码段的CPL和RPL。DPL取决于段或门的类型:如果是数据段,DPL表示访问该段的数值最高的特权级(规定最低特权级),比如,数据代码段的DPL为1,CPL只有在0或1才能访问该段;如果是非一致代码段(不通过调用门),DPL表示访问该段的特权级,比如DPL为1,只有CPL为1才能访问;如果是调用门,与数据段相同;如果是一致代码段和非一致代码段通过调用门,DPL表示访问该段数值最小的特权级(规定最高特权级),比如,DPL为2,则CPL为2或3可以访问,0或1不可以访问;如果是TSS,与数据段相同。
RPL—在段选择器中保存,处理器检查和CPL一起的RPL决定是否可以访问一个段。如果有足够的CPL,RPL不足够,也不能访问一个段。如果一个段选择器中的RPL数值大于CPL,CPL的值就会被RPL重写。RPL保证特权级代码不会代替应用程序访问一个段,除非应用程序自己有特权级去访问这个段。(比如,应用程序CPL、RPL为2,通过操作系统的内核代码系统调用访问某以资源时,此时的CPL可能变为0,如果没有RPL,应用程序依靠CPL为0可能访问到它不应该访问的数据,有了RPL对CPL检查,发现RPL>=CPL,此时CPL重写为RPL的值2,起到保护作用)。
一致代码段和非一致代码段:
在代码段描述符中的TYPE字段中C位,为1表示一致代码段,为0表示非一致代码段。一致代码段属于共享代码,可以被低特权级的访问。一致代码段:特权级高的程序不允许访问低特权级的数据,内核态不允许调用用户态的数据;特权级低的程序可以访问特权级高的数据,但是特权级不会改变。非一致代码段:避免低特权级的访问被操作系统保护的代码,只允许同级调用,禁止不同级调用。
通常低特权级的代码通过门来对特权级高的代码访问和调用。