1
\$\begingroup\$

This MIPS Assembly program will make you access the elements in the 4x4 matrix in either row or column-major order i.e. accessing all elements row by row or column by column.

Output is posted below as well.

Data section has variables declared, Text section has the main function.

This took me several days to put together since I just started this from scratch. I'll appreciate any feedback. I also hope this helps out those who are looking to to some matrix calculations and such.

# Data Section
.data
    .globl array

    .align 4
    array: .float 1.00, 2.00, 3.00, 4.00, 5.00, 6.00, 7.00, 8.00, 9.00, 10.00, 11.00, 12.00, 13.00, 14.00, 15.00, 16.00

    matrix_size: .word 4 
    float_size: .word 4

    lb_:    .asciiz "Print in row or column-major order\n" #uncomment a line in ADDING OFFSET section to change which to print (can't print both at the same time!)

    j_:     .asciiz "j: "
    k_:     .asciiz " k: "
    bar_:   .asciiz " | "
    colon:  .asciiz ": "
    lineBrk: .asciiz "\n"

    # MIPS Printing Syntax
    # li $v0  n     # n = 1:(print_integer), 2:(print_float), 4:(print_str)
    # la $a0 text_  # text_ should be defined in the .data section above beforehand
    # syscall


# Text Section
.text
    .globl main
main:
    #Print title
    li $v0 4    
    la $a0 lb_
    syscall

    la $a1 array 
    move $s7 $a1 # base address of array

    lw $s1 matrix_size # $s1 = matrix_size
    lw $s2 float_size # $s2 = float_size


li $t5 0 # j counter
jloop:
    li $t6 0 # k counter
    # j kloop
        kloop:
            #Print j and k value
            #j: t5 
            #k: t6

            li $v0 4        # "j"
            la $a0 j_
            syscall

            li $v0 1 
            move $a0 $t5
            syscall         # value_j


            li $v0 4        # "k"
            la $a0 k_
            syscall

            li $v0 1 
            move $a0 $t6
            syscall         # value_k

            li $v0 4        # " | "
            la $a0 bar_
            syscall 

        ## Caculate column major offset
                # $s0 = offset result
                # $s1 = matrix_size: 4
                # $s2 = float_size: 4
                # $s7 = base address stored
                # $t5 = j
                # $t6 = k

                # offset = 4*(4*k + j) = float_size * (matrix_size*k + j)

            mul $s0 $s1 $t6 # s0 = 4*k
            add $s0 $s0 $t5 # s0 = s0 + j
            mul $s0 $s0 $s2 # s0 = 4*s0, offset stored in s0


            # print( offset: )
            li $v0 1
            move $a0 $s0
            syscall

            li $v0 4    
            la $a0 colon
            syscall


        #### ADDING OFFSET ####

            # This will increase the memory address. It's like increasing the index for accessing next element. 
            # addi $a1 $a1 4    #row major    -> new_addr += 4  (cumulatively increase the address to access the array by 4)
            add $a1 $s7 $s0     #column major -> new addr = base_addr + offset

            # print( element\n )
            lwc1 $f12 0($a1)
            li $v0 2    
            syscall 

            li $v0 4    
            la $a0 lineBrk
            syscall 

            # k_counter++
            addi $t6 $t6 1 
            bne $t6 $s1 kloop

    # j_counter++
    addi $t5 $t5 1 
    bne $t5 $s1 jloop


#Done, terminate program
    li $v0, 10
        syscall

.end main

Output: #0,16,32.. etc. are the offset added to the base address

it is in multiple of 4 since floats are 4 bytes

enter image description here

\$\endgroup\$
  • \$\begingroup\$ I know the mods are going to yell at me again, but since I (still) don't speak MIPS, I can only ask questions, not make recommendations. So: Why does it look like you are declaring array 3 times? If those other 2 are commented out (as they appear), remove them before asking for a CR. It appears that matrix_size and float_size are declared as variables instead of equ? Does it make sense to do j kloop when the next line is kloop? Why does your comment say "j" when you are printing k? Add " " to k_ to avoid extra print? Oops I'm out of sp \$\endgroup\$ – David Wohlferd Jul 5 '18 at 6:43
  • \$\begingroup\$ @DavidWohlferd Thank you very much. 1) For the array, they are comments to just help me understand. I should get rid of them or call the actual array being used differently yes. 2) I did not know about .equ at all. I've only did this for 5 days now. 3) Somehow I thought I had to specify in Assembly to enter a loop but i guess you don't have to! It still runs fine 4) fixed the typo in the comment, and yes I can just simply add space " " instead of making a character... thank you \$\endgroup\$ – Leonard Jul 5 '18 at 8:17
  • \$\begingroup\$ MARS/SPIM has .eqv I believe, .equ is ignored (and overall the MARS/SPIM assembler parser is quite crude, I think it can't evaluate any expression (like .eqv zzz 5*30 ... or if it works in eqv, then surely it does not in lw argument), etc.. which makes some things a bit painful, when one is used to modern powerful assembler from other platforms. \$\endgroup\$ – Ped7g Jul 5 '18 at 8:28
  • \$\begingroup\$ I see. Well I'll stick to lw for now. I almost got the multiplication working except it doesn't update the index of array2 properly. I'm almost there... codeshare.io/5e3AQK \$\endgroup\$ – Leonard Jul 5 '18 at 8:35
  • \$\begingroup\$ This is really stressing me out :( I don’t know why it is printing out wrong things... Could you please take a look? @Ped7g. I updated the above link in the comment \$\endgroup\$ – Leonard Jul 5 '18 at 9:15

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Browse other questions tagged or ask your own question.