You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

ARMv7汇编R6寄存器被破坏问题求助(CPULATOR环境)

解决思路
  • 严格遵守ARMv7异常服务程序的寄存器保护规则
    ARMv7的IRQ异常触发时,硬件仅自动保存R0-R3、R12、LR、PC和CPSR到异常栈。R4-R11(包括你用的R6)属于非易失性寄存器,必须由软件手动保存/恢复。如果ISR中直接使用这些寄存器而不先入栈保存,中断返回后原程序的寄存器值会被覆盖,触发"clobbered register"错误。修改KEY_ISR的模板如下:

    KEY_ISR:
        PUSH {R6, LR}        ; 先将用到的R6和LR入栈保存
        ; 你的逻辑:加载SEQ到R6
        LDR R6, =SEQ
        ; 其他按键处理代码
        POP {R6, LR}         ; 恢复R6和LR的值
        SUBS PC, LR, #4      ; IRQ异常返回(必须减去4修正返回地址)
    

    如果你还用到其他R4-R11寄存器,要把它们也加入PUSH/POP列表。

  • 排查SEQ的存储与访问合法性
    确认SEQ的定义位置:如果是在.text段(代码段),可能被后续指令意外覆盖;建议将SEQ放在.data或.bss段。同时检查主循环、其他ISR中是否有修改SEQ内存地址的代码,导致R6加载的内容异常。

  • 验证中断返回逻辑的正确性
    确保中断返回指令正确:IRQ异常必须用SUBS PC, LR, #4返回,而非BX LR——因为LR在IRQ触发时会自动保存返回地址+4,需要减去4修正。如果返回指令错误,会导致上下文混乱,寄存器值被破坏。

  • 检查主程序对寄存器的使用规范
    即使更换了寄存器,若主程序在中断可能触发的代码段中未正确保护寄存器(比如主循环中直接使用R6而未考虑中断会修改它),也会出现同样问题。确保主程序中使用R6时,要么在临界区关闭中断,要么在使用前保存、使用后恢复。

  • 分步调试定位问题点
    在CPULATOR中设置断点:

    1. KEY_ISR入口处,查看R6的初始值;
    2. 加载SEQ到R6后,检查R6的值是否正确;
    3. ISR结束前,确认POP操作后R6恢复为初始值;
    4. MODE1标签处,查看R6的值是否被意外修改。
      通过跟踪寄存器值的变化,确定是ISR内部未保护寄存器,还是主程序或其他代码破坏了R6。

内容的提问来源于stack exchange,提问作者PeppeBz

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.16 13:12:34