微波EDA网,见证研发工程师的成长!
首页 > 硬件设计 > 嵌入式设计 > GNU ARM汇编--(四)中断汇编之非嵌套中断处理

GNU ARM汇编--(四)中断汇编之非嵌套中断处理

时间:11-26 来源:互联网 点击:

00000,那在异常向量表中:

@b irq
ldr pc, _irq

就出现了一个问题:只能用b irq跳转,无法用ldr pc, _irq跳转.当时就觉得奇怪,找了半天原因.后来才知道b跳转和用ldr伪指令只有区别的:

b是位置无关的,ldr不是位置无关的

b的范围只能是前后16M,总共32M,而ldr是4G

ldr的跳转是根据_irq: .word irq的值,这个值是链接的时候确定的,也就是与链接地址相关.

所以在lds中链接地址改为0x00000000后,b和ldr都是正确的.

具体可以用dump看一下实际效果:

当lds中是0x30000000时,arm-linux-objdump -d int.elf结果如下:

30000000 <_start>:
30000000: ea00000e b 30000040
30000004: e59ff014 ldr pc, [pc, #20] ; 30000020 <_undefined_instruction>
30000008: e59ff014 ldr pc, [pc, #20] ; 30000024 <_software_interrupt>
3000000c: e59ff014 ldr pc, [pc, #20] ; 30000028 <_prefetch_abort>
30000010: e59ff014 ldr pc, [pc, #20] ; 3000002c <_data_abort>
30000014: e59ff014 ldr pc, [pc, #20] ; 30000030 <_not_used>
30000018: e59ff014 ldr pc, [pc, #20] ; 30000034 <_irq>
3000001c: e59ff014 ldr pc, [pc, #20] ; 30000038 <_fiq>

而lds中是0x00000000时,dump的结果如下:

00000000 <_start>:
0: ea00000e b 40
4: e59ff014 ldr pc, [pc, #20] ; 20 <_undefined_instruction>
8: e59ff014 ldr pc, [pc, #20] ; 24 <_software_interrupt>
c: e59ff014 ldr pc, [pc, #20] ; 28 <_prefetch_abort>
10: e59ff014 ldr pc, [pc, #20] ; 2c <_data_abort>
14: e59ff014 ldr pc, [pc, #20] ; 30 <_not_used>
18: e59ff014 ldr pc, [pc, #20] ; 34 <_irq>
1c: e59ff014 ldr pc, [pc, #20] ; 38 <_fiq>

解决了这第一个问题,总算可以用ldr跳入中断向量了.

2、中断处理程序的写法:

[cpp]view plaincopy

  1. irq:
  2. sublr,lr,#4
  3. stmfdsp!,{r0-r12,lr}
  4. blirq_isr
  5. ldmfdsp!,{r0-r12,pc}^

值得注意的是ldmfd sp!,{r0-r12,pc}^ 会自动的从spsr_irq中恢复到cpsr中.

stmfd等价于stmdb,ldmfd等价于ldmia.因为arm使用FD(向低地址整长的满栈),所以堆栈处理都用fd的后缀即可.

3、记得在中断处理程序中清除中断,不然的话会一直响应那个中断.

Copyright © 2017-2020 微波EDA网 版权所有

网站地图

Top