【问题标题】:Not understanding instruction execution order in recursive factorial function (MIPS)不了解递归阶乘函数 (MIPS) 中的指令执行顺序
【发布时间】:2014-04-13 04:44:27
【问题描述】:

在给定序列顺序的情况下,我对这段代码如何为每个 n-1 乘以 n 感到困惑。让我解释一下我如何看待正在发生的事情,你可以指出我错在哪里。

如果 n 小于 0,则比较结果为假,程序仅返回 1(如果这是第一次调用)。如果不是,则调用 L1 并递减。这是我感到困惑的地方。看起来事实在减量后立即再次被调用,并且乘法函数永远不会发生。在这种情况下,如果 n = 5,那么它会简单地递减直到 n = 0,最后乘以 1 x 5。

我最好的猜测是,我在将值推入和弹出堆栈方面遗漏了一些东西,但我不知道。

 fact: addi $sp, $sp, -8 # adjust stack for 2 items 
 sw $ra, 4($sp) # save the return address 
 sw $a0, 0($sp) # save the argument n 

 slti $t0, $a0, 1 # test for n < 1 
 beq $t0, $zero, L1 # if n >= 1, go to L1 

 addi $v0, $zero, 1 # return 1 
 addi $sp, $sp, 8 # pop 2 items off stack 
 jr $ra # return to instruction after jal 

 L1: addi $a0, $a0, -1 # n >= 1; argument gets (n – 1)
 jal fact # call fact with (n – 1)

 lw $a0, 0($sp) # return from jal: restore argument n 
 lw $ra, 4($sp) # restore the return address 
 addi $sp, $sp, 8 # adjust stack pointer to pop 2 items 

 mul $v0, $a0, $v0 # return n * fact (n – 1) 

 jr $ra # return to the caller 

编辑:

这里是用 C 语言编写的函数:

int fact (int n)
{
  if (n < 1) return (1);
  else return (n * fact(n – 1));
}

【问题讨论】:

  • 条件可以是if (n &lt;= 1) 以避免一次(无用的)递归。

标签: assembly mips


【解决方案1】:

假设你想要 3 个!所以从 n = 3 开始。

n

--> 返回 3 * 事实(2)

返回 n = 2 的函数

n

-> 返回 2* 事实(1)

返回 n = 1 的函数

再次 n

-> 返回 1* 事实(0)

返回 n = 0 的函数

现在 n

返回 1


递归开始展开

1 替换 fact(0) 并且函数返回 1*1

1 替换 fact(1) in 并且函数返回 2*fact(1) 即 2

2 替换 fact(2) 并且函数返回 3*fact(2) 即 6

递归结束。

【讨论】:

    【解决方案2】:

    “我最好的猜测是,我在将值推入和弹出堆栈方面遗漏了一些东西,但我不知道。”

    就是这样;

    你忘记了从堆栈中弹出,一旦你调用到 4 然后 3 然后 2 然后 1(这里得到值 1),你返回 AT $ra !并且函数继续并逐一进行乘法,然后逐一弹出每个堆栈级别,直到最后的 $ra 结束整个函数调用。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2013-10-13
      • 2017-03-17
      • 2019-08-06
      • 1970-01-01
      • 1970-01-01
      • 2015-04-16
      • 1970-01-01
      相关资源
      最近更新 更多