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

ARM Cortex-M3(Keil)汇编实现累加总和问题咨询

解决R5累加被重置的问题

嘿,兄弟,我刚看完你的问题——R3能正常累加,R5却每次被打回初始值,最后只拿到48而不是预期的780,这事儿我之前帮朋友排查过类似的,大概率是踩了这几个汇编常见坑:

可能的原因&排查方向

1. 循环体里意外重置了R5

这是最常见的坑!你是不是在循环的开头或者某个分支里,不小心重复给R5赋值了?比如下面这种错误写法:

; 错误示例:每次循环都把R5打回初始值
MOV R5, #0  ; 累加初始值
LOOP:
    MOV R5, #0  ; 这里坑了!每次循环都清零R5
    ADD R5, R5, R3
    ADD R3, R3, #1
    CMP R3, #40
    BNE LOOP

这种情况下,R5永远只能拿到当前R3的值,最后R3走到48的话,R5自然就是48了。

排查方法:搜索代码里所有出现R5的地方,看有没有在循环内给R5赋值的指令,把多余的初始化语句移到循环外面。

2. 子程序调用时没保护R5寄存器

如果你的求和模块里调用了其他子程序,要注意:很多汇编架构(比如ARM)里,子程序会默认使用某些寄存器作为临时存储,如果你调用前没把R5压栈保存,子程序返回后R5的值就会被篡改,看起来像是被重置回初始值。比如:

; 错误示例:调用子程序前未保存R5
SUM:
    MOV R5, #0
    MOV R3, #1
LOOP:
    BL SUB_CALC  ; 调用子程序,没保存R5
    ADD R5, R5, R3
    ADD R3, R3, #1
    CMP R3, #40
    BNE LOOP

SUB_CALC:
    MOV R5, #48  ; 子程序直接修改了R5
    BX LR

解决方法:调用子程序前把R5和返回地址压栈,子程序返回后再弹栈恢复:

; 正确示例:保护R5寄存器
SUM:
    MOV R5, #0
    MOV R3, #1
LOOP:
    PUSH {R5, LR}  ; 保存R5和返回地址
    BL SUB_CALC
    POP {R5, PC}   ; 恢复R5并返回
    ADD R5, R5, R3
    ...

3. 累加指令写错了

有没有可能你把累加的ADD指令写成了MOV?或者误操作了其他寄存器?比如本来应该写ADD R5, R5, R3,结果写成了MOV R5, R3,这样R5永远只会等于当前的R3,而不是累加值。

排查方法:直接定位到累加逻辑的代码行,仔细核对指令的寄存器和操作码。

快速验证的正确累加示例(以ARM汇编为例)

如果你是计算1到39的和(1+2+...+39=780),正确的核心逻辑应该是这样的:

MOV R3, #1      ; 循环起始值设为1
MOV R5, #0      ; 累加器初始化为0
LOOP:
    ADD R5, R5, R3  ; 把当前R3的值加到R5里
    ADD R3, R3, #1  ; R3自增1
    CMP R3, #40     ; 判断是否超过39(到40就停止)
    BNE LOOP        ; 没到就继续循环
; 循环结束后R5的值就是780

你可以先按照上面的方向排查,尤其是用调试器单步执行,一眼就能看到R5什么时候被意外修改了。如果还是找不到问题,把你的核心代码片段贴出来,我帮你盯着看~

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.19 08:37:10