MIPS指令学习-嵌套过程

先来一个计算阶乘的递归过程(C编写):

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

参数n对应$a0
上代码

fact:
  addi  $sp, $sp, -8
  sw    $ra, 4($sp)
  sw    $a0, 0($sp)
slti $t0, $a0, 1
beq  $t0, $zero,  L1
--------------------------
addi $v0, $zero, 1
addi $sp, $sp, 8
jr $ra
--------------------------
L1: addi $a0, $a0, -1
jal fact
--------------------------位置2
lw $a0, 0($sp)
lw $ra, 4($sp)
addi $sp, $sp, 8
mul $v0, $a0, $v0
jr $ra

假设 n = 3,用计算机的思维去一步步推
首先计算机正在外面执行指令遇到fact的时候是位置1,等用完fact再返回位置1继续执行主代码。
所以先开2个栈,存放ra(位置1)和a0(n=3),接着判断 a0 > 1,3大于1使得t0=0,继而转到L1

fact:
  addi  $sp, $sp, -8
  sw    $ra, 4($sp)
  sw    $a0, 0($sp)
slti $t0, $a0, 1
beq  $t0, $zero,  L1

使a0=3-1=2,再把a0返回给fact,注意此时指令执行发生跳转,需要记录下ra=位置2

L1: addi $a0, $a0, -1
jal fact

回到上面,继续再开2个栈,存放ra(位置2)和a0(n=2),接着判断 a0 > 1,2大于1使得t0=0,继而转到L1

fact:
  addi  $sp, $sp, -8
  sw    $ra, 4($sp)
  sw    $a0, 0($sp)
slti $t0, $a0, 1
beq  $t0, $zero,  L1

使a0=3-1=1,再把a0返回给fact,注意此时指令执行发生跳转,需要记录下ra=位置2

L1: addi $a0, $a0, -1
jal fact

继续再开2个栈,存放ra(位置2)和a0(n=1),接着判断 a0 > 1,结果不于1使得t0=1

fact:
  addi  $sp, $sp, -8
  sw    $ra, 4($sp)
  sw    $a0, 0($sp)
slti $t0, $a0, 1
beq  $t0, $zero,  L1

终于可以顺序执行下去了,把1赋给返回值v0,再把ra(位置2)和a0(n=1)这两栈退了,jr跳转到ra(位置2)

addi $v0, $zero, 1
addi $sp, $sp, 8
jr $ra

从栈中读取并退掉ra(位置2)和a0(n=2)这两栈,接着v0=v0 * a0=1 * 2,又碰到jr指令跳转到刚刚读取的ra(位置2)

lw $a0, 0($sp)
lw $ra, 4($sp)
addi $sp, $sp, 8
mul $v0, $a0, $v0
jr $ra

此时栈中只剩存放ra(位置1)和a0(n=3)的栈,从栈中读取并退掉ra(位置1)和a0(n=3)这两栈,接着v0=v0 * a0=1 * 2 * 3,又碰到jr指令跳转到刚刚读取的ra(位置1)

lw $a0, 0($sp)
lw $ra, 4($sp)
addi $sp, $sp, 8
mul $v0, $a0, $v0
jr $ra

至此程序执行完成,程序执行又回到外面,得到了v0=123的返回值

你可能感兴趣的:(MIPS指令学习-嵌套过程)