曲径通幽论坛

标题: 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