关于ARM7软中断的那个小事 2011年11月25日

1

读取软中断标号的方法:

软件中断由专门的软中断指令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 位

由些可见,在ARM状态下有16M个中断标号,也就是说可以有16M个软中断。在THUMB下有256个软中断

那么在__swi(0x24) void my_swi (void);
定义为__swi(0x24) void my_swi (uint32 i,uint32 j);时,中断调用时,i被存储到R0中,这时可以将上面的程序中的R0修改为R1,那么j中存储的值就是R1中的数据,也就是中断编号。ATPCS中指出函数的参数1....参数4,分别存储到R0....R3中,多于4个参数的用堆栈来进行存储。

FIQ_Handler
        STMFD   SP!, {R0-R3, LR}
        BL      FIQ_Exception
        LDMFD   SP!, {R0-R3, LR}
        SUBS    PC,  LR,  #4

在快速中断时,ARM不自动保存PC到LR中,必须用程序来保存!所以在推出中断时,SUBS    PC,  LR,  #4

而软中断会自动保存PC值到LR中,有下列程序分析可知:

SWI_Handler                 
 STMFD   SP!, {R0-R3, LR}
 LDR  R1,[LR,#-4]
 BIC  R1,R1,#0xff000000
    BL      SWI_Exception
    LDMFD   SP!, {R0-R3, LR}
    MOVS    PC,  LR

虽然第二行程序中 我把LR也做压栈处理了,但是从第三行程序LR-4得到的就是软中断指令可知在,在译码指到软中断时,PC指向软中断的下一条指令就不再取指令了,而第三行能正确地取得软中断指令就说明了在发生了软中断时,ARM自动保存了PC到LR中。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值