532628838
圣骑士
圣骑士
  • 注册日期2011-06-10
  • 发帖数98
  • QQ
  • 火币517枚
  • 粉丝77
  • 关注39
阅读:2476回复:0

通过调用门的转移

楼主#
更多 发布于:2011-08-01 16:48
 当段间转移指令JMP和段间调用指令CALL所含指针的选择子指示调用门描述符时,就可以实现通过调用门的转移。但只有CALL指令能变换到内层的特权级,JMP指令只能转移到同级的代码。  
    调用门描述符转移的入口点包含目标地址的段及偏移量的48位全指针。在执行通过任务门的段间转移指令JMP或段间调用指令CALL时,指令所含指针内的选择子用于确定调用门,而偏移被丢弃;把调用门内的48位全指针作为目标地址指针进行转移。  
    处理器采用与访问数据段相同的特权级规则控制对门描述符的访问。调用门描述符的DPL规定了访问该门的最外层特权级,在取出调用门内的48位全指针,把它作为目标地址指针向目标代码段转移之前,要进行特权级检查。只有在相同级或者更内层特权级的程序才可访问调用门,即CPL<=调用门的DPL。同时,还要求指示门的选择子的RPL必须满足RPL<=调用门的DPL的条件。检测通过后,才开始向目标代码段转移的步骤。其中还要检测目标描述符是否为代码段描述符,调用门内的选择子指示的描述符必须是代码段描述符。此外,在装载代码段描述符高速缓冲寄存器之前调整代码段选择子的RPL=0,也即调用门中代码段选择子的RPL被忽略。  
    在装载CS高速缓冲寄存器时,还要对目标代码段描述符进行保护检测。检测过程中的DPL不再是调用门的DPL,而是调用门内选择子所指示的目标代码段描述符的DPL。段间调用指令CALL和段间转移指令JMP所做的检测不一样。  
    对于使用调用门的段间转移指令JMP,检测条件与段间直接转移相同。由于已置RPL=0,所以可认为 RPL<=DPL的条件总能满足。所以,对于普通的非一致代码段,当CPL=DPL时,发生无特权级变换的转移;对于一致代码段,在满足CPL>=DPL时也发生无特权级变换的转移;其它情形就引起异常。  
    对于使用调用门的段间调用指令CALL,情形就不同了。由于已置RPL=0,所以可认为RPL<=DPL的条件总能满足。对于一致代码段,在满足CPL>=DPL时发生无特权级变换的转移。对于非一致代码段,当CPL=DPL时,仍发生无特权级变换的转移;当CPL>DPL时,就发生向内层特权级变换的转移,将调用门中的选择子和偏移装入CS和指令指针EIP中,并使CPL保持等于DPL,同时切换到内层堆栈。  
    综上所述,使用段间调用指令CALL,通过调用门可以实现从外层程序调用进入内层程序(JMP指令只能实现无特权级变换的转移);通过调用门也可实现无特权级变换的转移。需要注意的是,JMP指令和CALL指令都不能实现向外层特权级的转移否则会引起异常。  
当然,CALL指令在最后把目标代码段的指针装入CS和EIP之前,要把原CS和EIP,即返回地址保存到堆栈。如无特权级变换,堆栈保持不变,返回地址就保存在原堆栈中;否则,返回地址保存在内层堆栈中。

喜欢0 评分0
游客

返回顶部