For the assignment I am doing for my Computer Orgainzation and Assembly class, we are to print a given array, using the selection sort. Then, for bonus points, we are to print the array after it is sorted 5 per line. I am stuck on this part. My codes sorts the array, but I don't know how to get it to print 5 per line. Can anyone help?

    .data
size: .word  20
array:  .word  99,23,45,42,09,34,71,64,88,42,12,37,33,36,83,78,17,04,52,46
before: .asciiz "Before sort:\n"
space:  .asciiz " "
after:  .asciiz "\n\nAfter Sort\n"
newLine: .asciiz "\n"

    .text
    .globl main

main:   li  $v0, 4      # system call
    la  $a0, before # to print before string
    syscall         

    jal print       # subroutine prints all elements in array 


    li      $t5, 0      # t5 is k = 0

    la      $t7, size     
        lw      $t7, 0($t7)     # t7 = size

    addi    $t8, $t7, -1    # t8 = size - 1
    la  $t6, array  # t6 = address of the array

outer: slt  $t0, $t5, $t8   # if k < size - 1  t0 = 1
    beq $t0, $zero, endOuter # k >= (size - 1)
    add $t9, $zero, $t5 # t9 is min = k

    addi    $t1, $t5, 1     # t1 is j = k + 1

inner: slt  $t0, $t1, $t7   # if j < size t0 = 1
    beq $t0, $zero, endInner

    add $s3, $t9, $t9   # s3 = 2 * min
    add $s3, $s3, $s3   # s3 = 4 * min
    add $s3, $t6, $s3   # s3 is address of list[min]
    lw  $t2, 0($s3)     # t2 is list[min]

    add $s0, $t1, $t1   # s0 = 2 * j
    add $s0, $s0, $s0   # s0 = 4 * j
    add $s0, $t6, $s0   # s0 is address of list[j]
    lw  $t3, 0($s0)     # t3 is list[j]

    slt $t0, $t3, $t2   # if list[j] < list[min] t0 = 1
    beq $t0, $zero, secondIF # skip min = j & ++j and jump to secondIF
    add     $t9, $zero, $t1 # min = j
    j secondIF

secondIF: beq   $t9, $t5, incrementJ # if min != k swap, else goto incrementJ

    # BEGIN SWAP :
    add $s0, $t9, $t9   # s0 = 2 * min
    add $s0, $s0, $s0   # s0 = 4 * min
    add $s0, $s0, $t6   # s0 = address of list[min]
    lw  $t4, 0($s0)     # t4 is temp = list[min]


    add $s1, $t5, $t5   # s1 = 2 * k
    add $s1, $s1, $s1   # s1 = 4 * k
    add $s1, $t6, $s1   # s1 = address of list[k]
    lw  $s3, 0($s1)     # s3 = list[k]


    sw  $s3, 0($s0)     # list[min] = list[k]

    sw  $t4, 0($s1)     # list[k] = temp 
    addi    $t1, $t1, 1 # ++j
    add $t9, $zero, $t5 # t9 is min = k  
    # END SWAP

    j inner 

incrementJ: addi $t1, $t1, 1    # ++j
    j inner

endInner: addi $t5, $t5, 1 # ++k
    j outer


endOuter: li $v0, 4 # system call
    la  $a0, after  # to print after string
    syscall         

    jal print       # subroutine prints all elements in array 
    j exitProgram           

print:  li  $t5, 0      # k = 0
    la  $t6, array  # t6 = address of the array
    la      $t7, size    
        lw      $t7, 0($t7)     # t7 = size 

loop:   slt $t0, $t5, $t7   # if k < size t0=1
    beq $t0, $0, printExit  # if k >= 10 exit

    li  $v0, 1      # print an integer
    lw  $a0, 0($t6) # address of integer in a0
    syscall

    addi    $t6, $t6, 4 # increment address of array by 4(next int)
    addi    $t5, $t5,1  # k++

    li  $v0, 4      # print a newline after each int
    la  $a0, space  # address of space string
    syscall

    j   loop

printExit: jr   $ra

exitProgram:    li $v0, 10  # system call to
    syscall         # terminate program

Could you please tell us what system or emulator you are using? There are small but sometimes important differences in the way different emulators (e.g., SPIM, MARS) work, especially in terms of the assembly directives they accept, and it may be relevant. For now, I'll assume you are using SPIM, but if you are using a different one such as MARS or MIPSym, or an actual hardware MIPS system such as a Playstation 2, please let us know.

As for how to print exactly five values per line, there are two simple solutions: first you can have an inner loop with a counter variable, which would repeat five times. The psuedo-code for this would be something like:

a = your array
p = pointer to a
x = 10
while x != 0
    y = 5
    while y != 0
        print 0(p)
        p += 4
        y--
    end while

    print newline
    x--
end while

The other solution is to simply unroll the loop, and have one loop which hs five print operations:

a = your array
p = pointer to a
x = 2
while x != 0
    print 0(p)
    p += 4
    print 0(p)
    p += 4
    print 0(p)
    p += 4
    print 0(p)
    p += 4
    print 0(p)
    p += 4
    print newline
    x--
end while    

On a guess, the first is what you instructor is looking for.

I am running the code on both Mars and Spim. It works on both of them, and displays the array after sorting. I'm just trying to get it to print 5 numbers per line after it sorts.

OK, I'm going to break the usual rules regarding how much we can do, but I have a reason for doing so. I worked out a solution for the problem, but the code I wrote involes using some techniques you are almost certainly unaware of at this time. The main things I have done are A) moved the function(s) past the end of the main code, so that they ae no longer embedded in the program; B) re-written the print function as two functions, one of which, print_array, calls the second, print_array_line; C) used parameter passing in the functions to make them more general and modular; and D) applied stack discipline to hold an activation record for the print_array function. I have also used a few features of SPIM which are not supported by MARS, but changing the code to work in MARS is simply a matter of replacing the symbolic constants with the equivalent literals. The SPIM=specific version should be a good deal easier to read, but the MARS version should work in both emulators.

    .data

#stack offsets
fp.ra = 4
fp.a0 = 8
fp.a1 = 12
fp.a2 = 16
fp.a3 = 20
fp.s0 = -4
fp.s1 = -8
fp.s2 = -12
fp.s3 = -16
fp.s4 = -20
fp.s5 = -24
fp.s6 = -28
fp.s7 = -32
################################################################################
#System calls
print_int   = 01 #$a0  = integer
print_float = 02 #$f12 = float
print_double= 03 #$f12 = double
print_string= 04 #$a0  = string
read_int    = 05 #returns integer in $v0
read_float  = 06 #returns float   in $f0
read_double = 07 #returns double  in $f0
read_string = 08 #$a0 = buffer, $a1 = length
malloc      = 09 #$a0 = size of request returns pointer in $v0
Exit        = 10
print_char  = 11 #$a0 = char
read_char   = 12 #returns char (in $v0)
open        = 13 #$a0 = filename (string), $a1 =flags, $a2 = mode 0=read 1= wr 2=rw 8=append
                 #         returns file descriptor (in $v0)
read        = 14 #$a0 = file descriptor, $a1 = buffer, $a2 = length
                 #         returns num chars read (in $v0 )
write       = 15 #$a0 = file descriptor, $a1 = buffer,$a2 = length
                 #         returns num chars written (in $v0 )
close       = 16 #$a0 = file descriptor
exit2       = 17 #$a0 = result    


array:    .word   99,23,45,42,09,34,71,64,88,42,12,37,33,36,83,78,17,04,52,46
arrayend: .word   0
size:     .word   (arrayend - array) / 4

before:   .asciiz "Before sort:\n"
space:    .asciiz " "
after:    .asciiz "\n\nAfter Sort\n"
newline:  .asciiz "\n"

    .text
    .globl main

main:   
    li  $v0, print_string           # system call
    la  $a0, before                 # to print before string
    syscall         

    la $a0, array
    la $t0, size
    lw $a1, 0($t0)
    li $a2, 5
    jal print_array                 # subroutine prints all elements in array 

    li $t5, 0                       # t5 is k = 0

    la $t7, size     
    lw $t7, 0($t7)                  # t7 = size

    addi $t8, $t7, -1                # t8 = size - 1
    la $t6, array                    # t6 = address of the array

outer: 
    slt $t0, $t5, $t8  A              # if k < size - 1  t0 = 1
    beq $t0, $zero, endOuter         # k >= (size - 1)
    add $t9, $zero, $t5              # t9 is min = k

    addi    $t1, $t5, 1              # t1 is j = k + 1

inner:
    slt  $t0, $t1, $t7               # if j < size t0 = 1
    beq $t0, $zero, endInner

    add $s3, $t9, $t9                # s3 = 2 * min
    add $s3, $s3, $s3                # s3 = 4 * min
    add $s3, $t6, $s3                # s3 is address of list[min]
    lw  $t2, 0($s3)                  # t2 is list[min]

    add $s0, $t1, $t1                # s0 = 2 * j
    add $s0, $s0, $s0                # s0 = 4 * j
    add $s0, $t6, $s0                # s0 is address of list[j]
    lw  $t3, 0($s0)                  # t3 is list[j]

    slt $t0, $t3, $t2                # if list[j] < list[min] t0 = 1
    beq $t0, $zero, secondIF         # skip min = j & ++j and jump to secondIF
    add $t9, $zero, $t1              # min = j
    j secondIF

secondIF: 
    beq $t9, $t5, incrementJ         # if min != k swap, else goto incrementJ

    # BEGIN SWAP :
    add $s0, $t9, $t9                # s0 = 2 * min
    add $s0, $s0, $s0                # s0 = 4 * min
    add $s0, $s0, $t6                # s0 = address of list[min]
    lw  $t4, 0($s0)                  # t4 is temp = list[min]


    add $s1, $t5, $t5                # s1 = 2 * k
    add $s1, $s1, $s1                # s1 = 4 * k
    add $s1, $t6, $s1                # s1 = address of list[k]
    lw  $s3, 0($s1)                  # s3 = list[k]


    sw  $s3, 0($s0)                  # list[min] = list[k]

    sw  $t4, 0($s1)                  # list[k] = temp 
    addi    $t1, $t1, 1              # ++j
    add $t9, $zero, $t5              # t9 is min = k  
    # END SWAP

    j inner 

incrementJ: 
    addi $t1, $t1, 1                 # ++j
    j inner

endInner:
    addi $t5, $t5, 1                 # ++k
    j outer

endOuter: 
    li $v0, print_string             # system call
    la  $a0, after                   # to print after string
    syscall         

    la $a0, array
    la $t0, size
    lw $a1, 0($t0)
    li $a2, 5    
    jal print_array                  # subroutine prints all elements in array 

exitProgram:    
    li $v0, Exit                     # system call to
    syscall                          # terminate program


########################################################
## int* print_array(int* a0, int a1, int a2)
print_array:
    addi $sp, $sp, -24
    sw $fp, 8($sp)
    addi $fp, $sp, 16
    sw $ra, fp.ra($fp)
    sw $s0, fp.s0($fp)
    sw $s1, fp.s1($fp)
    sw $s2, fp.s2($fp)
    sw $s3, fp.s3($fp)

    div $a1, $a2 
    move $s0, $a0                    # s0 = address of the array
    move $s1, $a2    
    mflo $s2                         # s2 = the num of full lines to print 
    mfhi $s3                         # s3 = the size of the final line

    j print_array.mainloop_end

print_array.mainloop:
    move $a0, $s0
    move $a1, $s1
    jal print_array_line
    move $s0, $v0
    addi $s2, $s2, -1
print_array.mainloop_end:
    bnez $s2, print_array.mainloop   # if k > 0 continue

    beqz $s3, print_array.exit       # if there are no more to print, stop
    move $a0, $s0                    # else print the remaining integers
    move $a1, $s3
    jal print_array_line    

print_array.exit:
    lw $s3, fp.s3($fp)
    lw $s2, fp.s2($fp)
    lw $s1, fp.s1($fp)
    lw $s0, fp.s0($fp)
    lw $ra, fp.ra($fp) 
    lw $fp, 8($sp)
    addi $sp, $sp, 24    
    jr $ra


########################################################
## int* print_array _line(int* a0, int a1) 
print_array_line:
    move $t0, $a0
    move $t1, $a1

    j print_array_line.loop_end

print_array_line.loop:    
    li  $v0, print_int               # print an integer
    lw  $a0, 0($t0)                  # address of integer in a0 
    syscall

    li  $v0, print_string            # print a space after each int
    la  $a0, space                   # address of space string
    syscall    

    addi $t0, $t0, 4                 # increment address of array by 4(next int)
    addi $t1, $t1, -1                # decrement the loop index
print_array_line.loop_end:
    bnez $t1, print_array_line.loop

    li  $v0, print_string            # print a newline after each line
    la  $a0, newline                 # address of newline string
    syscall

print_array_line.exit: 
    move $v0, $t0
    jr   $ra

I do recommend that you go over the new code carefully, and familiarize yourself with what I did and how it works. If you have any questions, especially regarding the activation record, feel free to ask.

Edited 2 Years Ago by Schol-R-LEA

This question has already been answered. Start a new discussion instead.