【问题标题】:Why this recursive factorial program only returns the number that I want to calculate?为什么这个递归阶乘程序只返回我要计算的数字?
【发布时间】:2020-09-09 15:42:39
【问题描述】:

我在 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        

为什么?

【问题讨论】:

  • 当您到达n == 1 并开始进行所有乘法运算时,您已经设置了r1 = 1。您可能应该在堆栈上保存并恢复它。
  • 使用调试器单步执行您的代码,以查看寄存器值如何变化。并考虑一下您的递归函数接受并传递给子调用的 2 个参数到底是什么。以及传递 2 个参数对于阶乘实现是否有效。
  • 你现在应该已经完成​​了这个作业,你会在这门课上挣扎。非递归版本发生了什么?

标签: recursion assembly arm factorial


【解决方案1】:
.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

浏览您的代码...

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 乱扔代码,一旦你用你知道的语言编写了算法,然后只需用汇编语言或任何你熟悉的新语言重新编写它正在学习。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2017-11-29
    • 2015-04-19
    • 2015-12-21
    • 2015-01-08
    • 2023-03-30
    • 2012-10-24
    • 1970-01-01
    • 2013-11-03
    相关资源
    最近更新 更多