zoukankan      html  css  js  c++  java
  • 操作系统学习(十五) 、异常与中断处理

    一、中断调用过程

    处理器对异常和中断的处理过程的调用 操作方法与使用CALL指令调用程序过程和任务的方法类似。当响应一个异常或中断时,处理器使用异常或中断的向量作为IDT表的索引。如果索引指向中断门或陷阱门,则处理器使用与CALL指令操作任务门类似的方法进行任务切换,执行异常或中断处理任务。

    异常或中断门引用运行在当前任务上下文中的异常或中断处理过程。门中的段选择符指向GDT或当前LDT中的可执行代码段描述符。门描述符中的偏移字段指向异常或中断处理过程的开始处。

    中断调用过程

    当处理器执行异常或中断处理过程调用时会进行一下操作;

    • 如果处理器过程在搞特权级上执行时就会发生堆栈切换操作。堆栈切换过程如下:

      • 处理器从当前执行任务的TSS段中得到中断或异常处理过程使用的堆栈的段选择符和栈指针。然后处理器会把被中断程序(或任务)的栈选择符和栈指针压入新栈中。
      • 接着处理器会吧EFLAFS、CS和EIP寄存器的当前值也压入新栈中。
      • 如果异常会产生一个错误号,那么该错误号也会被最后压入新栈中。
    • 如果处理过程将在被中断任务同一个特权级上运行,那么:

      • 处理器会把EFLAGS、CS和EIP寄存器的当前值保存在当前堆栈上。
      • 如果异常会产生一个错误号,那么该错误号也会被最后压入新栈中。

    转移到中断处理过程时堆栈使用方法

    为了从中断处理过程中返回,处理过程必须使用IRET指令。IRET指令与RET指令相似,但IRET指令还会把保存的寄存器内容恢复到EFLAFS中。不过只有当CPL是0时才会恢复EFLAFS中的IOPL字段,并且只有当CPL<=IOPL时,IF标志才会被改变。如果当调用中断处理过程时发生了堆栈切换,那么在返回时IRET指令会切换回原来的堆栈。

    二、异常或中高端处理过程的保护

    异常和中断处理过程的特权级保护机制与通过调用门调用普通过程类似。处理器不允许把控制转移到比CPL更低特权级代码段的中断处理过程中,否则将产生一个一般保护性异常。另外中断和异常的保护机制在一下方面与一般调用门过程不同:

    • 因为中断和异常向量没有RPL,因此在隐式调用异常和中断处理过程时不会检查RPl。
    • 只有当一个异常或中断时利用INT n、INT 3 或INTO指令产生时,处理器才会检查中断或陷阱门中的DPL。此时CPL必须小于等于们的DPL。这个限制可以防止运行在特权级3的应用程序使用软件中断访问重要的异常处理过程,例如页错误处理过程,假设这些处理过程已被存放在更高特权级的代码段中。对于硬件产生的中断和处理器检测到的异常,处理器会忽略中断门和陷阱门中的DPL。 因为异常和中断通常不会定期发生。这个技术可以用于只需已访问堆栈上的数据的处理过程。如果处理程序需要数据段中的数据,那么特权级 3 必须能够访问这个数据段,但这样就没保护可言了。
    • 处理过程可以放在具有特权级 0 的非一致代码段中。这种处理过程总是可以执行的,而不管被中断程序或任务的当前特权级CPl。

    三、异常或中断处理过程标志的使用方式

    当通过中断门或陷阱门访问一个异常或中断处理过程,处理器会在把EFLAGS寄存器内容保存到堆栈上之后清除EFLAGS中的TF标志。清除TF标志可以防止指令跟踪影响中断响应。而随后的IRET指令会用堆栈上的内容恢复EFLAGS的原TF标志。

    中断门与陷阱门唯一的区别在于处理器操作EFLAGS寄存器TF标志的方法。当通过中断门访问一个异常或中断处理过程时,处理器会复位TF标志以防止其他中断干扰当前中断处理过程。随后IRET指令则会用保存在堆栈上的内容恢复EFLAGS寄存器的TF标志,而通过陷阱门访问处理过程并不会影响TF标志位。

    四、执行中断处理过程的任务

    当通过IDT表中任务门访问异常或中断处理过程时,就会导致任务切换。从而可以在一个专用任务中执行中断或异常处理过程。IDT表中的任务门引用GDT中的TSS描述符。切换处理过程任务的方法与普通任务切换一样。

    五、中断处理任务

    当通过IDT中任务门来访问异常或中断处理过程时就会导致任务切换。使用单独的任务来处理异常或中断有以下好处:

    • 被中断程序或任务的完整上下文会被自动保存;
    • 在处理异常或中断时,新的 TSS 可以允许处理过程使用新特权级 0 的堆栈。在当前特权级 0 的堆栈已毁坏时如果发生了一个异常或中断,那么在为中断过程提供一个新特权级0的堆栈条件下,通过任务门访问中断处理过程能够防止系统崩溃。
    • 通过使用党的的IDT给中断或异常处理过程独立的地址空间,可以把它与其它任务隔离开来。 使用独立任务处理异常或中断的不足之处是: 在任务切换时必须对大量机器状态进行保存,使得它比使用中断门的响应速度要慢,导致中断延时增加。

    IDT中的任务门会引用 GDT中的TSS 描述符。切换到句柄任务的过程与普通任务切换过程相同。到被中断任务的反向链接会被保存在句柄任务TSS的前一任务链接字段中。如果一个一场会产生一个出错码,该出错码会被复制到新任务堆栈上。

    当异常或中断句柄任务用于操作系统中时,实际上有两种分派调度任务的机制:操作系统软件调度和处理器中断机制的硬件调度。试用软件调度方法时需要考虑到中断开启时采用中断处理任务。
    

    中断处理任务切换

    六、错误码

    当异常条件与一个特定的段相关时,处理器会把一个错误码压入异常处理过程的堆栈上。出错码的格式如下所示:

    错误码格式
    • 位 0 是外部事件 EXT 标志。当置位时,表示执行程序以外的事件造成了异常,例如硬件中断。
    • 位 1 是描述符位置 IDT 标志。当该位置位时,表示错误码的索引部分指向 IDT中的一个门描述符。当该位复位时,表示索引部分指向GDT或LDT中的一个段描述符。
    • 位 2 是 GDT/LDT 表选择标志 TI。当有当位 1 的IDT=0 才有用。当 TI=1时,表示错误码的索引部分指向LDT中的一个描述符。当TI=0时,说明错误码中的索引部分指向GDT表中的一个描述符。

    ​ 段选择索引字段提供了错误码引用的IDT、GDT或者当前LDT中段或门描述符的索引值。在某些情况下错误码是空的(即低16位全为0)。空错误码表示错误不是由于引用某个特地给段造成的,或者是在操作中引用了一个空段描述符。

    ​ 页故障异常的错误码格式与上面不同,只有最低三个比特位有用,他们的名称与页表项中的最后三位相同(U/S、W/R、P)。如下所示:

    页面故障错误码格式
    • 位 0 (P),异常是由于页面不存在或违反访问特权而引发,P=0,表示页不存在;P=1表示违反也级保护权限。
    • 为 1 (W/R),异常时由于内存读或写操作引起。W/R=0,表示由读操作引起;W/R=1,表示由写操作引起。
    • 位 2 (U/S),发生异常时CPU执行的代码级别。U/S=0;表示CPU正在执行超级用户代码;U/S=1,表示CPU正在执行一般用户代码。

    另外,处理器还会把引起页面故障异常所访问的地址存放在CR2中。也出错异常处理程序可以使用这个地址来定位相关的页目录和页表项。注意,错误不会被 IRET指令自动地弹出堆栈,因此中断处理程序在返回之前必须清除堆栈上的错误码。另外,虽然处理产生的某些异常会产生错误码并会自动地保存到处理过程的堆栈中,但是外部硬件中断或者重新执行 INT n 指令产生的异常并不会把错误码压入堆栈中。

  • 相关阅读:
    Spring.Net + Ibatis.Net + Log4Net 结合搭的一个简单多层开发架子
    驳网上常见的半调子程序员白痴言论
    IT对联大汇总
    ClassBase A = New ClassSon() 全面分析
    C# 反射/映射学习
    C++ 一般类型与变量
    HttpModule是如何工作的(转自大牛)
    SQL Server 中的嵌套事务与@@TranCount(转)
    IT人不要一直做技术(转我也不知道转了几圈了)
    kingcms的双重循环
  • 原文地址:https://www.cnblogs.com/ay-a/p/9433595.html
Copyright © 2011-2022 走看看