曲径通幽论坛

 找回密码
 立即注册
搜索
查看: 7352|回复: 4
打印 上一主题 下一主题

IRQ.S 的解析

[复制链接]

4918

主题

5880

帖子

3万

积分

GROAD

曲径通幽,安觅芳踪。

Rank: 6Rank: 6

积分
34395
跳转到指定楼层
楼主
发表于 2008-11-16 22:34:41 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
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]

4918

主题

5880

帖子

3万

积分

GROAD

曲径通幽,安觅芳踪。

Rank: 6Rank: 6

积分
34395
沙发
 楼主| 发表于 2008-11-16 22:34:55 | 只看该作者
说明:
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的保存是因为会在发生中断嵌套时被覆盖掉。

0

主题

2

帖子

64

积分

初学弟子

积分
64
QQ
板凳
发表于 2009-3-16 10:24:58 | 只看该作者
根据ATPCS,R0-R3负责传递参数,R4-R11负责保存局部变量,那如果调用的C处理函数中有局部变量,R4-R11不是变化了吗

4918

主题

5880

帖子

3万

积分

GROAD

曲径通幽,安觅芳踪。

Rank: 6Rank: 6

积分
34395
地板
 楼主| 发表于 2009-3-16 11:57:58 | 只看该作者
R4-R11是保存局部变量,在使用过程中是会变化。但在一个程序中再调用一个子程序时,这些寄存器的内容会被入栈保存,当返回时再出栈恢复,看起来像是没改变过一样。所以说在返回后,这些寄存器中的内容没有变化。可能上面我表达的不是很清楚。

这些帖子都只是个人的笔记,中间有些地方难免有理解错误的地方。如果兄弟看到了,还望指点出来。

0

主题

2

帖子

64

积分

初学弟子

积分
64
QQ
5#
发表于 2009-3-16 16:40:10 | 只看该作者

呵呵,共同学习

刚才看了一下ATPCS文档,发现里面有一句In the base standard, a subroutine call preserves the values of r4-r11 and SP. 明白了
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

小黑屋|手机版|Archiver|曲径通幽 ( 琼ICP备11001422号-1|公安备案:46900502000207 )

GMT+8, 2025-5-3 00:26 , Processed in 0.104224 second(s), 22 queries .

Powered by Discuz! X3.2

© 2001-2013 Comsenz Inc.

快速回复 返回顶部 返回列表