我必须在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
答案 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