Home > Software design >  Adding a calculated integer value into my array in mips
Adding a calculated integer value into my array in mips

Time:04-16

When I run the program I try adding my numbers to my array in mips but the only index in the array that is getting filled is when my index value is = 0, the other numbers are all showing as 0.

Edit: This is my full mips code and the code I used to translate

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

Any help for why I am not able to access any index past 0 would be appreciated.

CodePudding user response:

You never initialize $t4.  So, the first time the bne $t4, 0, exitLoop falls through, because $t4 is initialized to zero by the simulator.  Thereafter, it is "initialized" to the last value it took on which was, on purpose, a non-zero value, since that is the only way that the inner loop exits.

That inner loop also does not modify $t3, so if it ever comes up with multiple values, it will store them all to the same place.

Fundamentally, you have made the mistake of having presumably working high-level language code, but chosen to deviate from that during the translation to assembly.  This is always an error prone endeavor.  If you want to make changes (e.g. to improve or optimize) then do that in your high-level or pseudo code first, and test it to make sure it works.  Then transcribe faithfully the pseudo code to assembly.

In the assembly you have introduced an additional function, and moved parts of the pseudo code's loop inside those new function(s), while leaving other parts of the same loop outside.  This is not a transformation based on logical equivalence.  So, there's no reason to expect the assembly code to work the same as the pseudo/Java code.  While you might think introducing smaller functions to do parts of work is a logical transformation, you have split the work of the main loop incorrectly over the new function(s) and its caller.


You have a number of calling convention violations, but if it otherwise works, that may not be of issue to you.

  • Related