以 mips 的形式将计算出的整数值添加到我的数组中

Adding a calculated integer value into my array in mips

当我 运行 程序时,我尝试以 mips 的形式将我的数字添加到我的数组中,但数组中唯一被填充的索引是当我的索引值 = 0 时,其他数字都显示作为 0.

编辑:这是我的完整 mips 代码和我用来翻译的代码

import java.util.Scanner;

public class PrimeDivisors {

    public static void main(String[] args) {
        Scanner input = new Scanner(System.in);
        System.out.print("Enter n: ");
        int n = input.nextInt();
        int factorial = 1;
        for (int i = 1; i <= n; i++) {
            factorial *= i;
        }
        System.out.println(n + "! = " + factorial);
        int[] primes = findPrimeDivisors(factorial);
        largestPower(primes, n);
    }

    public static void largestPower(int[] primes, int n) {
        System.out.println("Prime divisor\tLargest Power");
        int largestPower = 0;
        for (int i = 0; i < primes.length; i++) {
            if (primes[i] == 0) {
                break;
            }
            int primeNum = primes[i];
            System.out.print("\t" + primeNum);
            int hold = n;
            while (hold > 0) {
                hold /= primeNum;
                largestPower += hold;
            }
            System.out.print("\t\t\t\t" + largestPower + "\n");
            largestPower = 0;
        }
    }

    public static int[] findPrimeDivisors(int factorial) {
        int[] primes = new int[1000000];
        int index = 0;
        System.out.print("Prime Divisors of " + factorial + " = ");

        for (int i = 2; i < factorial; i++) {
            while (factorial % i == 0) {
                primes[index] = i;
                factorial /= i;
            }
            index++;
        }
        if(factorial > 2){
            primes[index-1] = factorial;
        }
        for(int i = 0; i < primes.length; i++){
            if(primes[i+1] == 0){
                System.out.print(primes[i]);
                break;
            } else {
                System.out.print(primes[i] + ", ");
            }
        }
        System.out.println();
        return primes;
    }
}
.data
primeArray: .space 120
prompt: .asciiz "Enter n: "
prompt2: .asciiz "Prime Divisor\tLarges Power"
prompt3: .asciiz "Prime Divisors of "
comma: .asciiz ", "
equals: .asciiz " = "
period: .asciiz ".\n"
exclamation: .asciiz "! = "
tab: .asciiz "\t"
tabs: .asciiz "\t\t\t\t"
newLine: .asciiz "\n"
input_number: .space 32 #Space for user input


.text
.globl main

main:
    #Print the prompt
    li $v0, 4
    la $a0, prompt #Address of prompt
    syscall
    
    #User Input
    li $v0, 5
    syscall

    #Store user input into $t0
    move $t0, $v0
    
    li $t1, 0 #int i = 1
    li $t2, 1 #factorial = 1
    jal calculateFactorial
    
    #print user input
    li $v0, 1
    move $a0, $t0
    syscall
    #print exclamation and equals
    li $v0, 4
    la $a0, exclamation
    syscall
    #print factorial value
    li $v0, 1
    move $a0, $t2
    syscall
    #print period
    li $v0, 4
    la $a0, period
    syscall
    
    jal findPrimeDivisors
    
    #print factorial value
    li $v0, 1
    move $a0, $t2
    syscall
    #exit program
    li $v0, 10
    syscall

findPrimeDivisors:
    #Print prompt3
    li $v0, 4
    la $a0, prompt3
    syscall
    #print factorial value
    li $v0, 1
    move $a0, $t2
    syscall
    #Print equals
    li $v0, 4
    la $a0, equals
    syscall
    
    addi $t3, $zero, 0 #Array index = 0
    li $t1, 2 #Index I=2
    la $s1, primeArray
    jal findPrimes
    
    #exit program
    li $v0, 10
    syscall

#input={$t0} i={$t1}, factorial={$t2}, arrayIndex={$t3}
findPrimes: #outer loop
    bgt $t1, $t2 exitLoop
    sw $ra, ($sp)
    jal innerLoop #innerLoop
    lw $ra, ($sp)
    
    addi $t1, $t1, 2 #increment outer loop by 2
    addi $t3, $t3, 4 #increment array index in outside loop
    
    j findPrimes

#remainder = ${t4}
innerLoop:
    bne $t4, 0, exitLoop #Break if remainder is not equal
    sw $t1, primeArray($t3) #Store value of I into array
    
    div $t2, $t2, $t1 #Factorial = Factorial / I
    mfhi $t4
    j innerLoop
    

#input={$t0} i={$t1}, factorial={$t2}
calculateFactorial:
    beq $t1, $t0, exitLoop
    addi $t1, $t1, 1
    mul $t2, $t1, $t2
    j calculateFactorial
exitLoop:
    jr $ra

如果我无法访问任何超过 0 的索引,请提供任何帮助。

您永远不会初始化 $t4。因此,bne $t4, 0, exitLoop 第一次落空,因为 $t4 被模拟器初始化为零。此后,它被“初始化”为它采用的最后一个值,该值是故意的 non-zero 值,因为这是内部循环退出的唯一方式。

该内部循环也不会修改 $t3,因此如果它有多个值,它会将它们全部存储到同一个地方。

从根本上说,您犯了一个错误,即假设可以使用 high-level 语言代码,但在翻译成汇编的过程中却选择偏离该代码。这始终是一个容易出错的尝试。如果您想进行更改(例如改进或优化),请先在 high-level 或伪代码中进行更改,然后对其进行测试以确保其有效。然后忠实地把伪代码转录成汇编。

在程序集中,您引入了一个附加函数,并将部分伪代码循环移到了这些新函数中,同时将同一循环的其他部分留在了外部。这不是基于逻辑等价的转换。因此,没有理由期望汇编代码的工作方式与 pseudo/Java 代码相同。虽然您可能认为引入较小的函数来完成部分工作是一种逻辑转换,但您错误地将主循环的工作分配给了新函数及其调用者。


您有一些违反调用约定的行为,但如果它在其他方面有效,那对您来说可能不是问题。