如果异常中断处理程序中使用它自己的物理寄存器之外的其他寄存器,异常中断处理程序必须保存和恢复这些寄存器。在上表中各物理寄存器名称在ARM汇编中并没有被预定义。用户使用这些寄存器时,必须使用伪操作RN来定义这些名称。如可以通过下面操作定义寄存器名称R13_svc:
常中断处理程序中使用它自己的物理寄存器之外的其他寄存器,异常中断处理程序必须保存和恢复这些寄存器。在上表中各物理寄存器名称在ARM汇编中并没有被预定义。用户使用这些寄存器时,必须使用伪操作RN来定义这些名称。如可以通过下面操作定义寄存器名称R13_svc:
R13_svc RN R13
进入和退出异常中断的过程:
下面介绍处理器对于各种异常中断的响应过程以及从异常中断处理程序中返回的方法。对于不同的异常中断处理程序,返回地址以及使用的指令是不同的。
ARM处理器对异常中断的响应过程如下:
(1).保存处理器当前状态、中断屏蔽位以及各条件标志位。这是通过将当前程序状态寄存器CPSR的内容保存到将要执行的异常中断对应的SPSR寄存器中实现的。各异常中断有自己的物理SPSR寄存器。
(2).设置当前程序状态寄存器CPSR中相应的位。包括设置CPSR中的位,使处理器进入相应的执行模式;设置CPSR中的位,禁止IRQ中断,当进入FIQ模式时,禁止IRQ中断。
(3).将寄存器lr_mode设置成返回地址。
(4).将程序计数器(PC)值,设置成该异常中断的中断向量地址,从而跳转到相应的异常中断处理程序处执行。
上述的处理器对异常中断的响应过程可以用如下的伪代码描述。
R14_ = return link
SPSR_ = CPSR
CPSR[4:0] = excep
tion mode number
/* 当运行于ARM状态时 */
CPSR[5] = 0
/* 当相应FIQ异常中断时,禁止新的FIQ中断 */
if == RESET or FIQ then
CPSR[6] = 1
/* 禁止新的FIQ中断 */
CPSR[7] = 1
PC = exception vector address
1.响应复位异常中断
当处理器的复位引脚有效时,处理器终止当前指令。当处理器的复位引脚变成无效时,处理器开始执行下面的操作。
R14_svc = UNPREDICATBLE value
SPSR_svc = UNPREDICATBLE value
/* 进入特权模式 */
CPSR[4:0] = 0b10011
/* 切换到ARM状态 */
CPSR[5] = 0
/* 禁止FIQ异常中断 */
CPSR[6] = 1
/* 禁止IRQ中断 */
CPSR[7] = 1
if high vectors configured then
PC = 0XFFFF0000
else
PC = 0X00000000
2.响应未定义指令异常中断
处理器响应未定义指令异常中断时的处理过程如下面的伪代码所示。
R14_und = address of next instruction after the undefined instruction
SPSR_und = CPSR
/* 进入未定义指令异常中断 */
CPSR[4:0] = 0b11011
/* 切换到ARM状态 */
CPSR[5] = 0
/* CPSR[6]不变 */
/* 禁止IRQ异常中断 */
CPSR[7] = 1
if high vectors configured then
PC = 0xFFFF0004
else
PC = 0x00000004
3.响应SWI异常中断
处理器响应SWI异常中断的处理过程如下面的伪代码所示。
R14_svc = address of next instruction after the SWI instruction
SPSR_svc = CPSR
/* 进入特权模式 */
CPSR[4:0] = 0b10011
/* 切换到ARM状态 */
CPSR[5] = 0
/* CPSR[6]不变 */
/* 禁止IRQ异常中断 */
CPSR[7] = 1
if high vectors configured then
PC = 0xFFFF0008
else
PC = 0x00000008
4.响应指令预中止异常中断
处理器响应指令预取中止异常中断时的处理过程如下面的伪代码所示。
R14_abt = address of the aborted instruction+4
SPSR_abt = CPSR
/* 进入指令预取中止模式 */
CPSR[4:0] = 0b10111
/* 切换到ARM状态 */
CSPR[5] = 0
/* CPSR[6]不变 */
/* 禁止IRQ异常中断 */
CPSR[7] = 1
if high vectors configured then
PC = 0xFFFF000C
else
PC = 0x0000000C
5.响应数据访问中止异常中断
处理器响应数据访问中止异常中断时的处理过程如下面的伪代码所示。
R14_abt = address of the aborted instruction+8
SPSR_abt = CPSR
/* 进入数据访问中止 */
CPSR[4:0] = 0b10111
/* 切换到ARM状态 */
CSPR[5] = 0
/* CPSR[6]不变 */
/* 禁止IRQ异常中断 */
CPSR[7] = 1
if high vectors configured then
PC = 0xFFFF0010
else
PC = 0x00000010
6.响应IRQ异常中断
处理器响应IRQ异常中断时的处理器过程如下面的伪代码所示。
R14_irq = address of next instruction to be executed + 4
SPSR_irq = CPSR
/* 进入IRQ异常中断模式 */
CPSR[4:0] = 0b10010
/* 切换到ARM状态 */
CSPR[5] = 0
/* CPSR[6]不变 */
/* 禁止IRQ异常中断 */
CPSR[7] = 1
if high vectors configured then
PC = 0xFFFF0018
else
PC = 0x00000018
7.响应FIQ异常中断
处理器响应FIQ异常中断时的处理器过程如下面的伪代码所示。
R14_fiq = address of next instruction to be executed + 4
SPSR_fiq = CPSR
/* 进入FIQ异常中断模式 */
CPSR[4:0] = 0b10001
/* 切换到ARM状态 */
CSPR[5] = 0
/* 禁止FIQ中断 */
CPSR[6] = 1
/* 禁止IRQ异常中断 */
CPSR[7] = 1
if high vectors configured then
PC = 0xFFFF001C
else
PC = 0x0000001C
从异常中断处理程序中返回包括下面两个基本操作:
恢复被中断的程序的处理器状态,即将SPSR_mode寄存器内容复制到当前程序状态寄存器CPSR中。
返回到发生异常中断的指令的下一条指令处执行,即将lr_mode寄存器的内容复制到程序计数器PC中。
复位异常中断处理程序不需要返回。整个应用系统是从复位异常中断处理程序开始执行的,因为它不需要返回。
实际上,当异常中断发生时,程序计数器PC所指的位置对于各种不同的异常中断是不同的。同样,返回地址对于各种不同的异常中断也是不同的。
下面详细介绍各种异常中断处理程序的返回方法。
1.SWI和未定义指令异常中断处理程序的返回
SWI和未定义指令异常中断是由当前执行的指令自身产生的,当SWI和未定义指令异常中断发生时,程序计数器PC的值还未更新,它指向当前指令后面第2条指令。当SWI和未定义指令异常中断发生时,处理器将值(PC-4)保存到异常模式下的寄存器lr_mode中。这时(PC-4)即指向当前指令的下一条指令。因此返回操作可以通过下面的指令来实现:
MOV PC LR
该指令寄存器LR中的值复制到程序计数器PC中,实现程序返回,同时将SPSR_mode寄存器内容复制到当前程序状态寄存器CPSR中。
当异常中断处理程序使用了数据栈时,可以通过下面的指令在进入异常中断处理程序时保存被中断程序的执行现场,在退出异常中断处理程序时恢复被中断程序的执行现场。异常中断处理程序中使用的数据栈由用户提供。
stmfd sp!, {reglist,lr}
....
ldmfd sp!, {reglist,pc}^
在上述指令中,reglist是异常中断处理程序中使用的寄存器列表。标识符^指示将SPSR_mode寄存器内容复制到当前程序状态寄存器CPSR中。该指令只能在特权模式下使用。
2.IRQ和FIQ异常中断处理程序的返回
通常处理器执行完当前指令后,查询IRQ中断引脚和FIQ中断引脚,并且查看系统是否允许FIQ中断及IRQ中断。如果有中断引脚有效,并且系统允许该中断发生,处理器将产生IRQ异常中断或FIQ异常中断。当IRQ和FIQ异常中断产生时,程序计数器PC的值已经更新,它指向当前指令后面第3条指令。当IRQ和FIQ异常中断发生时,处理器将值(PC-4)保存到异常模式下的寄存器lr_mode中。这时(PC-4)即指向当前指令后的第2条指令。因此返回操作可以通过下面的指令来实现:
SUB PC, LR, #4
该指令将寄存器LR中的值减4后,复制到程序计数器PC中,实现程序返回,同时将SPSR_mode寄存器内容复制到当前程序状态寄存器CPSR中。
当异常中断发处理程序使用了数据栈时,可以通过下面的指令在进入异常中断处理程序时保存被中断程序的执行现场,在退出异常中断处理程序时恢复被中断程序的执行现场。异常中断处理程序中使用的数据栈由用户提供。
SUB LR, LR, #4
STMFD sp!, {reglist, lr}
...
LDMFD sp!, {reglist, pc}^
上述指令中,reglist是异常中断处理程序中使用的寄存器列表。标识符^指示将SPSR_mode寄存器内容复制到当前程序状态寄存器CPSR中。该指令只能在特权模式下使用。
其它异常中断返回情况请参考《ARM体系结构与编程》一书中的第9章。