【问题标题】:MIPS recursion call in loop, preserving loop variable循环中的 MIPS 递归调用,保留循环变量
【发布时间】:2012-11-17 21:02:50
【问题描述】:

我正在将以下递归 java 程序转换为 MIPS asm。该算法计算数字的所有可能的排序/排列。但是递归调用在 for 循环中。我需要在我的 MIPS 版本中保留变量“i”,但我不知道在哪里添加它。我的算法是正确的,只是我的 $t0(即“i”)永远不会重置为 0。我只是不知道如何/在何处将其保存在堆栈中或何时将其从堆栈中取出。任何帮助表示赞赏。

import java.util.Arrays;


public class Test 
{
    private static void swap(int[] v, int i, int j) 
    {
        int t = v[i]; 
        v[i] = v[j]; 
        v[j] = t;
    }

    public void permute(int[] v, int n) 
    {
        if (n == 1) 
            System.out.println(Arrays.toString(v));
        else 
        {
            for (int i = 0; i < n; i++) 
            {
                permute(v, n-1);
                if (n % 2 == 1) 
                    swap(v, 0, n-1);
                else 
                    swap(v, i, n-1);
            }
        }
    }

    public static void main(String[] args) 
    {
        int[] ns = {1, 2, 3, 4};
        new Test().permute(ns, ns.length);
    }

}

和 mips 函数 注意:我是在置换字符串,而不是整数,但算法是一样的。

#----------------------------------------------
# anagram - Prints all the permutations of 
# the given word
#     a0 - the word to compute the anagrams
#     s0 - n, the length of the word
#     a1 - n - 1 (length-1)
#----------------------------------------------
anagram:
addi $sp, $sp, -16

sw $a0, 0($sp)
sw $a1, 4($sp)
sw $s0, 8($sp)
sw $ra, 12($sp)

add $s0, $a1, $zero         # this is n

addi $a1, $s0, -1           # n-1
beq $s0, 1, printS
init: move $t0, $zero       # t0 = i = 0
logic: slt $t1, $t0, $s0        # Set t1 = 1 if t0 < length
       beqz $t1, endAnagram     # if it's zero, it's the end of the loop

jal anagram

li $t2, 2
div $s0, $t2
mfhi $t3

beqz $t3, even          # if even branch to even, otherwise it will go to odd
odd: # swap the n-1 char with the first
add $t4, $a0, $zero
add $t5, $a0, $a1

lb $t6, 0($t4)          # first char
lb $t7, 0($t5)          # n-1 char

sb $t7, 0($t4)          # swap the two
sb $t6, 0($t5)

j inc # skip the even section

even: # swap the ith char with n-1 char
add $t4, $a0, $t0           # ith char
add $t5, $a0, $a1           # n-1 char

lb $t6, 0($t4)          # ith char
lb $t7, 0($t5)          # n-1 char

sb $t7, 0($t4)          # swap the two
sb $t6, 0($t5)

inc: addi $t0, $t0, 1           # t0++;
j logic

endAnagram:
# reset stack pointers
lw $a0, 0($sp)
lw $a1, 4($sp)
lw $s0, 8($sp)
lw $ra, 12($sp)
addi $sp, $sp, 16           # adjust stack
jr $ra

printS: # print string and jump to return
   jal printString # calls printString function which prints the string

   j endAnagram

【问题讨论】:

    标签: loops assembly recursion stack mips


    【解决方案1】:

    $t0 不会根据约定在子例程调用中保留,并且您似乎遵循该约定。因此,您有两个选择:

    1. 您可以将i 存储在保留的寄存器中,在这种情况下 您需要在序言/尾声中自己保存注册表。您已经为$s0 这样做了。
    2. 或者您将$t0 自己保存在堆栈中,围绕子例程调用

    在这两种情况下,您都需要为本地人提供更多空间,因此请将addi $sp, $sp, -16 更改为addi $sp, $sp, -20(以及结尾处的匹配代码)。如果您选择选项#1,例如使用$s1 来存储i。添加代码以保存和恢复$s1,就像您为$s0 所做的那样。如果您选择选项#2,请在jal anagram 周围添加代码,将$t0 写入jal 之前的堆栈,并在之后重新加载。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2013-11-21
      • 1970-01-01
      • 1970-01-01
      • 2022-01-24
      • 2021-01-17
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多