中断与异常机制

中断与异常的详细介绍

Posted by 邹盛富 on June 2, 2018

软件与硬件的工作

中断、异常机制实际上是现代计算机系统中的核心机制之一,主要工作是由硬件和软件相互配合来完成的,通过软硬件的配合使计算机的能力得到充分地发挥。在这个机制工作过程中,硬件实际上是捕获中断源发出的各种中断、异常的请求,同时把控制权转交给特定的处理程序来完成这个过程,称这个过程为中断异常的响应。软件的工作就是识别中断、异常类型完成对应的处理,实际上就是处理程序,称这个程序为中断、异常处理程序。 所以硬件完成的是响应,软件完成的是处理。

中断响应就是发现中断、接收中断的一个过程,这个过程是由中断的硬件部件完成,在处理器控制部件当中设置了一个中断寄存器,保存了发来的各种各样的中断信号。如下图所示当CPU取下一条指令,然后执行这条指令,在执行完这条指令之后(也就是在每条指令周期的最后),扫描中断寄存器,查看是否有中断发生即是否有中断信号,如果有中断信号,就要对中断进行相应的处理,会把它的内容按规定编码送到程序状态字寄存器当中的相应的位,称该编码为中断码。然后查中断向量表,把中断处理程序调用出来,然后下一个指令周期执行相应的中断处理指令。

中断向量表

硬件会根据中断寄存器中的中断码查询中断向量表,中断向量表实际上是个非常重要的软硬件结合的一个数据结构。中断向量表中每一行实际上是一个中断向量,中断向量表是由若干行中断向量组成。每一个中断向量其实就是一个内存单元,它是存放了中断处理程序的入口地址以及中断程序在运行的时候所需要的一个处理机的状态字。那么,操作系统需要把填写事先写好的中断处理程序和这些中断处理程序的起始地址(入口地址),填在中断向量表里。那么当中断发生时,那么执行流程就会按照中断码/异常类型的不同,通过中断向量表把控制权转移给对应的中断处理程序。Linux中的中断向量表如下:

中断响应过程

流程图如下:

  • 设备发来了中断信号
  • 中断硬件会去保存现场(保存到系统堆栈),主要的是PSW和PC
  • 中断硬件根据中断码来去查中断向量表,通过查中断向量表得到对应的中断处理程序
  • 把中断处理程序的入口地址等相关信息,推送到相应的寄存器,那么下一个指令周期开始,执行中断处理程序

中断处理程序

中断处理程序的主要工作:

  • 保存相关寄存器信息
  • 分析相关异常的具体原因
  • 执行对应处理程序
  • 恢复现场,返回被事件打断的程序

X86中断与异常机制

在X86处理器当中,中断是指的由硬件信号引发的,那么通常分成了可屏蔽中断不可屏蔽中断。异常是由正在执行指令而引发的,例如除零、算数溢出等等,X86处理器中大约发布了大概20多种不同的异常,不同的处理器发布的异常个数是不一样的。 而且对于某些异常呢,CPU会在处理异常处理程序之前产生一个硬件出错码,把这个硬件出错码压入到内核栈里头。另外一种就是特殊的一种异常,叫系统调用,它是用户态到内核态的一个唯一入口。

在X86处理器当中有实模式和保护模式之分。在实模式下,中断向量表就叫中断向量表,存放了中断服务程序的入口地址。入口地址等于这个段寄存器的段地址左移4位,然后加上偏移地址就得到了这个中断处理程序的入口地址。 在实模式下没有CPU状态的这种转换,所以中断的处理与一般过程的这个调用呢是很相似的。但是在保护模式下,中断向量表被叫中断描述符表,那么中断描述符表当中每一个中断向量叫门描述符,用一个门描述符来表示我们前面说的中断向量,一般情况下有四种门描述符表,分别如下:

  • 任务门
  • 中断门:中断门是在门描述符当中给出了段选择符,以及中断、异常程序的一个段内的偏移量,中断门通过之后,系统自动禁止中断,不再接受新的中断
  • 陷阱门:整体的处理是和中断门相似的,只是通过了陷阱门之后不会自动禁止中断,所以还可以接收新的中断
  • 调用门

X86中断/异常硬件处理过程如下:

  • 确定与中断和异常相关的中断向量i
  • 查中断描述符表,中断描述符表的起始位置呢可以通过一个IDTR寄存器得到,得到了这个中断描述符是在这个表当中的第i项
  • 再去查GDT表,首先从GDTR寄存器得到了GDT的地址,结合中断描述符表当中的中断描述符当中的段选择符,在GDT表当中呢查到对应的段描述符,从这个段描述符当中得到了中断或者异常处理程序的段的基地址
  • 如果是有特权级的改变,则要进行堆栈的切换
  • 硬件压栈,保存上下文,如果异常产生出错码,同时保存出错码
  • 如果是中断门,清IF位,禁止中断;如果是陷阱门则不需要
  • 通过中断描述符当中的段内偏移量,还有段描述符当中的基地址,就可以算出来中断、异常处理程序的一个入口地址,然后呢去执行它的第一条指令

总结