软件中断由专门的软中断指令SWI 触发,SWI 指令后面跟一个中断编号,
以标识可能共存的多个软件中断程序。
在C 程序中调用软件中断需要用到编译器的扩展功能,使用关键字“__swi”
来声明中断函数。注意软中断号码同时在函数定义时指定。
__swi(0x24) void my_swi (void);
这样当调用函数my_swi 的时候,就会用“SWI 0x24”来代替普通的函数调
用“BL my_swi”。
可以发现软件中断同样存在着中断分支的问题,即需要根
据中断号码来决定调用不同的处理程序。软中断号码只存在于SWI 指令码当中,
因此需要在中断处理程序中读取触发中断的指令代码,然后提取中断号信息,再进行进一步处理。
下面是软中断指令的编码格式:
ARM 状态下的SWI 指令编码格式,32 位长度,其中低24 位是中断编号。
Thumb 状态下的SWI 指令编码格式,16 位长度,其中低8 位是中断编号。
为了在中断处理程序里面得到SWI 指令的地址,可以利用LR 寄存器。每
当响应一次SWI 的时候,处理器都会自动保存并调整LR 寄存器,使里面的内
容指向SWI 下一条指令的地址,所以把LR 里面的地址内容上溯一条指令就是
所需的SWI 指令地址。需要注意的一点是当SWI 指令的执行状态不同时,其指
令地址间隔不一样,如果进入SWI 执行前是在ARM 状态下,需要通过LR-4 来
获得SWI 指令地址,如果是在Thumb 状态下进入,则只要LR-2 就可以了。
下面是一段提取SWI 中断号码的例程:
MRS R0, SPSR ;检查进入SWI 响应前的状态
TST R0, #T_bit ;是ARM 还是Thumb?#T_bit=0x20
LDRNEH R0, [LR, #-2] ;是Thumb,读回SWI 指令码
BICNE R0, R0, #0xff00 ;提取低8 位
LDREQ R0, [LR, #-4] ;是ARM,读回SWI 指令码
BICEQ R0, R0, #0xff000000 ;提取低24 位
;寄存器R0 中的内容是正确的软中断编号了
阅读(2673) | 评论(0) | 转发(0) |