假设我们想由代码段A转移到代码段B,运用一个调用门G,调用门G中的目标选择子指向代码B的段。这里有几个要素:CPL、RPL、代码B得DPL(DPL_B)、调用门G的DPL(DPL_G)。A访问调用门G是,要求CPL和RPL都小于等于DPL_G。即CPL和RPL需要在更高的特权级上。
除了上面一步符合要求之外,系统还将比较CPL和DPL_B。如果一致代码段的话,要求DPL_B<=CPL;如果非一致代码段的话,call指令和jmp指令有所不同。call指令要求DPL_B<=CPL;在用jmp指令时,只能是DPL_B=CPL.
综上所述,调用门特权规则如下图:
通过调用门call指令,可以实现从低特权级到高特权级的转移,无论目标代码段是一致的还是非一致的。
在有特权级转移时,堆栈也会随之变化,见下图
每个任务最多可能在4个特权级间转移,所以每个任务实际需要4个堆栈。可是我们只有一个ss和esp,在发生堆栈切换时,从哪里获得其余堆栈ss和esp呢?从TSS(Task-State Stack)。32位TSS如下图所示:
TSS包