为什么此递归阶乘程序仅返回我要计算的数字?

问题描述

我在ARM32中做了一个简单的(不工作)程序:

.global main

main:
    mov r0,#5    // 5 is the number that I want to calculate the factorial
    mov r1,r0

factorial:
    cmp r1,#1
    beq end
    sub r1,r1,#1    // n-1
    push {ip,lr}    // save the lr
    bl factorial
    mul r0,r0    // multiply r0 * n-1
    pop {ip,lr}
end:
    bx  lr

如果我执行它,我得到5,而不是120。

$ ./a.out
$ echo $?
5        

为什么?

解决方法

.global main

main:
    mov r0,#5    // 5 is the number that I want to calculate the factorial
    mov r1,r0

factorial:
    cmp r1,#1
    beq end
    sub r1,r1,#1    // n-1
    push {ip,lr}    // save the lr
    bl factorial
    mul r0,r0    // multiply r0 * n-1
    pop {ip,lr}
end:
    bx  lr

浏览代码...

mov r0,#5  r0 = 5
mov r1,r0  r1 = 5
cmp r1,#1
beq end 
sub r1,#1  r1 = 4
push
bl factorial
cmp r1,#1
beq end
sub r1,#1 r1 = 3

您看到问题了吗?您应该已经看到它了。

and this continues a few more times until
sub r1,#1 r1 = 1
push
bl factorial
cmp r1,#1
beq end
bx lr
mul r0,r0   r0 = 1 * 5 = 5
pop
bx lr
cmp r1,r0   r0 = 1 * 5 = 5
...

首先尝试不进行递归,然后记住递归,在这种情况下,您将需要一个局部变量,该局部变量会随每次调用而变化,并且如果您要使用单个值,或者如果要使用单个值,则需要考虑放置比较的位置您想使用两个,推送中的ip只是为了保持堆栈对齐,因此请记住,因为您可以使用它来保存这些寄存器之一并在退出时将其恢复。

请注意,来自小学

4*3*2*1 = 1*2*3*4

在stackoverflow上提问之前,您需要付出一些努力。

首先用C(或您更擅长的某种语言)编写和调试它,用printfs填充代码,一旦使用了已知的语言,就可以用汇编语言或任何新语言重新编写它正在学习。