gpt4 book ai didi

assembly - 如何在 MIPS Assembly 中执行递归操作?

转载 作者:行者123 更新时间:2023-12-04 04:40:25 25 4
gpt4 key购买 nike

我的任务是编写一个递归 MIPS 汇编程序,该程序在 function1 中执行以下数学运算:

(-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ás Badan 关于保护 $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

但它仍然返回不正确的值,尽管更接近正确的数字。

最佳答案

好吧,我会指定一些错误,这不是一个完整的调试 session :

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

已编辑

正如我在评论中所说,您需要保留所有需要在过程调用之间保持状态的寄存器。

如果您遵循 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

关于assembly - 如何在 MIPS Assembly 中执行递归操作?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/18991655/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com