上述的处理器对异常中断的响应过程可以用如下的伪代码描述。
R14_ = return link SPSR_ = CPSR CPSR[4:0] = exception 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中。该指令只能在特权模式下使用。
|