中断(Interrupt)机制,即处理器核在顺序执行程序指令流的过程中,突然被别的请求打断而中止执行当前的程序,转而去处理别的事情,待其处理完了别的事情,然后重新回到之前程序中断的点,继续执行之前的程序指令流,其要点如下。
第一种,可能是处理器并不响应新的中断,而是继续执行当前正在处理的中断服务程序,待到彻底完成之后才响应新的中断请求,这种称为处理器“不支持中断嵌套”。
第二种,可能是处理器中止当前的中断服务程序,转而开始响应新的中断,并执行其“中断服务程序”,如此便形成了中断嵌套(即前一个中断还没响应完,又开始响应新的中断),并且嵌套的层次可以有很多层。
注意:
假设新来的中断请求的优先级,比正在处理的中断优先级低(或者相同),则不管处理器是否能支持“中断嵌套”,都不应该响应这个新的中断请求,处理器必须完成当前的中断服务程序之后,才考虑响应新的中断请求(因为新中断请求的优先级并不比当前正在处理的中断优先级高)。
RISC-V架构默认不支持中断嵌套。
异常(Exception)机制,即处理器核在顺序执行程序指令流的过程中,突然遇到了异常的事情而中止执行当前的程序,转而去处理该异常,其要点如下。
• 处理器遇到的“异常的事情”称为异常(Exception)。异常与中断的最大区别在于中断往往是一种外因,而异常是由处理器内部事件或程序执行中的事件引起的,譬如本身硬件故障、程序故障,或者执行特殊的系统服务指令而引起的,简而言之是一种内因。
• 与中断服务程序类似,处理器也会进入异常服务处理程序。
• 与中断类似,可能存在多个异常同时发生的情形,因此异常也有优先级,并且也可能发生多重异常的嵌套。
如上文所述,中断和异常最大的区别是起因内外有别。除此之外,从本质上来讲,中断和异常对于处理器而言基本上是一个概念。中断和异常发生时, 处理器将暂停当前正在执行的程序,转而执行中断和异常处理程序;返回时,处理器恢复执行之前被暂停的程序。
因此中断和异常的划分是一种狭义的划分。从广义上来讲,中断和异常都被认为是一种广义上的异常。处理器广义上的异常,通常只分为同步异常(Synchronous Exception)和异步异常(Asynchronous Exception)。
同步异常,是指由于执行程序指令流或者试图执行程序指令流而造成的异常。这种异常的原因,能够被精确定位于某一条执行的指令。同步异常的另外一个通俗的表象便是,无论程序在同样的环境下执行多少遍,每一次都能精确地重现出来。
譬如,程序流中有一条非法的指令,那么处理器执行到该非法指令便会产生非法指令异常(Illegal Instruction Exception),能被精确地定位于这一条非法指令,并且能够被反复重现。
异步异常,是指那些产生原因不能够被精确定位于某条指令的异常。异步异常的另外一个通俗的表象便是,程序在同样的环境下执行很多遍,每一次发生异常的指令PC 都可能会不一样。
最常见的异步异常是“外部中断”。比如,外部中断的发生,是由外围设备驱动的,一方面外部中断的发生带有偶然性,另一方面中断请求抵达于处理器核之时,处理器的程序指令流执行到具体的哪一条指令更带有偶然性。因此一次中断的到来,可能会巧遇到某一条“正在执行的不幸指令”,而该指令便成了“背锅侠”。在它的指令PC 所在之处,程序便停止执行,并转而响应中断去执行中断服务程序。但是当程序重复执行时,却很难会出现同一条指令反复“背锅”的精确情形。
对于异步异常,根据其响应异常后的处理器状态,又可以分为两种:
(1)精确异步异常(Precise Asynchronous Exception):指响应异常后的处理器状态,能够精确反映为某一条指令的边界,即某一条指令执行完之后的处理器状态。
(2)非精确异步异常(Imprecise Asynchronous Exception):指响应异常后的处理器状态,无法精确反映为某一条指令的边界,即可能是某一条指令执行了一半然后被打断的结果,或者是其他模糊的状态。
常见的典型同步异常和异步异常,如下表所示,此表可以帮助读者更加理解同步异常和异步异常的区别。
参考文档: