请求特权级别RPL和当前特权级CPL不相同的例子

请求特权级别RPL和当前特权级CPL不相同的例子

Content #

在绝大多数时候,请求者都是当前程序自己,因此,CPL=RPL。要判断请求者是谁,最简单的方法就是看谁提供了选择子。

以下是两个典型的例子: jmp dword 0x0010:flush 在这里,提供选择子0x0010 的是当前程序自己。再比如: mov eax, 0x0008 mov ds, eax 这同样是当前程序自己拿着段选择子0x0008 来“请求”代入段寄存器DS,以便在随后的指令中访问该段中的数据。

但是,在一些并不多见的情况下,RPL 和CPL 并不相同。如下图所示,特权级为 3 的应用程序希望从硬盘读一个扇区,并传送到自己的数据段,因此,数据段描述符的DPL 同样会是3。 请求特权级RPL 和当前特权级CPL 不相同的例子

由于I/O 特权级的限制,应用程序无法自己访问硬盘。好在位于0 特权级的操作系统提供了相应的例程,但必须通过调用门才能使用,因为特权级间的控制转移必须通过门。假设,通过调用门使用操作系统例程时,必须传入3 个参数,分别是CX 寄存器中的数据段选择子、EBX 寄存器中的段内偏移,以及EAX 中的逻辑扇区号。

高特权级别的程序可以访问低特权级别的数据段,这是没有问题的。因此,操作系统例程会用传入的数据段选择子代入段寄存器,以便代替应用程序访问那个段: mov ds, cx 在执行这条指令时,CX 寄存器中的段选择子,其RPL 字段的值是3,当前特权级 CPL 已经变成0,因为通过调用门实施控制转移可以改变当前特权级。显然,请求者并非当前程序,而是特权级为3 的应用程序,RPL 和CPL 并不相同。

From #

保护模式的三种权限类型 CPL的值存放在CS寄存器Selector域的RPL。