Warning: file_get_contents(/data/phpspider/zhask/data//catemap/0/assembly/6.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Recursion 为什么这个递归阶乘程序只返回我要计算的数字?_Recursion_Assembly_Arm_Factorial - Fatal编程技术网

Recursion 为什么这个递归阶乘程序只返回我要计算的数字?

Recursion 为什么这个递归阶乘程序只返回我要计算的数字?,recursion,assembly,arm,factorial,Recursion,Assembly,Arm,Factorial,我在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

我在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,r1,r0    // multiply r0 * n-1
    pop {ip,lr}
end:
    bx  lr
如果我执行它,我得到的是5,而不是120

$ ./a.out
$ echo $?
5        
为什么?

浏览你的代码

mov r0,#5  r0 = 5
mov r1,r0  r1 = 5
cmp r1,#1
beq end 
sub r1,r1,#1  r1 = 4
push
bl factorial
cmp r1,#1
beq end
sub r1,r1,#1 r1 = 3
你看到问题了吗?你现在应该已经看到了

and this continues a few more times until
sub r1,r1,#1 r1 = 1
push
bl factorial
cmp r1,#1
beq end
bx lr
mul r0,r1,r0   r0 = 1 * 5 = 5
pop
bx lr
cmp r1,#1
beq end
bx lr
mul r0,r1,r0   r0 = 1 * 5 = 5
...
请先在不使用递归的情况下进行尝试,记住对于递归,在这种情况下,每次调用都需要一个局部变量进行更改,如果要使用单个值或两个值,则需要考虑将比较放在何处,推送中的ip只是保持堆栈对齐,所以请记住,您可以使用它来保存其中一个寄存器,并在退出时恢复它

注意,从小学开始

4*3*2*1 = 1*2*3*4
在stackoverflow上提问之前,你需要付出一些努力

首先用C语言(或者你比较擅长的语言)编写并调试它,在代码中加入printfs,一旦你用一种你知道的语言编写了算法,然后简单地用汇编语言或任何你正在学习的新语言重新编写它

浏览你的代码

mov r0,#5  r0 = 5
mov r1,r0  r1 = 5
cmp r1,#1
beq end 
sub r1,r1,#1  r1 = 4
push
bl factorial
cmp r1,#1
beq end
sub r1,r1,#1 r1 = 3
你看到问题了吗?你现在应该已经看到了

and this continues a few more times until
sub r1,r1,#1 r1 = 1
push
bl factorial
cmp r1,#1
beq end
bx lr
mul r0,r1,r0   r0 = 1 * 5 = 5
pop
bx lr
cmp r1,#1
beq end
bx lr
mul r0,r1,r0   r0 = 1 * 5 = 5
...
请先在不使用递归的情况下进行尝试,记住对于递归,在这种情况下,每次调用都需要一个局部变量进行更改,如果要使用单个值或两个值,则需要考虑将比较放在何处,推送中的ip只是保持堆栈对齐,所以请记住,您可以使用它来保存其中一个寄存器,并在退出时恢复它

注意,从小学开始

4*3*2*1 = 1*2*3*4
在stackoverflow上提问之前,你需要付出一些努力


首先用C语言(或你比较擅长的语言)编写并调试它,在代码中加入printfs,一旦你用你熟悉的语言编写了算法,然后用汇编语言或你正在学习的任何新语言重新编写它。

当你达到
n==1
并开始执行所有乘法时,您已经设置了
r1=1
。您可能应该在堆栈上保存并还原它。使用调试器单步检查代码,以查看寄存器值是如何更改的。想想递归函数接受并传递给子调用的2个参数到底是什么。以及传递2个参数是否对阶乘实现有效。您现在应该已经完成了这个赋值,您将与这个类斗争。非递归版本发生了什么?当您到达
n==1
并开始执行所有乘法时,您已经设置了
r1=1
。您可能应该在堆栈上保存并还原它。使用调试器单步检查代码,以查看寄存器值是如何更改的。想想递归函数接受并传递给子调用的2个参数到底是什么。以及传递2个参数是否对阶乘实现有效。您现在应该已经完成了这个赋值,您将与这个类斗争。非递归版本发生了什么?