ARM32递归阶乘程序为何仅返回输入值而非正确阶乘结果?
问题分析:ARM32递归阶乘程序返回5而非120的原因
你的阶乘程序逻辑存在两个关键错误,直接导致了结果不符合预期,咱们一步步拆解问题所在:
1. 递归调用后r1的值被覆盖,丢失当前层的计算上下文
在进入递归前,你执行了sub r1,r1,#1把当前值减1,但递归调用返回后,r1已经变成1了——因为递归到最底层时,r1等于1,触发beq end直接返回,不会再修改r1。这时候你执行mul r0,r1,r0,其实是拿1去乘当前的r0,完全没用到当前层原本的n-1值。
举个实际流程例子:
- 第一层:
r0=5,r1=4,调用递归 - 第二层:
r0=5,r1=3,调用递归 - ...直到第五层:
r0=5,r1=1,直接返回 - 回到第四层时,
r1已经是1,乘法后r0还是5 - 所有上层返回后,
r0始终保持初始的5,最终返回结果自然是5
2. 未保存当前层的计算变量
你没有在递归调用前保存当前层的关键变量(也就是减1前的r1或者r0),导致递归回来后无法获取当前层需要参与乘法的数值,整个递归的累积计算逻辑完全失效。
修复后的代码示例
.global main main: mov r0,#5 // 初始化要计算阶乘的数 bl factorial // 调用阶乘计算函数 bx lr // 程序退出 factorial: cmp r0,#1 // 判断当前数是否为1(阶乘终止条件) beq fact_end // 是1直接返回(1的阶乘为1) push {r0, lr} // 保存当前的n值和返回地址,避免被递归覆盖 sub r0,r0,#1 // 计算n-1,作为递归入参 bl factorial // 递归计算(n-1)! pop {r1, lr} // 取出之前保存的n值和返回地址 mul r0,r1,r0 // 计算n * (n-1)!,得到当前层的阶乘结果 fact_end: bx lr // 返回上层调用
验证修复结果
编译运行修复后的代码,执行echo $?就能得到预期的120了——现在每一层递归都会妥善保存当前的计算变量,递归返回后能正确完成累积乘法,阶乘的逻辑就通顺了。
内容的提问来源于stack exchange,提问作者Mnkisd
相关产品推荐
相关产品推荐

