我的任务是编写一个递归MIPS汇编程序,在program1中执行以下数学运算:
(-3)*function1(n-2) + 7*function1(n-3) + 15
该程序以c:
为模型 // The function1 is a recursive procedure defined by:
// function1(n) = 1 if n <= 2
// = (-3)*function1(n-2) + 7*function1(n-3) + 15 otherwise.
int function1(int n)
{
if (n <= 2)
{
return 1;
}
else
{
int comp = (-3)*function1(n-2) + 7*function1(n-3) + 15;
return comp;
}
}
// The main calls function1 by entering an integer given by a user.
void main()
1 of 2{
int ans, n;
printf("Enter an integer:\n");
// read an integer from user and store it in "n"
scanf("%d", &n);
ans = function1(n);
// print out the solution computed by function 1
printf("The solution is: %d\n", ans);
return;
}
我编写了代码,编译并执行正常,但给了我不正确的值:
.data
mes1: .asciiz "\nEnter an integer: "
mes2: .asciiz "The solutinon is: "
.text
.globl main
main:
#Display message
la $a0, mes1
li $v0, 4
syscall
#Retrieve Value
li $v0, 5
syscall
#Store value into $a0 and jump to function1
move $a0, $v0
jal function1
#Store return value to $t0
move $t0, $v0
#Display solution
la $a0, mes2
li $v0, 4
syscall
move $a0, $t0
li $v0, 1
syscall
#End
li $v0, 10
syscall
function1:
#Store return address
addi $sp, $sp, -4
sw $ra, 0($sp)
#Store $a0 to stack
addi $sp, $sp, -4
sw $a0, 0($sp)
#If($a0<3):$t0=1:$t0=0
slti $t0, $a0, 3
#if($t0=0):math
beq $t0, $zero, math
addi $v0, $zero, 1
#Retrieve from stack
lw $a0, 0($sp)
addi $sp, $sp, 4
lw $ra, 0($sp)
addi $sp, $sp, 4
jr $ra
math:
addi $a0, $a0, -2
jal function1
mul $s0 $v0, -3
addi $a0, $a0, -3
jal function1
mul $s1, $v0, 7
add $s1, $s0, $s1
addi $v0, $s1, 15
#Retrieve from stack
lw $a0, 0($sp)
addi $sp, $sp, 4
lw $ra, 0($sp)
addi $sp, $sp, 4
jr $ra
当我输入6时,它应该输出91.目前,它输出44.也许更令人不安,每当我输入任何值时,输出数字总是可被4整除。对于我的生活,我无法想象出了什么问题。有人可以建议吗?
- 编辑 -
我考虑了@TomásBadan关于保护$ a0的评论。我试过了:
math:
#Store $a0 to stack
addi $sp, $sp, -4
sw $a0, 0($sp)
addi $a0, $a0, -2
jal function1
mul $s0, $v0, -3
#Retrieve from stack
lw $a0, 0($sp)
addi $sp, $sp, 4
addi $a0, $a0, -3
jal function1
mul $s1, $v0, 7
add $s1, $s0, $s1
addi $v0, $s1, 15
#Retrieve from stack
lw $a0, 0($sp)
addi $sp, $sp, 4
lw $ra, 0($sp)
addi $sp, $sp, 4
jr $ra
但它仍然返回不正确的值,尽管更接近正确的数字。
答案 0 :(得分:3)
好吧,我会指定一些错误,这不是一个完整的调试会话:
function1:
...
#If($a0<3):$t0=1:$t0=0
slti $t0, $a0, 3
#if($t0=0):sub1
beq $t0, $zero, math
#Load 4 to $v0
addi $v0, $zero, 4 // I thought you should return 1
...
math:
addi $a0, $a0, -2 // you are changing $a0 here
jal function1
lw $t2, constn3
mult $v0, $t2
mflo $t0 // you use $t0 to keep temporary values, but you function change $t0 too (look above, at instruction slti). You need to protect its contents
addi $a0, $a0, -3 // but you need your original value here
jal function1
lw $t2, const7
mult $v0, $t2
<强> EDITED 强>
正如我在评论中所说,你需要保留所有需要在过程调用之间保持状态的寄存器。
如果您遵循MIPS约定调用,则表示您必须保存在函数内部使用的s *系列中的任何寄存器。您使用其中两个s0和s1,因此,您必须将它们保存在入口点。嗯,这是另一个问题,你必须只有一个入口点和一个出口点。
function1:
#Store return address
addi $sp, $sp, -12
sw $ra, 0($sp)
sw $s0, 4($sp)
sw $s1, 8($sp)
#If($a0<3):$t0=1:$t0=0
slti $t0, $a0, 3
#if($t0=0):math
beq $t0, $zero, math
addi $v0, $zero, 1
j exit
math:
addi $sp, $sp, -4
sw $a0, 0($sp)
addi $a0, $a0, -2
jal function1
lw $a0, 0($sp)
addi $sp, $sp, 4
addi $t6, $zero, -3
mul $s0 $v0, $t6
addi $sp, $sp, -4
sw $a0, 0($sp)
addi $a0, $a0, -3
jal function1
lw $a0, 0($sp)
addi $sp, $sp, 4
addi $t6, $zero, 7
mul $s1, $v0, $t6
add $s1, $s0, $s1
addi $v0, $s1, 15
#Retrieve from stack
exit:
lw $ra, 0($sp)
lw $s0, 4($sp)
lw $s1, 8($sp)
addi $sp, $sp, 12
jr $ra