x386保护模式下的特权级互相跳转小结

特权级别互相跳转:

从内-->外  -------使用ret命令/或者retf命令实现长返回。(短返回和长返回是不一样的,主要是当时入栈时候cs要不要入栈),其实这里用的是带特权级变化的长返回进行特权级别跳转的。

从外-->内--------使用门,但是因为在特别级别之间互相调用的时候,涉及到堆栈的切换,所以要使用一个tss(task-state-segment)

写代码时候大致的框架:

  1. 先说利用call SelectorGate从PL3代码跳入PL0的代码需要注意的问题
    • 在利用retf进行PL3后,要注意除了code_seg需要设置为dpl3,位pl3所设立的stack3也要设置为dpl3.
    • 使用调用门时候,一个是调用门的DPL的设置,调用门选择子的RPL的设置。因为访问调用门相当于访问一个数据段,当前的cpl是3,所以调用门的g_dpl=3,调用才能成功;选择子的rpl的话,设为0-3多可以。(解释:因为cpu只允许高级别访问低级别或者是同级别访问,所以当前级别是cpl和rpl中的级别低的那一个,故dpl只有>=他们中的级别低的那个的数字,才能够实现访问,这里访问gate相当于访问数据段也是这个道理。)
    • 然后是TSS用于不同堆栈中的转换。在系统中生成一个TSS段用于盛放Tss,然后在保护模式中即将进入PL3的时候将Tss利用ltr ax,指令将其加载,好用于调用门。。
  2. 再说利用retf从PL0到PL3的代码的跳转需要注意的问题(高PL代码访问低PL代码就是使用retf来进行的
    • 首先说明RPL和CPL是为了联合控制访问请求是否合法。(CPL是一个动态的概念,它其实是cs中的Selector的RPL,所以不论所正在执行的代码段中的DPL多少,cs段中的RPL才决定了CPL),然后cpu首先会检查压入栈中Selector的RPL。因为RPL决定了caller的特权等级PL,假如这里的RPL=3,(就假装把它理解为调用关系,那么返回就认为这里需要转换到RPL为3的代码段中了)并且是从PL=0的代码中使用retf调用,那么就会进行特权级转换。
    • 堆栈段的PRL也要设置为相应的特权等级不是特别理解,先放一放),反正这里设置为和代码段的PRL相同的3

  3. 在进行特权级转换后,貌似所有的seg register都被清零,而且cpl为3时候,是不能将dpl为0-2的段的Selector赋值给gs(for example),但是反过来,dpl为3的段,可以被cpl为0-2的代码段执行将其Selector赋值给相应的段寄存器的。(即是说高级别的代码段可以使用低级别的段,低级别的确不能使用高级别的段(比如ds段和gs段))。

你可能感兴趣的:(框架)