3.7.1 什么是异常和中断
处理器执行一条指令,这条指令能不能运行成功,要看它的运行条件能不能满足。比如,一条访问存储器的指令,如果访问存储器的地址不存在或者不允许访问,那么这条指令就不能执行成功,先不管失败后怎么处理,反正最好的方式是执行另一段程序,但是当前这段程序肯定要被打断的。另一种情况,处理器正在运行程序,这时某个设备急切地需要处理器的关注,最好的方式也是去执行一段关注这个设备的代码,这也是要打断当前正在运行的程序。打断当前程序执行流转而执行其他程序的方式示意图,如图3-8所示。我们对打断的方式进行了分类,如下:
图3-8 中断、异常的执行过程
1)异常:同步的,是由于程序指令本身的问题,或者不能满足指令的执行条件而程序不能继续往下执行时,又或者执行到专门产生异常的指令时,所表现的一种状态。
2)中断:异步的,是由外部设备发起的,处理器不知道什么时刻什么设备需要关注,它只是每执行完一条指令就去检测它的中断信号引脚,看看有无中断信号。如果没有就继续执行指令。
下面分别看看ARM920T是怎么处理这两种情况的。
1.异常
异常,是因为不能满足程序指令的执行条件,或者违反了指令的执行规则,又或者执行了用于产生异常的指令。异常又是同步的,如果程序中有一条会产生异常的指令,你不修正这个程序,那么不管重新运行这个程序多少遍,都会在相同的程序地址上发生异常。先来看看ARM920T处理中规定了哪些异常。
□ARM920T复位异常。
□未定义指令异常。
□预取指令终止异常。
□数据访问终止异常。
□SWI指令异常。
1)复位异常:其实这个也不能完全划归为异常,只是它的行为和异常一样,它是当处理器的复位引脚收到一个信号时,就会马上中断当前执行的程序。处理器硬件执行如下操作并且这些操作不可中断:
①把处理器设为ARM状态和系统管理模式。
②系统管理模式下R14、SPSR寄存器中是不确定的数据,因为复位。
③禁止快速中断和外部中断。
④强制R15寄存器中的值为复位向量,这个复位向量后面会有介绍。
2)未定义指令异常:当ARM处理器执行协处理器指令时,它必须等待任何一个外部协处理器应答后,才能真正执行这条指令,此时若没有协处理器回应,则产生未定义指令异常。如果尝试执行未定义的指令,也会产生未定义指令异常。处理器硬件执行如下操作并且这些操作不可中断:
①处理器被切换到ARM状态和未定义指令终止模式。
②把未定义指令后的下一条指令的地址放进处理器未定义指令终止模式下的R14寄存器中,把CPSR寄存器的内容放进未定义指令终止模式下的SPSR寄存器中。
③禁止外部中断。
④强制R15寄存器中的值为未定义指令终止异常向量。
3)预取指令终止异常:当指令预取访问存储器失败时,存储器系统向处理器发出存储器中止信号,预取的指令被记为无效,但只有当处理器试图执行该无效指令时,指令预取终止异常才会发生,如果该指令未被执行,如在指令流水线中发生了跳转,则预取指令中止异常不会发生。如果预取终止异常发生,处理器硬件执行如下操作并且这些操作不可中断:
①处理器被切换到ARM状态和数据访问终止模式。
②把预取终止指令后的下一条指令的地址放进处理器数据访问终止模式下的R14寄存器中,把CPSR寄存器的内容放进数据访问终止模式下的SPSR寄存器中。
③禁止外部中断。
④强制R15寄存器中的值为预取指令终止异常向量。
4)数据访问终止异常:如果数据访问指令的目标地址不存在,或者该地址不允许当前指令访问,处理器会产生此异常。处理器硬件执行如下操作并且这些操作不可中断:
①处理器被切换到ARM状态和数据访问终止模式。
②把终止指令后的第二条指令的地址(这是因为指令流水线),放进处理器数据访问终止模式下的R14寄存器中,把CPSR寄存器的内容放进数据访问终止模式下的SPSR寄存器中。
③禁止外部中断。
④强制R15寄存器中的值为数据访问终止异常向量。
5)SWI指令异常:其实它也不能称为异常,只是它的行为和异常一样,使用指令SWI会使处理器模式切换到系统管理模式运行特定的程序。这条指令通常用于作为系统调用的陷入指令。处理器硬件执行如下操作并且这些操作不可中断。
①把处理器设为ARM状态和系统管理模式。
②把SWI指令后的下一条指令的地址放进系统管理模式下的R14寄存器中、把CPSR寄存器的内容放进系统管理模式下的SPSR寄存器中。
③禁止外部中断。
④强制R15寄存器中的值为SWI向量。
2.中断
处理器的速度比外部设备的速度快得多,然而外部设备又需要处理器的关注,于是这样高速的处理器就不得不等待低速的外部设备,这对高速的处理器无疑是巨大的浪费。人们就想了个方法,设备在需要处理器关注时就给处理器发送个信号,于是这样处理在没收到信号之前就可以高速地做它自己的事情。处理器在每运行完一条指令后,首先看有没有这个信号,如果有这个信号,还要看系统允不允许响应这个信号,如果系统允许响应这个信号,那么处理器就开始处理这个信号。由于处理器不知道什么设备会在什么时刻发送这个信号,所以这种信号是异步的。这种信号就是中断信号,由于各种外部设备有轻重缓急,有的设备需要快速响应,有的则不那么急。因此ARM920T处理器定义两种中断类型:外部设备中断和快速外部设备中断。
1)外部设备中断:通过处理器上的IRQ输入引脚,由外部设备产生IRQ中断,若此时CPSR的I位为0,处理器会产生外部设备中断请求IRQ中断。此时,处理器硬件执行如下操作并且这些操作不可中断。
①把处理器设为ARM状态和外部中断模式。
②把中断后将要执行的第二条指令的地址(这也是因为指令流水线的原因),放进处理器外部中断模式下的R14寄存器中,把CPSR寄存器的内容放进外部中断模式下的SPSR寄存器中。
③禁止外部设备中断。
④强制R15寄存器中的值为外部中断向量。
2)快速外部设备中断:通过处理器上的FIQ输入引脚,由外部设备产生FIQ中断,若此时CPSR的F位为0,处理器会产生快速设备中断请求FIQ中断。此时,处理器硬件执行如下操作并且这些操作不可中断。
□把处理器设为ARM状态和快速中断模式。
□把中断后将要执行的第二条指令的地址(这也是因为指令流水线的原因),放进处理器快速中断模式下的R14寄存器中,把CPSR寄存器的内容放进快速中断模式下的SPSR寄存器中。
□禁止快速设备中断和外部设备中断。
□强制R15寄存器中的值为快速中断向量。