曲径通幽论坛
标题:
IRQ.S 的解析
[打印本页]
作者:
beyes
时间:
2008-11-16 22:34
标题:
IRQ.S 的解析
IRQ.S 的解析
引用:
[blockquote]AREA IRQ,CODE,READONLY
MACRO ;
宏定义开始
$IRQ_Label HANDLER $IRQ_Exception_Function
;宏名为 HANDLER,$IRQ_Exception_Function--宏的参数
EXPORT $IRQ_Label
;输出的标号
IMPORT $IRQ_Exception_Function
;引用的外部标号
$IRQ_Label
SUB LR, LR, #4
;LR中保存的是下下一条指令,故这里需要-4
STMFD SP!, {R0-R3, R12, LR}
;保存任务环境
MRS R3, SPSR
;保存状态
STMFD SP!, {R3}
STMFD SP, {LR}^
;保存用户状态的LR,注意不能回写(后面有^符号),SP仍为 IRQ 模式的寄存器, STMFD 被翻译成 STMDB(先减),LR存入堆栈,但 SP 未更新,所以下面要调整
SUB SP, SP, #4
;调整
MSR CPSR_c, #(NoInt | SYS32Mode)
;切换到系统模式
BL $IRQ_Exception_Function
; 调用c语言的中断处理程序
MSR CPSR_c, #(NoInt | IRQ32Mode)
; 切换回irq模式
LDMFD SP, {LR}^ ;
恢复用户状态的LR,注意不能回写
ADD SP, SP, #4
;调整堆栈指针
LDMFD SP!, {R3}
MSR SPSR_cxsf, R3
LDMFD SP!, {R0-R3, R12, PC}^ ;
MEND[/blockquote]
作者:
beyes
时间:
2008-11-16 22:34
说明:
1、
希望在中断时调用这个 IRQ.S,那么对于 C 语言中的中断处理函数要用 extern来声明(IRQ_Exception_Function 在宏中表示 C 中的函数);还需要用 extern 在 C 中声明汇编的标号 IRQ_Label。这里要注意:IRQ_Label 在C中的声明要如C函数一样,比如
extern
void
Timer0_handler(
void
)
2、
在IRQ.S 中需要调用中断处理函数,而中断处理函数为 C 所写。根据 ATPCS 规范知道,C 语言函数返回时,寄存器 R4~R11,SP是不会改变的,因为如果函数使用的参数超出了 4 个,那么就会用堆栈来传递,但前面4个参数会用 R0~R3, 而 R12也将被用到,所以上面所要保存的寄存器正是在调用时会被破坏的寄存器,即 R0~R3 和 R12。LR的保存是因为会在发生中断嵌套时被覆盖掉。
作者:
nqlf
时间:
2009-3-16 10:24
根据ATPCS,R0-R3负责传递参数,R4-R11负责保存局部变量,那如果调用的C处理函数中有局部变量,R4-R11不是变化了吗
作者:
beyes
时间:
2009-3-16 11:57
R4-R11是保存局部变量,在使用过程中是会变化。但在一个程序中再调用一个子程序时,这些寄存器的内容会被入栈保存,当返回时再出栈恢复,看起来像是没改变过一样。所以说在返回后,这些寄存器中的内容没有变化。可能上面我表达的不是很清楚。
这些帖子都只是个人的笔记,中间有些地方难免有理解错误的地方。如果兄弟看到了,还望指点出来。
作者:
nqlf
时间:
2009-3-16 16:40
标题:
呵呵,共同学习
刚才看了一下ATPCS文档,发现里面有一句In the base standard, a subroutine call preserves the values of r4-r11 and SP. 明白了
欢迎光临 曲径通幽论坛 (http://www.groad.net/bbs/)
Powered by Discuz! X3.2