MIPS: reading 2d array and printing it - arrays

here is the code in C
Void mm ( double a[][]), double b[][], double c[][])
{
int i, j, k;
for (i=0; i! = 3; i = i+1){
for (j = 0; j! = 3; j = j+1){
d[i][j] = a[i][j] ;
for (k = 0; k! = 3; k = k+1){
d[i][j] = d[i][j] + b[i][k] * c[k][j];
}
}
}
}
also keep in mind that I have to read the data of arrays a,b,c and then print array d
and here is my assembly code
.data
arrA: .space 72
arrB: .space 72
arrC: .space 72
arrD: .space 72
bracA: .asciiz "a("
bracB: .asciiz "b("
bracC: .asciiz "c("
bracD: .asciiz "d("
comma: .asciiz ","
endBrac: .asciiz ")= "
nextLine: .asciiz "\n"
.text
.globl main
main:
addi $sp, $sp, -32 #Make space of stack
sw $ra, 20($sp) #Store $ra
la $a1, arrA #load base of Array a
la $a2, arrB #load base of Array b
la $a3, arrC #load base of Array c
la $t7, arrD #load base of Array d
li $s0, 1 #set i
li $s1, 1 #set j
li $s2, 1 #set k
li $s7, 1 #counter
loopi:
slti $t0, $s0, 4 #Check i<4
beq $t0, $zero, nextArr #If i=4 go nextArr
loopj:
slti $t0, $s1, 4 #Check j<4
beq $t0, $zero, nextRow #If i=4 go nextRow
slti $t1, $s7, 4 #Check counter
beq $t1, $zero, contB #if counter >=4 go to contB
li $v0, 4 #Prepare for print string
la $a0, bracA #Load adress of string "a("
syscall
j cont
contB:
slti $t1, $s7, 7
beq $t1, $zero, contC #if counter>=7 go to contC
li $v0, 4
la $a0, bracB
syscall
j cont
contC:
slti $t1, $s7, 10
beq $t1, $zero, calcD
li $v0, 4
la $a0, bracC
syscall
cont:
li $v0, 1 #prepare to print integer
move $a0, $s0 #print i
syscall
li $v0, 4
la $a0, comma
syscall
li $v0, 1
move $a0, $s1 #print j
syscall
li $v0, 4
la $a0, endBrac
syscall
sll $t0, $s0, 1 #t0=2*i
add $t0, $t0, $s0 #t0=3*i
add $t0, $t0, $s1 #t0=3*i +j
sll $t0, $t0, 3 #t0=(3*i +j)*8 create double precision
slti $t1, $s7, 4
beq $t1, $zero, useA2
add $t0, $t0, $a1 #a1=base address of a array
j contLi
useA2:
slti $t1, $s7, 7
beq $t1, $zero, useA3
add $t0, $t0, $a2 #a2=base address of a array
j contLi
useA3:
add $t0, $t0, $a3 #a3=base address of a array
contLi:
li $v0, 7
syscall
s.d $f0, 0($t0) #store $t0 to $f0 as floating point
l.d $f12, 0($t0)
li $v0, 3 #get ready to print double
syscall
addi $s1, $s1, 1 #increase j
li $v0, 4
la $a0, nextLine
syscall
j loopj
nextRow:
addi $s7, $s7, 1 #increase counter
addi $s0, $s0, 1 #increase i
li $s1, 1 #set j=1
j loopi
nextArr:
li $s0, 1 #set i=1
li $s1, 1 #set j=1
j loopi
calcD:
li $s0, 1 #set i,j,k=1 for calculations
li $s1, 1
li $s2, 1
li $t0, 0
li $t1, 0
li $t2, 0
li $t3, 0
outLoop:
slti $t0, $s0, 4 #Loop that count i
beq $t0, $zero, printRes
inLoop1:
slti $t0, $s1, 4 #loop that count j
beq $t0, $zero, finInLoop1
sll $t0, $s0, 1 #t0=2*i
add $t0, $t0, $s0 #t0=3*i
add $t0, $t0, $s1 #t0=3*i +j
sll $t0, $t0, 3 #t0=(3*i +j)*8 (double precision)
add $t0, $t0, $a1 #a1=base address of a array
sll $t1, $s0, 1 #t3=2*i
add $t1, $t1, $s0 #t3=3*i
add $t1, $t1, $s1 #t3=3*i +j
sll $t1, $t1, 3 #t3=(3*i +j)*8 for double precision
add $t1, $t1, $t7 #t4=base address of d array
mtc1 $zero,$f0 #f8=sum to be stored in d[i][j](initial value before k loops=0)
cvt.d.w $f0, $f0
mov.d $f8, $f0
l.d $f2, 0($t0) #Load $t0 to $f2
inLoop2:
slti $t4, $s2, 4 #Loop that count k
beq $t4, $zero, finInLoop2
sll $t2, $s0, 1 #t1=2*i
add $t2, $t2, $s0 #t1=3*i
add $t2, $t2, $s2 #t1=3*i +k
sll $t2, $t2, 3 #t1=(3*i +k)*8 (double precision)
add $t2, $t2, $a2 #a2=base address of b array
sll $t3, $s2, 1 #t2=2*k
add $t3, $t3, $s2 #t2=3*k
add $t3, $t3, $s1 #t2=3*k +j
sll $t3, $t3, 3 #t2=(3*k +j)*8 for double precision
add $t3, $t3, $a3 #a3=base address of c array
#So far, t0=address of a[i][j], t1=address of b[i][k], t2=address of c[k][j] and t3=address of d[i][j]
l.d $f4, 0($t2) #Load $t2 to $f4
l.d $f6, 0($t3) #Load $t3 to $f6
mul.d $f10, $f4, $f6
add.d $f8, $f8, $f10
addi $s2, $s2, 1
j inLoop2
finInLoop2:
add.d $f8, $f8, $f2
s.d $f8, 0($t1)#store total sum in d[i][j]
addi $s1, $s1, 1
li $s2, 1 #k=1 to start loop for next j
add.d $f8, $f8, $f0
j inLoop1
finInLoop1:
addi $s0, $s0, 1
li $s1, 1# j=1 to start loop for next i
j outLoop
printRes:
li $s0, 1 #initial value of i=1
li $s1, 1 #initial value of j=1
li $s2, 1 #initial value of k=1
printLoop1:
slti $t0, $s0, 4
beq $t0, $zero, Exit
slti $t0, $s1, 4
beq $t0, $zero, printLoop2
li $v0, 4
la $a0, nextLine
syscall
li $v0, 4
la $a0, bracD
syscall
li $v0, 1
move $a0, $s0
syscall
li $v0, 4
la $a0, comma
syscall
li $v0, 1
move $a0, $s1
syscall
li $v0, 4
la $a0, endBrac
syscall
sll $t0, $s0, 1 #t0=2*i
add $t0, $t0 $s0 #t0=3*i
add $t0, $t0, $s1 #t0=3*i +j
sll $t0, $t0, 3 #t0=(3*i +j)*8 (double precision)
add $t0, $t0, $t7 #t4=base address of d array
l.d $f12, 0($t0)
li $v0, 3 #get ready to print double
syscall
addi $s1, $s1, 1
j printLoop1
printLoop2:
addi $s0, $s0, 1
li $s1, 1
j printLoop1
Exit:
jr $ra
when I read the data
the program prints instantly what I have written
and it doesn't print in the end the d array
I'm a beginner in mips assembly so there might be some major problems with my code
but I can't find them...

Related

Translating from c to mips assembly

I have spent the greater part of today trying to properly translate this c code to mips and I'm struggling on the formatting and the second half of the pattern. The second part of the pattern breaks in a new way everytime i make a small change to the code. Im lookin to learn so any other tips regarding mips and mistakes made would help a ton.
.data
prompt: .asciiz "Please enter the number of Columns: "
s: .asciiz " "
n: .asciiz "\n"
.text
main:
li $v0, 4
la $a0, prompt
syscall
li $v0,5
syscall
move $s0, $v0 #$s0 holds N
li $s3, 0 #$s3 holds I
li $s4, 0 #$s4 holds J
li $s5, 1 #s5 holds K
add $s2, $zero, $s0 #holds N-i
li $s2, 0
add $s2, $zero, $s0
addi $s2, $s2, 1
sub $s2, $s2, $s3
for1:
blt $s0,$s3, bottom
addi $s3, $s3, 1
li $s4, 0
j for2
for2:
blt $s3, $s4,for3
li $v0, 4
la $a0, s
syscall
addi $s4, $s4, 1
li $s2, 0
add $s2, $zero, $s0
addi $s2, $s2, 1
sub $s2, $s2, $s3
li $s5 , 1
j for2
for3:
blt $s2, $s5,newline1
li $t0, 0
add $t0, $zero, $s5
li $v0, 1
move $a0, $t0
syscall
li $t0, 0
addi $s5, $s5, 1
j for3
bottom:
li $s3, 1 #$s3 holds I
li $s4, 1 #$s4 holds J
li $s5, 1 #s5 holds K
add $s2, $zero, $s0 #holds N-i
addi $s2, $s2, 1
sub $s2, $s2, $s3
for4:
blt $s0,$s3, exit
addi $s3, $s3, 1
li $s4, 0
li $s2, 0
add $s2, $zero, $s0
sub $s2, $s2, $s3
j for5
for5:
blt $s2, $s4,for6
li $v0, 4
la $a0, s
syscall
addi $s4, $s4, 1
li $t2, 1
addi $t2, $s3, 0
li $s5 , 1
j for5
for6:
blt $t2, $s5,newline2
li $t3, 2
addi $t3,$s3, 0
sub $t3,$t3,$s5
li $v0, 1
move $a0, $t3
syscall
addi $s5, $s5, 1
j for6
newline1:
li $v0, 4
la $a0, n
syscall
j for1
newline2:
li $v0, 4
la $a0, n
syscall
j for4
exit:
li $v0, 10
syscall
here is the c code:
#include <stdio.h>
int main(void) {
int n;
printf("Please enter the number of columns:"); // [0.25 mark]
scanf("%d",&n); // [0.25 mark]
//printing the upper part of the pattern.
for(int i=0;i<n;i++){ // [4 mark]
for(int j=0;j<i;j++) { // [4 mark]
printf(" "); // [0.25 mark]
}
for(int k=1;k<=n-i;k++){ // [4 mark]
printf("%d", k); // [0.5 mark]
}
printf("\n"); // [0.25 mark]
}
//printing the lower part of the pattern.
for(int i=1;i<n;i++){ // [4 mark]
for(int j=1;j<n-i;j++){ // [4 mark]
printf(" "); // [0.25 mark]
}
for(int k=1;k<=i+1;k++){ // [4 mark]
printf("%d", (i+2 - k)); // [0.5 mark]
}
printf("\n"); // [0.25 mark]
}
return 0; // [0.25 mark]
}
Any help with this is greatly apprciated!
update working code
.data
prompt: .asciiz "Please enter the number of Columns: "
s: .asciiz " "
n: .asciiz "\n"
.text
main:
li $v0, 4
la $a0, prompt
syscall
li $v0,5
syscall
move $s0, $v0 #$s0 holds N
li $s3, 0 #$s3 holds I
li $s4, 0 #$s4 holds J
li $s5, 1 #s5 holds K
add $s2, $zero, $s0 #holds N-i
li $s2, 0
add $s2, $zero, $s0
addi $s2, $s2, 1
sub $s2, $s2, $s3
for1:
ble $s0,$s3, bottom
li $s4, 0
j for2
for2:
blt $s3, $s4,for3
li $v0, 4
la $a0, s
syscall
addi $s4, $s4, 1
li $s2, 0
add $s2, $s0, 0
sub $s2, $s2, $s3
li $s5 , 1
j for2
for3:
blt $s2, $s5,newline1
li $t0, 0
add $t0, $zero, $s5
li $v0, 1
move $a0, $t0
syscall
li $t0, 0
addi $s5, $s5, 1
j for3
bottom:
li $s3,1 #$s3 holds I
li $s4, 1 #$s4 holds J
li $s5, 1 #s5 holds K
li $s2, 0
add $s2, $s0, 0 #holds N-i
j for4
for4:
blt $s0, $s3, exit
li $s2, 0
add $s2, $s0, 0
sub $s2, $s2, $s3
li $s4, 1
j for5
for5:
blt $s2, $s4,for6
li $v0, 4
la $a0, s
syscall
addi $s4, $s4, 1
li $t1, 1
li $t2, 2
add $t1, $t1, $s3
add $t2, $t2,$s3
li $s5, 1
j for5
for6:
blt $t1, $s5,newline2
li $t3, 0
sub $t3, $t2,$s5
li $v0, 1
move $a0, $t3
syscall
addi $s5, $s5, 1
j for6
newline1:
addi $s3, $s3, 1
li $v0, 4
la $a0, n
syscall
j for1
newline2:
addi $s3, $s3, 1
li $v0, 4
la $a0, n
syscall
j for4
exit:
li $v0, 10
syscall
This is the proper solution to the question. The mark comments are for grading purposes as this is an assignment. The issue I ran to was I was incrementing I within the first for loop moving it to the newline function helped fix the issue I was having. The pattern was only meant to reach 1-9. If there are any new questions ill try my best to answer them.
.data
prompt: .asciiz "Please enter the number of Columns: "
s: .asciiz " "
n: .asciiz "\n"
.text
main:
li $v0, 4
la $a0, prompt # asks column amount
syscall
li $v0,5
syscall
move $s0, $v0 #$s0 holds N
li $s3, 0 #$s3 holds I
li $s4, 0 #$s4 holds J #declares locations for variables
li $s5, 1 #s5 holds K
add $s2, $zero, $s0 #holds N-i
li $s2, 0
add $s2, $zero, $s0
addi $s2, $s2, 1 # sets up n-i
sub $s2, $s2, $s3
for1: # first for loop
ble $s0,$s3, bottom # break when less than to bottom func
li $s4, 0 # resets j to 0 eveery iteration
j for2 #jumps to second loop
for2:
blt $s3, $s4,for3 # breaks when less than to for3
li $v0, 4 #prints spaces
la $a0, s
syscall
addi $s4, $s4, 1 # increments J
li $s2, 0
add $s2, $s0, 0
sub $s2, $s2, $s3 #updates n-i
li $s5 , 1
j for2 #repeats loop
for3:
blt $s2, $s5,newline1 #break when less than to newline1
li $t0, 0
add $t0, $zero, $s5
li $v0, 1
move $a0, $t0 #prints numbers (K)
syscall
li $t0, 0
addi $s5, $s5, 1
j for3 # repeats loop
bottom:
li $s3,1 #$s3 holds I
li $s4, 1 #$s4 holds J #sets variables for second 3 loops
li $s5, 1 #s5 holds K
li $s2, 0
add $s2, $s0, 0 #holds N-i
j for4
for4:
blt $s0, $s3, exit #break to exit when less than
li $s2, 0
add $s2, $s0, 0
sub $s2, $s2, $s3 #sets up n-i
li $s4, 1 #sets j to 1
j for5
for5:
blt $s2, $s4,for6 #break to sixth loop
li $v0, 4
la $a0, s #prints spaces
syscall
addi $s4, $s4, 1 #increments j
li $t1, 1
li $t2, 2 #setting up i+1 and i+2
add $t1, $t1, $s3
add $t2, $t2,$s3
li $s5, 1 #sets k to 1
j for5 #repeats loop
for6:
blt $t1, $s5,newline2 #breaks to newline 2 func
li $t3, 0
sub $t3, $t2,$s5 #prints numbers
li $v0, 1
move $a0, $t3
syscall
addi $s5, $s5, 1
j for6 #repeats loops
newline1:
addi $s3, $s3, 1 #increments i
li $v0, 4
la $a0, n #prints new line
syscall
j for1 # jumps to for loop 1
newline2:
addi $s3, $s3, 1 #increments i
li $v0, 4 #prints new line
la $a0, n
syscall
j for4 #jumps to for loop 4
exit: #ends program
li $v0, 10
syscall

Trying to change array value in MIPS assembly

I was hoping that I could get some help debugging some code. I am going to try to not make this a It is for a MIPS assembly project in recursion. The program is only supposed to print prime numbers.
The idea is I have two arrays, one that lists every whole number up to 110, and the other as a flag array that is initialized to all ones.
For every position in the flag array that is a 1 it prints the number and every 0 it doesn't print the number. The good news is I figured out issues with all my loops, the issue I am having is saving the value 0 to the flag array at the position it currently is. Everything that I reference talks about using:
sw [register], ([register])
From what I understand that is how you save the contents of one register to the position of the other? It doesn't seem to work for me. I went ahead and posted the code down bellow, It is kind of messy and really long, but my code for recursion is down where it says Eratosthenes.
.data
NUM_ARRAY: .space 800 # 800-byte memory space
FLAG_ARRAY: .space 800 # 800-byte memory space
START_MSG: .asciiz "The prime numbers up to 110 are:\n"
END_MSG: .asciiz "Completed ...."
SPACE: .asciiz " "
NEWLINE: .asciiz "\n"
BUG1: .asciiz "Out of loop"
INK: .asciiz "incrementK"
INX: .asciiz "incrementX"
.text
.globl main
# THE BEGINNING OF MODULE MAIN #######################
main:
# save the ten registers --------------------------
subu $sp, $sp, 48 # stack frame for 12 registers
sw $ra, ($sp)
sw $s0, 4($sp)
sw $s1, 8($sp)
sw $s2, 12($sp)
sw $s4, 16($sp)
sw $s5, 20($sp)
sw $t0, 24($sp)
sw $t1, 28($sp)
sw $t2, 32($sp)
sw $v0, 36($sp)
sw $a0, 40($sp)
# initialize the essential parameters -------------
li $s0, 111 # the largest number (always - 1)
li $s1, 10 # the square-root of $s0 register
li $s2, 2 # the initial value for "k"
li $s4, 0 # the first numbers to consider
li $s5, 1 # '1' - it is a prime number
li $t2, 0 # loop ounter
# show an opening message ---------------------------------
li $v0, 4 # system call #4
la $a0, START_MSG
syscall
# initialize the two arrays -------------------------------
la $t0, NUM_ARRAY # set the address of the 1st array
la $t1, FLAG_ARRAY # set the address of the 2nd array
loop1: sw $s4, ($t0) # load a number
sw $s5, ($t1) # load the initial property (1 - a prime)
addi $t2, $t2, 1 # increase the loop counter by one
beq $t2, $s0, EXIT1 # if all the array elements are set up
addi $s4, $s4, 1 # increase the number by one
addu $t0, $t0, 4 # increase the pointer by four bytes
addu $t1, $t1, 4 # increase the pointer by four bytes
j loop1 # repeat to "loop1"
EXIT1: li $s2, 2
li $s6, 2
jal Eratosthenes # start recursive Eratosthenes
li $v0, 4 # system call #4
la $a0, NEWLINE
syscall
li $v0, 4 # system call #4
la $a0, NEWLINE
syscall
li $t2, 0 # reset the loop counter
la $t0, NUM_ARRAY # reset the address of the 1st array
la $t1, FLAG_ARRAY # reset the address of the 2nd array
loop3: lw $a0, ($t1) # load the number there
beq $a0, $zero, SKIP1 # if the target is '0': skip
beq $t2, $zero, SKIP1 # if repeated enough: skip
li $v0, 1 # system call #1
lw $a0, ($t0) # load the number there
syscall
li $v0, 4 # system call #4
la $a0, NEWLINE
syscall
SKIP1: addi $t2, $t2, 1 # increase the loop counter
addu $t0, $t0, 4 # increase the pointer by four bytes
addu $t1, $t1, 4 # increase the pointer by four bytes
blt $t2, $s0, loop3
li $v0, 4 # system call #4
la $a0, END_MSG
syscall
# restore registers ---------------------------------------
lw $ra, ($sp)
lw $s0, 4($sp)
lw $s1, 8($sp)
lw $s2, 12($sp)
lw $s4, 16($sp)
lw $s5, 20($sp)
lw $t0, 24($sp)
lw $t1, 28($sp)
lw $t2, 32($sp)
lw $v0, 36($sp)
lw $a0, 40($sp)
addu $sp, $sp, 48 # delete the stack frame
jr $31 # park it at the parking spot
# THE END OF MODULE MAIN ##########################################
Eratosthenes:
subu $sp,$sp,36
sw $ra, 0($sp)
sw $t5, 4($sp)
sw $t6, 8($sp)
sw $t0, 12($sp)
sw $t1, 16($sp)
sw $t2, 20($sp)
sw $s4, 24($sp)
sw $s5, 28($sp)
sw $s0, 32($sp)
li $s5, 0 #change s5 to 0
li $s6, 2 #reset the x
li $t2, 0
la $t0, NUM_ARRAY #reset Array 1
la $t1, FLAG_ARRAY #reset Array 2
R_Loop:
mult $s2,$s6
mflo $t7
addi $t2,$t2,1
lw $s4, ($t0)
beq $t7, $s4, SKIPone
beq $t2, $s0, EXITL #branch if counter is max
addu $t0, $t0, 4 #next spot in NUM_ARRAY
addu $t1, $t1, 4 #next spot in FLAG_ARRAY
li $v0,1
move $a0, $t7
syscall
li $v0,4
la $a0, NEWLINE
syscall
li $v0,4
la $a0, NEWLINE
syscall
j R_Loop
SKIPone:
addi $s6,$s6,1 #increment x by one
sw $zero, ($t1) #attempt at making position at array 0
#have also tried
#sw $s5, ($t1) #where s5 is initialized at 0
#please take note that offset is 0, because it needs to be
#at the current position at the array
li $v0,4
la $a0, NEWLINE
syscall
li $v0,4
la $a0, NEWLINE
syscall
li $v0,1
move $a0, $t4 #debug aid
syscall
li $v0,4
la $a0, NEWLINE
syscall
li $v0,4
la $a0, NEWLINE
syscall
beq $t2 $s0, EXITL
li $v0, 4
la $a0, INX #debug aid
syscall
j R_Loop
EXITL:
li $t8,10
li $v0, 4
la $a0, INK #debug aid
syscall
beq $s2,$t8, EXITR
addi $s2,$s2,1 #increment k by one
jal Eratosthenes
li $v0 4
la $a0, BUG1
syscall
EXITR:
lw $ra, 0($sp)
lw $t5, 4($sp)
lw $t6, 8($sp)
lw $t0, 12($sp)
lw $t1, 16($sp)
lw $t2, 20($sp)
lw $s4, 24($sp)
lw $s5, 28($sp)
lw $s0, 32($sp)
addu $sp,$sp,36
jr $ra
Any help is appreciated, nothing else seems to work and my teacher is of no help.

MIPS array assign infinity loop

I am trying to fix this problem for hours!!!!!
When I enter 8 integers for the array and then enter 0 to finish reading, when the loop section starts it goes to infinity loop!!
I can't find where's the problem, when I remove the addiu from the $s2 array it works fine but doesn't store the $t1 on the array!
Please HELP!!
.data
array: .space 32
percentage_Array: .space 32
newLine: .asciiz "\n"
.text
main:
la $s1, array
la $s2, percentage_Array
read_numbers:
li $v0, 5
syscall
sw $v0, 0($s1)
addiu $s1, $s1, 4
beqz $v0, continue
j read_numbers
continue:
la $s1, array
loop:
lw $t0, 0($s1)
addiu $s1, $s1, 4
beqz $t0, exit
move $a1, $t0
jal calculate_Ones_and_Bits
move $s6, $v0
move $s7, $v1
#put the total number of ones
add $s0, $s0, $s7
#calculate the percentage
addi $t5, $zero, 100
mult $s7, $t5
mflo $t1
div $t1, $s6
mflo $t1
#-----I THINK HERE IS MY PROBLEM------
#Put the percentages on percentage_Array array
sw $a1, 0($s2)
addiu $s2, $s2, 4
#Check which percentages are greater than 50 and print the numbers
which fulfill the condition
slti $t2, $t1, 50
beq $t2, 1, loop
li $v0, 1
move $a0, $t0
syscall
#lines 66,67,68 are extra just for printing in new line more clearly
li $v0, 4
la $a0, newLine
syscall
j loop
exit:
#lines 73,74,75 are also extra just to print the value of s0, it is
printed here so it
#will be executed after the loop has finished
li $v0, 1
move $a0, $s0
syscall
#tell the OS to exit/finish
li $v0, 10
syscall

Copying an array for sorting not working correctly in MIPS program?

I'm working on a sorting program that sorts an array of integers, for which I copy the array entered in by the user into a new array to be mutated. However, I'm not sure if I'm doing it correctly.
.globl main
.data
input: .asciiz "Enter the size of the array: \n"
entries: .asciiz "Enter the elements of the array, one line at a time: \n"
output: .asciiz "Original array and then sorted array: \n"
space: .asciiz " "
.text
main:
subi $sp, $sp 32
sw $ra, 0($sp)
sw $t0, 4($sp) # the size of the array
sw $t4, 8($sp) # the number 4
sw $t1, 12($sp) # temporary
sw $t2, 16($sp) # array original
sw $t3, 20($sp) # specific element
sw $s1, 24($sp) # copied array
sw $t5, 28($sp) # number to copy
la $a0, input
li $v0, 4
syscall
# get the size
li $v0, 5
syscall
move $t0, $v0
# allocate space for the array on the heap
li $t4, 4
mul $t1, $t0, $t4
li $v0, 9
move $a0, $t1
syscall
move $t2, $v0
li $s0, 0
la $a0, entries
li $v0, 4
syscall
read_array:
# read element
li $v0, 5
syscall
move $t3, $v0
# place in right address
mul $t1, $s0, $t4
add $t1, $t2, $t1
sw $t3, 0($t2)
addi $s0, $s0, 1
blt $s0, $t0, read_array
li $s0, 0
gnome_sort:
# allocate space on heap for copy
mul $t1, $t0, $t4
li $v0, 9
move $a0, $t1
syscall
move $s1, $v0
mul $s2, $t4, $t0
add $s3, $s1, $s2
copy_array:
lw $t5, 0($t2)
sw $t5, 0($s1)
add $t2, $t2, $t4
add $s1, $s1, $t4
blt $s1, $s3, copy_array
li $s0, 0
while_loop:
bgt $s0, $t0, finish_sort
beq $s0, $zero, increase_i
sw $s4, 0($s1)
sw $s5, -4($s1)
bge $s4, $s5, increase_i
j swap_elements
increase_i:
addi $s0, $s0, 1
j while_loop
swap_elements:
la $a0, input
li $v0, 4
syscall
sw $t6, 0($s1)
sw $t7, -4($s1)
lw $t7, 0($s1)
lw $t6, -4($s1)
subi $s0, $s0, 1
j while_loop
finish_sort:
li $s0, 0
la $a0, output
li $v0, 4
syscall
j print_original
print_original:
bge $s0, $t0, print_sorted
lw $s6, 0($t2)
li $v0, 1
move $a0, $s6
syscall
la $a0, space
li $v0, 4
syscall
addi $s0, $s0, 1
j print_original
print_sorted:
li $s0, 0
loop:
bge $s0, $t0, finish
lw $s6, 0($s1)
li $v0, 1
move $a0, $s6
syscall
la $a0, space
li $v0, 4
syscall
addi $s0, $s0, 1
j loop
finish:
li $v0, 10
syscall
After testing this in QTSpim, it seems that you're going out of allocated memory on the line sw $s4, 0($s1)
in the while_loop. This is because $s1 at that point is past the end of the second array you allocated. If you want to use that memory, you will have to syscall for it.
The way you copy the array using lw and sw is correct.

MIPS (arrays and loops)

so i am working on a project which asks the user for numbers (integers) and than rearranges them in ascending order and prints them out.
now i am stuck because i want to also print them in descending order but in a separate array with the same numbers. can anyone help me out?
this is my code so far for ascending numbers:
(btw the comments are just for my guiding)
.data
array1: .space 100
array2: .space 100
array3: .space 100
msg1: .asciiz "Enter at least 4 integers: Enter the number 500 to exit \n"
msg2: .asciiz "Numbers you entered are: \n"
msg3: .asciiz "The numbers you entered in ascending order are: \n"
commas: .asciiz ","
msg4: .asciiz "The numbers you entered in descending order are: \n"
.text
.globl main
main:
la $a1, array1 #load pointer to array1
la $a2, array2 ##load pointer to array2
la $a3, array3 #load pointer to array3
li $t1, 500 # once 500 is entered it will exit the input and produce an output
li $t0, 0
loopset:
la $a0, msg1 #loads msg1 text into $a
li $v0, 4 #loads 4 into $v0 (prints string)
syscall
li $v0, 5 #loads 5 into $v0 (read interger)
syscall
beq $v0,$t1,swap
addi $t0,$t0,4 #add 4 to $t0, save to $t0
sw $v0, ($a1) #stores input into array
addi $a1, $a1,4 #add 4 to $a1, save to $a1
j loopset
swap:
la $t4, array1 #loads array1 to $t4
la $t1, array1 #loads array1 to $t1
addi $t1, $t1, 4 #add 4 to $t1, save to $t1
la $t8, array1 #loads array to $t8
add $t8,$t0,$t8 #add $t8 to $t0, save to $t8
la $t9,array1 #loads array1 to $t9
add $t9, $t0, $t9 #add $t9 to $t0, save to $t9
addi $t9, $t9, -4 #subtracts 4 from $t9, save to $t9
loop1:
lw $t2, ($t4) #load input into $t2
lw $t3, ($t1) #load input into $t3
blt $t2, $t3, loop2 #if $t2 > $t3, go to loop2
sw $t3, ($t4) #store $t3 in $t4
sw $t2, ($t1) #store $t2 in $t1
loop2:
addi $t1, $t1, 4 #add 4 to $t1, save to $t1
blt $t1, $t8, loop1 #if $t1< $t8, go to loop1
addi $t4, $t4, 4 #add 4 to $t4, save to $t4
move $t1, $t4
addi $t1, $t1, 4 #add 4 to $t1, save to $t1
blt $t4, $t9, loop1 #if $t4 < $t9, to go loop1
print:
la $a1, array1 #loads array to $a1
la $a0, msg3 #loads msg3 to $a0
li $v0, 4
syscall
la $a0, array1 #loads array1 to $a0
li $v0, 4 #loads 4 into #v0
syscall
loop3:
blez $t0, EXIT #if $t0 <= 0, go to EXIT
li $v0, 1 #loads 1 into $v0
lw $a0, 0($a1) #load an input into $a0
syscall
la $a0, commas #loads commas into $a0
li $v0, 4 #loads 4 into $v0
syscall
addi $a1, $a1, 4 #add 4 to $a1, save to $a1
addi $t0, $t0, -4 #subtracts 4 from #t0, save to $t0
j loop3
EXIT:
li $v0,10 #exit
syscall
Try changing out all of the blt (branch less than) to bgt (branch greater than) and assuming your program works like it is supposed to you should get an array in descending order. If you want it in a different array for the descending order you will need to copy your loop1, loop2, loop3, and print and change their names switching out the blt calls for bgt calls.

Resources