在一个正常的程序执行过程中,由内部或外部源产生的一个事件使正常的程序执行产生暂时停止的状态时,称之为异常。异常是由内部或外部源产生并引起处理器处理的一个事件,例如一个外部的中断请求。在处理异常之前,当前处理器的状态必须保留,当异常处理完成之后,恢复保留的当前处理器状态,继续执行当前程序。多个异常同时发生时,处理器将会按固定的优先级进行处理。
此处所指异常与8位单片机的中断有相似之处,但异常与中断的概念并不完全等同,例如,外部中断或试图执行未定义指令都会引起异常。中断包含在异常中。
ARM体系结构支持7种类型的异常,异常类型、所处的运行模式、异常向量入口地址、优先级的对应关系见表2-2。
异常出现后,强制从异常类型对应的固定存储器地址开始执行程序,在特定异常向量地址ROM空间存放一条跳转指令,跳转到异常处理程序的入口处。这些固定的地址称为异常向量(Exception Vectors)。
优先级是指当有多个异常发生时,优先级高的先执行。
表2-2 异常类型和异常处理模式表
当处理器的复位电平有效时,产生复位异常,ARM处理器立刻停止执行当前指令。复位后,ARM处理器在禁止中断的管理模式下,程序跳转到复位异常处理程序处执行(从地址0x00000000或0xFFFF0000开始执行指令)。
当ARM处理器或协处理器遇到不能处理的指令时,产生未定义指令异常。当ARM处理器执行协处理器指令时,必须等待任一外部协处理器应答后,才能真正执行这条指令。
若协处理器没有响应,就会出现未定义指令异常。
若试图执行未定义的指令,也会出现未定义指令异常。
未定义指令异常可用于在没有物理协处理器(硬件)的系统上,对协处理器进行软件仿真,或在软件仿真时进行指令扩展。
软件中断异常由执行SWI(SoftWare Interrupt)指令产生,可使用该异常机制实现系统功能调用,用于用户模式下的程序调用特权操作指令,以请求特定的管理(操作系统)函数。
若处理器预取指令的地址不存在,或该地址不允许当前指令访问,存储器会向处理器发出存储器中止(Abort)信号,但当预取的指令被执行时,才会产生指令预取中止异常。
若处理器数据访问指令的地址不存在,或该地址不允许当前指令访问时,产生数据访问中止异常。存储器系统发出存储器中止信号。响应数据访问(加载或存储)激活中止,标记数据为无效。
当处理器的外部中断请求引脚nIRQ有效,且CPSR中的I位为有效电平0时,IRQ才会产生异常。系统的外设可通过该异常请求中断服务。IRQ异常的优先级比FIQ异常的低。当进入FIQ处理时,会屏蔽掉IRQ异常。
注意 :CPSR中的I位,只有在特权模式下才能使用软件设置。
当处理器的快速中断请求引脚nFIQ有效,且CPSR中的F位为有效电平0时,FIQ才会出现异常。FIQ支持数据传送和通道处理,并有足够的私有寄存器,处理速度将会大大提高。 注意事项 同上。
当一个异常发生后,ARM微处理器执行时有以下几步操作。
1)系统根据异常类型调整当前的PC指针值后,存入链接寄存器(R14),以便程序在处理异常返回时能从正确的位置重新开始执行。
2)系统硬件自动将当前程序状态寄存器(CPSR)的条件状态位、控制位、运行模式字复制到相应的SPSR中保存,以便异常返回时使用。
3)根据异常类型,系统硬件强制设置当前程序状态寄存器(CPSR)的I、F、T位及运行模式M[4:0]位,禁止普通中断和快速中断。
前面已讲述,ARM的PC指针是指向当前指令的下两条指令地址,即PC+8。由于指令的执行是按流水线进行的,每种异常模式下指令最终执行完了哪一条是与异常类型有关的,所以送入到RL中的内容是不同的。还有返回时也可对RL中的内容进行调整,实现指令的无缝响应与返回。表2-3是进入异常模式前和返回时RL值的调整以及使用的ARM指令。若异常是从Thumb状态进入,则在RL寄存器中保存的是当前PC值的偏移量。
表2-3 RL值的变化与使用的ARM指令
①在此PC应是预取中止的BL指令/SWI/未定义指令的地址。
②在此PC是从IRQ/FIQ取得不能执行的指令的地址。
③在此PC是产生访问数据中止时加载或存储指令的地址。
④强制PC指针指向相关的异常向量地址处,取出下一条指令执行,跳转到相应的异常处理程序。
如果异常发生时,处理器处于Thumb状态,则当异常向量地址加载到PC时,处理器自动切换到ARM状态。
异常处理完毕之后,ARM微处理器会执行以下几步操作从异常返回。
1)在执行上述异常发生后第二步中的指令(如SUBS PC,R14_fiq,#4)时,硬件自动将SPSR内容送回CPSR中,恢复原来的运行模式值。或者说,恢复CPSR的内容和RL值送PC使用一条指令就可完成。
2)使用指令将连接寄存器(LR)的值减去相应的偏移量后送到PC中,每种异常减去的具体偏移量值见表2-3。
3)若在进入异常处理时设置了普通中断禁止位、快速中断禁止位,要在此清除。但有新的异常发生时,处理器可以进行新的异常处理。
可以认为应用程序总是从复位异常处理程序开始执行,因此复位异常处理程序不需要返回。
在应用程序的设计中,异常处理采用的方式是在异常向量入口表中的特定位置放置一条跳转指令,跳转到异常处理程序。
当ARM处理器发生异常时,程序计数器PC会被强制设置为对应的异常向量,从而跳转到异常入口处理程序,当异常处理完成以后,返回到主程序继续执行。