ARM的状态寄存器与中断详解

CPSR & SPSR

  • CPSR: current program status register
  • SPSR: saved program status register

CPU中只有一个全局的CPSR寄存器,但对应每一个异常中断模式(usr和sys不是异常中断模式,所以没有SPSR)都有一个独立的SPSR,用于在CPU切换至其他mode时对当前的CPSR进行备份。

由于CPSR的特殊性,不同于r0~r15,它只能通过msrmrs指令进行读写。其中s表示status register,即CPSR,而r表示register,即普通寄存器。这两个指令中的sr和rs按照从右向左的顺序表示着数据移动的方向。msr表示数据从r移动至s,即将r中的内容写入s,mrs则为从s移动至r,即从s中读取数据至r。

msr cpsr, r0 // write cpsr
mrs r0, cpsr // read cpsr

而作为备份寄存器,SPSR就单纯得多。

当中断引起mode转变时,ARM将通过硬件替我们完成一系列工作来确保mode顺利切换,其中就包含将当前的CPSR保存至SPSR的操作。

!CPSR中的mode位改变的瞬间才是CPU真正切换mode的一刻,因此CPSR必须在被改变之前就保存至目标mode的SPSR,所以只能由硬件完成。

不仅如此,ARM还有一个特殊设计:当目标寄存器为pc时,后缀s修改的将不是NZCV,而是将当前SPSR中的内容写入CPSR。

因此我们只需要在ISR(interrupt service routine)结束后,使用以下指令即可同时复原CPSR:

movs pc, lr // pc = lr_mode && cpsr = spsr_mode
adds pc, lr, #0xff // pc = lr_mode + 0xff && cpsr = spsr_mode
subs pc, lr, #4 // pc = lr_mode - 4 && cpsr = spsr_mode

!pc与cpsr是同时被修改的

作为信息量超大的状态寄存器,CPSR中的每一个bit都至关重要,因此常常需要在保持其他bit不变的前提下对其中的个别bit进行读写,此时若使用普通的指令就会非常繁琐。因此ARM额外提供了一系列专门用于访问CPSR的特别指令 to make our life easier:

  • cps Change Processor Status(修改CPSR[4:0])

      cps #0x1f // change CPU to SYS mode
      cps #0x11 // change CPU to FIQ mode
      cps #0x10 // change CPU to USR mode
  • cpsIE / cpsID Interrupt Enable / Disable(修改A、I、F位)

      cpsIE a // enable ABT interrupt (cpsr_a = 0)
      cpsIE i // enable IRQ interrupt (cpsr_i = 0)
      cpsID f, #0x10 // disable FIQ interrupt (cpsr_f = 1) and change to USR mode

    !disables when the bit is set.

Interrupt

// 待续

全部评论

相关推荐

投递腾讯等公司10个岗位
点赞 评论 收藏
转发
点赞 收藏 评论
分享
牛客网
牛客企业服务