STR r0,(r4,#4)
ADD sp,sp,#4
LDMFD sp!,(r0-r4,r12,lr)
SUBS pc,lr,#4
ENDP
BXPORT IRQHandler
//第2 个程序没有使用关键词_irq 声明
_irq void IRQHandler (void)
{
Volatile unsigned int *base=(unsigned int *) 0x80000;
If(*base 1)
{
//调用相应的 C 语言处理程序
C_int_handler();
}
//清除中断标志
*(base+1)=0;
}
;第1 个C 语言程序对应的汇编程序
IRQHandler PROC
STMFD sp!(r4,lr)
MOV r4,#0x8000000
LDR r0,(r4,#0)
CMP r0,#1
SLEQ C_int_handler
MOV r0,#0
STR r0,(r4,#4)
LDMFD sp!(r4,pc)
ENDP
② 可重入的 IRQ/FIQ 异常中断处理程序
如果在可重入的 IRQ/FIQ 异常中断处理程序中调用了子程序,子程序的返回地址被保存
到寄存器的 LR_irq 中,这时如果发生了 IRQ/FIQ异常中断,这个 LR_irq寄存器的值将
被破坏,那么被调用的子程序将不能正确的返回。因此,对于可重入的 IRQ/FIQ异常中
断处理程序一些需要特别的操作。下面列出了在可重入的 IRQ/FIQ 异常中断处理程序中
需要的操作。这时,第1 级中断处理程序不能使用 C 语言,因为其中一些操作不能通过
C 语言实现:
● 将返回地址保存到 IRQ的数据栈中。
● 保存工作寄存器和 SPSR_irq。
● 清除中断标志位。
● 将处理器切换到系统模式,重新使能中断(IRQ/FIQ)。
● 保存用户模式的 LR 寄存器和被调用者的不保存的寄存器。
● 调用 C 语言的 IRQ/FIQ异常中断处理程序。
● 当 C 语言的 IRQ/FIQ 异常中断程序返回后,恢复用户模式的寄存器,并禁止中断
(IRQ/FIQ)。
● 切换到 IRQ模式,禁止中断。
● 恢复工作组寄存器和寄存器 LR_irq。
● 从 IRQ 异常中断处理程序中返回。
下面程序 6.5 演示了这些操作的过程。
程序6.5 可重入的 IRQ/FIQ 异常中断处理程序
AREA INTERRUPT ,CODE,PEADONJY
;引入C语言的 IRQ中断处理程序 C_irq_handler
IMPORT C_irq_handler
IRQ
;保存返回 IRQ 处理程序地址
SUB lr,lr,#4
STMFD sp! ,(lr)
保存 SPSR_irq,及其他工作寄存器
MRS r14,SPSR
STMFD sp!,lr12,r14
;
;在这里添加指令,清除中断标志位
;添加指令重新使能中断
;
;切换到系统模式,并使能中断
MSR CPSR_C,#0x1f
;保存用户模式的 LR_usr 及被调用者不保存寄存器
STMFD sp!,(r0-r3,lr)
;跳转到C 语言的中断处理程序
BL C_irq_handler
;恢复用户模式的寄存器
LDMFD sp!,(r0-r3,lr)
;切换到IRQ 模式,禁止 IRQ 中断,FIQ 中断允许
MSR CPSP_c,#0x92
;恢复工作寄存器和 SPSR_irq
LDMFD sp!,(pc)^
END
6.2.2 复位中的异常中断处理程序
复位异常中断处理程序在系统加电或复位时执行,它将进行一些初始化的工作,具体内
容与复位系统相关,然后程序控制权交给应用程序,因而复位异常中断处理程序不需要返回。
下面时通常在复位异常中断处理程序进行的一些处理:
● 设置异常中断向量表。
● 初始化数据栈和寄存器。
● 初始化存储系统,如系统中的 MMU等。
● 初始化一些关键的 I/O设备。
● 使用中断。
● 将处理器切换到会话模式。
● 初始化 C 语言环境变量,条状到应用程序执行。
6.2.3 C 语言程序中的异常中断处理程序
在程序运行过程中,也可以在 C 语言程序中安装异常中断处理程序。这时需要把相应的跳
转指令或者数据读取指令的编码写到中断向量表的响应位置。下面分别讨论这两种情况下安
装异常中断处理程序的方法。
1.中断向量表中使用跳转指令的情况
当中断向量表中使用跳转指令时,在 C 程序中安装异常中断处理程序的操作如下:
(1) 读取中断处理程序的地址。
(2 ) 从上一步得到的地址中减去该异常中断对应的中断向量的地址。
(3) 从上一步得到的地址中减去 8,以允许指令的预取。
(4 ) 将上一步得到的地址右移 2 位,得到以字(32位)为单位的偏移量。
(5) 确保上一步得到的地址高 8 位为0,因为跳转指令只允许 24位的偏移量。
(6) 将上一步得到的地址与数据 0xea000000 作逻辑或,从而得到将要写到中断向