MIPS中的递归过程 - 堆栈?

时间:2016-03-10 14:10:08

标签: recursion stack mips

我必须在MIPS中创建一个过程eval_expr。基本上,它执行基本操作,如计算器,因此如果地址$a0中的参数为正,则它存储一个数字,如果它是否定的,则执行操作,它可以是:

  • -80,然后执行添加
  • -60,然后执行减法
  • -40,然后我们向右移动
  • -20,然后我们左转

$a0 + 4存储左子表达式的地址

$a0 + 8存储右子表达式的地址

使用伪代码,我们可以将此过程编写为:

int eval_expr (expr e) {
    if (is_number(e)) {
        return e.op;
    }
    else {
        if (e == -80)
            return eval_expr(e.left) + eval_expr(e. right);
        if (e == -60)
            return eval_expr(e.left) - eval_expr(e.right);
        if (e == -40)
            return eval_expr(e.left) >> eval_expr(e.right);
        if (e == -20)
            return eval_expr(e.left) << eval_expr(e.right);
        }
}

这是我到目前为止的代码:

eval_expr:
#stack frame 
addi $sp $sp -24
sw $ra 4($sp)
sw $fp 8($sp)
addiu $fp $sp 20

#if positive
lw $t1 ($a0)
slti $t0 $t1 0
bne $t0 $zero else
add $v0 $t1 $zero
j destack

#if negative
else:
addi $t3 $zero -20 
addi $t4 $zero -40
addi $t5 $zero -60
addi $t6 $zero -80

beq $a0 $t3 sl
beq $a0 $t4 sr
beq $a0 $t5 subs
beq $a0 $t6 addit

sl:
sw $a0 ($sp)
lw $a0 4($a0)
jal eval_expr
lw $a0 ($sp)
sw $v0 12($sp)
lw $a0 8($a0)
jal eval_expr
lw $t0 12($sp)
sllv $v0 $t0 $v0
j destack

sr:
sw $a0 ($sp)
lw $a0 4($a0)
jal eval_expr
lw $a0 ($sp)
sw $v0 12($sp)
lw $a0 8($a0)
jal eval_expr
lw $t0 12($sp)
srlv $v0 $t0 $v0
j destack

subs:
sw $a0 ($sp)
lw $a0 4($a0)
jal eval_expr
lw $a0 ($sp)
sw $v0 12($sp)
lw $a0 8($a0)
jal eval_expr
lw $t0 12($sp)
sub $v0 $t0 $v0
j destack

addit:
sw $a0 ($sp)
lw $a0 4($a0)
jal eval_expr
lw $a0 ($sp)
sw $v0 12($sp)
lw $a0 8($a0)
jal eval_expr
lw $t0 12($sp)
add $v0 $t0 $v0
j destack

#destacking
destack:
lw $a0 ($sp)
lw $ra 4($sp)
lw $fp 8($sp)
addi $sp $sp 24
jr $ra

不幸的是,只有在执行的操作向左移动时才有效。我认为这是因为这部分代码没有跳转到任何地方(这表明堆栈存在某种问题?),因此总是向左移动。

beq $a0 $t3 sl
beq $a0 $t4 sr
beq $a0 $t5 subs
beq $a0 $t6 addit

以下是我跑的所有测试:

Evaluate : (2<<2)
** Test passed **  Expected : 8 Received : 8

Evaluate : (1<<(2+(3-4)))
!! TEST FAILED !!  Expected : 2 Received : 1

Evaluate : (((2<<2)+(2<<2))<<((2<<2)+(2<<2)))
!! TEST FAILED !!  Expected : 1048576 Received : 2048

Evaluate : ((((1<<(2+(3-4)))<<3)-4)-(((2<<2)+(2<<2))<<((2<<2)+(2<<2))))
!! TEST FAILED !!  Expected : -1048564 Received : 128

Evaluate : (((((1<<(2+(3-4)))<<3)-4)-(((2<<2)+(2<<2))<<((2<<2)+(2<<2))))>>5)
!! TEST FAILED !!  Expected : -32768 Received : 4096

Evaluate : (((1+2)+((1<<(2+(3-4)))<<3))-(((((1<<(2+(3-4)))<<3)-4)-(((2<<2)+(2<<2))<<((2<<2)+(2<<2))))>>5))
!! TEST FAILED !!  Expected : 32787 Received : 1024

1 个答案:

答案 0 :(得分:0)

好吧,如果有人对答案感兴趣 - 我只加载一个地址,而不是实际值(来自寄存器$ a0)。这是代码的更正版本:

    eval_expr:
#stack frame
addi $sp $sp -24
sw $ra 4($sp)
sw $fp 8($sp)
addiu $fp $sp 20

#if positive
lw $t1 ($a0)
slti $t0 $t1 0
bne $t0 $zero else
add $v0 $t1 $zero
j destack

#if negative
else:
sw $a0 16($sp)
lw $a0 4($a0)
jal eval_expr
lw $a0 16($sp)
sw $v0 20($sp)
lw $a0 8($a0)
jal eval_expr
lw $t0 20($sp)
lw $a0 16($sp)
add $t1 $a0 $zero
lw $a0 ($a0) 
addi $t3 $zero -20
beq $a0 $t3 sl
addi $t3 $zero -40
beq $a0 $t3 sr
addi $t3 $zero -60
beq $a0 $t3 subs
addi $t3 $zero -80
beq $a0 $t3 addit


#operations

sl:
sllv $v0 $t0 $v0
j destack
sr:
srav $v0 $t0 $v0
j destack
addit:
add $v0 $t0 $v0
j destack
subs:

sub $v0 $t0 $v0
j destack

#destacking
destack:
lw $a0 ($sp)
lw $ra 4($sp)
lw $fp 8($sp)
addi $sp $sp 24
jr $ra