WEB开发网
开发学院软件开发汇编语言 汇编教程:控制转移(3) 阅读

汇编教程:控制转移(3)

 2009-10-12 09:36:41 来源:WEB开发网   
核心提示:3.关于实例四的说明程序中部分片段的背景和实现方法在前面的实例中做过介绍,下面主要就如何实现任务内特权级变换做些说明:(1)通过段间返回指令实现特权级变换实例在两处使用段间返回指令实现任务内的特权级变换,汇编教程:控制转移(3),一处是在0级的过渡代码段中用段间RET指令从特权级0变换到特权级3的演示代码段,该处RET

3.关于实例四的说明

程序中部分片段的背景和实现方法在前面的实例中做过介绍,下面主要就如何实现任务内特权级变换做些说明:

(1)通过段间返回指令实现特权级变换

实例在两处使用段间返回指令实现任务内的特权级变换。一处是在0级的过渡代码段中用段间RET指令从特权级0变换到特权级3的演示代码段。该处RET指令并不对应CALL指令。实例从实模式切换到保护模式后CPL=0。为了演示如何通过调用门调用内层程序,要设法使CPL>0。为此,实例先建立一个已发生的从外层到内层变换的环境,即按上图所示在当前堆栈(0级堆栈)中放入外层堆栈的指针和外层演示程序的入口指针,形成一个如下图所示的0级堆栈,无需传递参数。然后,执行段间返回指令RET,从堆栈中弹出3级演示代码段的选择子,RPL=3,而当时CPL=0,所以导致向外层变换特权级,从0级的过渡代码段变换到3级的演示代码段,同时切换到3级堆栈。

另一处是从1级的显示子程序EchoSub返回到3级的演示程序段。该处的RET指令与演示程序中使用的通过调用门的段间调用指令CALL相对应,执行段间返回指令RET时的1级堆栈也如上图所示,其中的返回地址和外层栈指针由CALL指令压入。

(2)通过调用门实现特权级变换

实例在两处使用了段间调用指令,通过调用门实现特权级的变换。一处是3级演示代码通过调用门ToEchoGate调用1级的显示子程序。调用门ToEchoGate自身的DPL=3,只有这样,3级的演示代码才能够使用该调用门。由于调用门内的选择子Echo_Sel3所指示的显示子程序代码段描述符DPL=1,而当时CPL=3,所以引起从外层特权级向内层特权级的变换,使CPL=1。同时形成如上图所示的1级堆栈。虽然调用门内的选择子Echo_Sel3的RPL=3,大于目标代码段的DPL,但没有关系,因为在通过调用门转移时,门内指示目标代码段的选择子RPL总被作0对待。

另一处是3级演示代码还通过调用门ToT32GateB调用了0级的过渡代码。该处使用的调用门描述符DPL也等于3。由于调用门内的选择子T32Code_Sel所指示的过渡代码段描述符的DPL=0,而当时CPL=3,所以引起从3特权级向0特权级的变换,使CPL=0。同时形成如上图所示的0级堆栈。但该处的调用实际上是 “有去无回”的,调用的目的是转移到0级的过渡代码,准备返回实模式。由于从3级的演示代码到0级的过渡代码要发生特权级变换,所以不能使用转移指令JMP,必须使用调用指令CALL。

(3)通过调用门实现无特权级变换

在临时代码段中,使用调用门ToT32GateA转移到过渡代码段。尽管调用门内的选择子T32Code_Sel所指示的过渡代码段描述符的DPL=0,但当时CPL=0,所以不发生特权级变换。正是这个原因,才可以使用段间转移指令JMP。

(4)子程序EchoSub的实现

子程序EchoSub的功能是显示调用程序执行时的特权级。调用程序的执行特权级在代码段寄存器CS内选择子的RPL字段,在调用EchoSub时,CS寄存器的内容被压入堆栈。子程序从堆栈取得调用程序的代码段选择子,再从中分离出RPL就可得调用程序的执行特权级。

(5)装载任务状态段寄存器TR

在任务内发生特权级变换时堆栈也随着自动切换,外层堆栈指针保存在内层堆栈中,而内层堆栈指针存放在当前任务的TSS中。所以,在从外层向内层变换时,要访问TSS(从内层向外层转移时不需要访问TSS,而只需内层栈中保存的栈指针)。实例在进入保护模式下的临时代码段后,通过如下两条指令装载任务状态段寄存器TR,使其指向已预置好的任务的TSS:

mov   ax,DemoTSS_Sel   ltr   ax

LTR指令是专门用于装载任务状态段寄存器TR的指令。该指令的操作数是对应TSS段描述符的选择子。LTR指令从GDT中取出相应的TSS段描述符,把TSS段描述符的基地址和界限等信息装入TR的高速缓冲寄存器中。

1 2 3 4  下一页

Tags:汇编 教程 控制

编辑录入:爽爽 [复制链接] [打 印]
赞助商链接