异常架构

和中断相比,异常最大的不同在于它是在程序的执行过程中同步发生的。例如下面这个程序:

void main(){

int a = 10;

a = a/0;

}

程序运行到a = a/0;一句时必然引起一个除0异常,但不能预料该程序在执行时是否会发生中断。异常根据产生的原因和严重程度可以分为如下三类。

(1)错误 :由某种错误情况引起,一般可以被错误处理程序纠正。错误发生时,处理器将控制权转移给对应的处理程序。例如常见的缺页错误就属于此类。

(2)陷阱:指在执行了一条特殊指令后引起的异常。例如linux中用于实现系统调用的INT 80 指令就属于此类。

(3)终止:指严重的不可恢复的错误,将导致程序终止的异常。例如MCA。

和中断门一样,陷阱门存放在IDT表中。异常发生后,CPU用该异常的vector号索引其对应的陷阱门。x86架构将vector 0~19预留给各个异常。

操作系统对中断/异常的处理流程

虽然各个操作系统对于中断/异常处理实现不同,但基本流程遵循如下的顺序。

一个中断/异常发生,打断当前正在执行的任务。

(1)CPU通过vector 索引IDT表得到对于的"门",并获得其处理函数的入口地址。

(2)程序跳转到处理函数执行,由于处理函数存放在CPL= 0 的代码段,程序可能会发生权限提升。处理函数通常执行下列几个步骤。:保存被打断的上下文,并开始执行处理函数。如果是中断,处理完后需要些EOI寄存器应答,异常不需要。恢复打断的任务上下文准备返回。

(3)从中断/异常的处理函数返回,恢复被打断的任务,使其继续执行。

操作系统可能对上述执行路径进行封装,也会引入诸如软中断之类的机制,但总顺序如上所述,不会有太大的不同。

中断/异常属于处理器架构中比较复杂的部分,上面的内容仍然有很多细节没有涉及到。目前,新的中断方式——MSI已经被广泛应用。

猜你喜欢

转载自blog.csdn.net/d1306937299/article/details/88257713