为什么中断服务程序,PUSH {r3,r4,r5,lr},但导致ERROR的POP {r0,r4,r5,lr}?

时间:2017-08-17 06:13:29

标签: c arm iar

我使用IAR编译例程,但在ARM A7上运行错误;当我打开IAR生成的 .lst 文件时,我得到了以下问题。     它是ISR,第一个push {r3, r4, r5, lr},但POP {r0, r4, r5, lr}返回时,R0值在推送前更改为R3的值。因此R0irqHandler返回时出错,导致后续例程出错。     为什么?

    void irqHandler(void)
    {
         878:   e92d4038    push    {r3, r4, r5, lr}
      volatile u32 *pt = (u32 *)AM_INTC_BASE;
         87c:   e3a044b0    mov r4, #176, 8 ; 0xb0000000
      u32 id_spin;

      id_spin = *(pt+0x200c/4) & 0x3ff;
         880:   e302000c    movw    r0, #8204   ; 0x200c
         884:   e7900004    ldr r0, [r0, r4]
         888:   e1b00b00    lsls    r0, r0, #22
         88c:   e1b00b20    lsrs    r0, r0, #22
         890:   e1b05000    movs    r5, r0
      if(id_spin<32)
         894:   e3550020    cmp r5, #32
         898:   2a000000    bcs 8a0 <irqHandler+0x28>
      {
    #ifdef WHOLECHIPSIM
        print("id_spid<32 error...\r\n",0);
    #endif    
        while(1);
         89c:   eafffffe    b   89c <irqHandler+0x24>
      }
      else
      {
        (pFuncIrq[id_spin-32])();
         8a0:   e59f0010    ldr r0, [pc, #16]   ; 8b8 <.text_8>
         8a4:   e1b01105    lsls    r1, r5, #2
         8a8:   e0910000    adds    r0, r1, r0
         8ac:   e5100080    ldr r0, [r0, #-128] ; 0x80
         8b0:   e12fff30    blx r0
      }
    }
         8b4:   e8bd8031    pop {r0, r4, r5, pc}

4 个答案:

答案 0 :(得分:0)

当硬件调用中断向量例程时,R0-R3,R12,LR,PC,xPSR自动保存在堆栈中无关紧要。调用bxldmpopldr并调用PC时,硬件执行中断例程退出弹出这些寄存器。

不要检查您的编译器。它知道它的作用。检查错误的逻辑 - 特别是在中断处理程序中打印字符串。

答案 1 :(得分:0)

abi需要一个64位对齐的堆栈,因此r3的推送简单地促进了这一点。可以选择任何尚未指定的寄存器。同样在pop上他们需要清理堆栈,函数原型为void,所以返回(r0)是不关心的,r0-r3不会被保留,所以没有理由匹配每一端的r3也不匹配每端都是r0。

如果他们在推送时选择了编号高于r3(例如r6)的寄存器,则需要在pop上进行匹配。否则,pop必须是r0-r3之一才能不丢弃非易失性寄存器。 (无法推动r3然后弹出r6会破坏r6)

答案 2 :(得分:0)

使用关键字__irq __arm汇编代码如下:

    __irq __arm void irqHandler(void)
    {
         878:   e24ee004    sub lr, lr, #4
         87c:   e92d503f    push    {r0, r1, r2, r3, r4, r5, ip, lr}
      volatile u32 *pt = (u32 *)AM_INTC_BASE;
         880:   e3a044b0    mov r4, #176, 8 ; 0xb0000000
      u32 id_spin;

      id_spin = *(pt+0x200c/4) & 0x3ff;
         884:   e302000c    movw    r0, #8204   ; 0x200c
         888:   e7900004    ldr r0, [r0, r4]
         88c:   e1b00b00    lsls    r0, r0, #22
         890:   e1b00b20    lsrs    r0, r0, #22
         894:   e1b05000    movs    r5, r0
      if(id_spin<32)
         898:   e3550020    cmp r5, #32
         89c:   2a000000    bcs 8a4 <irqHandler+0x2c>
      {
    #ifdef WHOLECHIPSIM
        print("id_spid<32 error...\r\n",0);
    #endif    
        while(1);
         8a0:   eafffffe    b   8a0 <irqHandler+0x28>
      }
      else
      {
        (pFuncIrq[id_spin-32])();
         8a4:   e59f0010    ldr r0, [pc, #16]   ; 8bc <.text_8>
         8a8:   e1b01105    lsls    r1, r5, #2
         8ac:   e0910000    adds    r0, r1, r0
         8b0:   e5100080    ldr r0, [r0, #-128] ; 0x80
         8b4:   e12fff30    blx r0
      }
    }
         8b8:   e8fd903f    ldm sp!, {r0, r1, r2, r3, r4, r5, ip, pc}^

答案 3 :(得分:0)