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
相关产品推荐
相关产品推荐

