Academic Integrity: tutoring, explanations, and feedback — we don’t complete graded work or submit on a student’s behalf.

MIPS Assignment - Matrix Multiply Part 1: Write a program that inputs a 4x4 matr

ID: 3848893 • Letter: M

Question

MIPS Assignment - Matrix Multiply

Part 1:

Write a program that inputs a 4x4 matrix of single-digit integers one row at a time (one row per input line – not one number per line!) and stores it into a linear 32-bit Integer Array M (so called Row-Major order). It is not completely trivial to do this given the Syscalls available and the desired input format. Hint: Format conversion will be required (do not use syscalls for the format conversion, just use loads, math, and stores).

Print the matrix back out with each row on a separate line and the values separated by spaces.Make this program a procedure so that you can use it again in later labs. For now, you can call it from a very simple main routine that just calls the routine.When you run the program, the input should look something like

Input row 1: 1 4 3 2

Input row 2: 5 7 6 8

Input row 3: 9 1 2 3

Input row 4: 4 5 6 7

Where the integers 1 2 3 4 … 8 9 or whatever matrix values the user wants to input are input by the user on the “console.”

And the output will look like

Row 1: 1 4 3 2

Row 2: 5 7 6 8

Row 3: 9 1 2 3

Row 4: 4 5 6 7

Part 2 :

First, recall how matrices are multiplied. http://www.mathsisfun.com/algebra/matrix-multiplying.html

Given the 32x32 matrices:

C code:

void mm (double x[][], double y[][], double z[][]) {

int i, j, k;

for (i = 0; i! = 32; i = i + 1)

for (j = 0; j! = 32; j = j + 1)

for (k = 0; k! = 32; k = k + 1)

x[i][j] = x[i][j]+ y[i][k] * z[k][j];

}

Addresses of x, y, z in $a0, $a1, $a2, and i, j, k in $s0, $s1, $s2

MIPS code:

li $t1, 32       # $t1 = 32 (row size/loop end)

li $s0, 0        # i = 0; initialize 1st for loop

L1: li $s1, 0        # j = 0; restart 2nd for loop

L2: li $s2, 0        # k = 0; restart 3rd for loop

sll $t2, $s0, 5   # $t2 = i * 32 (size of row of x)

addu $t2, $t2, $s1 # $t2 = i * size(row) + j

sll $t2, $t2, 3   # $t2 = byte offset of [i][j]

addu $t2, $a0, $t2 # $t2 = byte address of x[i][j]

l.d $f4, 0($t2)   # $f4 = 8 bytes of x[i][j]

L3: sll $t0, $s2, 5   # $t0 = k * 32 (size of row of z)

addu $t0, $t0, $s1 # $t0 = k * size(row) + j

sll $t0, $t0, 3   # $t0 = byte offset of [k][j]

addu $t0, $a2, $t0 # $t0 = byte address of z[k][j]

l.d $f16, 0($t0) # $f16 = 8 bytes of z[k][j]

sll $t0, $s0, 5       # $t0 = i*32 (size of row of y)

addu $t0, $t0, $s2    # $t0 = i*size(row) + k

sll   $t0, $t0, 3      # $t0 = byte offset of [i][k]

addu $t0, $a1, $t0    # $t0 = byte address of y[i][k]

l.d   $f18, 0($t0)     # $f18 = 8 bytes of y[i][k]

mul.d $f16, $f18, $f16 # $f16 = y[i][k] * z[k][j]

add.d $f4, $f4, $f16   # f4=x[i][j] + y[i][k]*z[k][j]

addiu $s2, $s2, 1      # $k k + 1

bne   $s2, $t1, L3     # if (k != 32) go to L3

s.d   $f4, 0($t2)      # x[i][j] = $f4

addiu $s1, $s1, 1      # $j = j + 1

bne   $s1, $t1, L2     # if (j != 32) go to L2

addiu $s0, $s0, 1      # $i = i + 1

bne   $s0, $t1, L1     # if (i != 32) go to L1

Now, convert the matrix multiply to a program that multiplies 4x4 integer matrices instead of 32x32 floating-point matrices (replace all the floating-pointloads, stores, and operations with their integer equivalents, e.g., l.d becomes lw etc.).Modify your program from Part 1 that reads in a 4x4 integer matrix to allow the user toinput two 4x4 matrices by row, then multiply the integer matrices and print out the results by row.

Explanation / Answer

Part 1:

Coding: MIPS

     .file     "main.c"

     .section .rodata

.LC0:

     .string   "Input row %d: "

.LC1:

     .string   "%d"

.LC2:

     .string   " Row %d:"

.LC3:

     .string   " %d"

     .text

     .globl    main

     .type     main, @function

main:

.LFB0:

     .cfi_startproc

     pushq     %rbp

     .cfi_def_cfa_offset 16

     .cfi_offset 6, -16

     movq %rsp, %rbp

     .cfi_def_cfa_register 6

     subq $80, %rsp

     movl $0, -4(%rbp)

     jmp .L2

.L4:

     movl -4(%rbp), %eax

     andl $3, %eax

     testl     %eax, %eax

     jne .L3

     movl -4(%rbp), %eax

     leal 3(%rax), %edx

     testl     %eax, %eax

     cmovs     %edx, %eax

     sarl $2, %eax

     addl $1, %eax

     movl %eax, %esi

     movl $.LC0, %edi

     movl $0, %eax

     call printf

.L3:

     leaq -80(%rbp), %rax

     movl -4(%rbp), %edx

     movslq    %edx, %rdx

     salq $2, %rdx

     addq %rdx, %rax

     movq %rax, %rsi

     movl $.LC1, %edi

     movl $0, %eax

     call __isoc99_scanf

     addl $1, -4(%rbp)

.L2:

     cmpl $15, -4(%rbp)

     jle .L4

     movl $0, -4(%rbp)

     jmp .L5

.L7:

     movl -4(%rbp), %eax

     andl $3, %eax

     testl     %eax, %eax

     jne .L6

     movl -4(%rbp), %eax

     leal 3(%rax), %edx

     testl     %eax, %eax

     cmovs     %edx, %eax

     sarl $2, %eax

     addl $1, %eax

     movl %eax, %esi

     movl $.LC2, %edi

     movl $0, %eax

     call printf

.L6:

     movl -4(%rbp), %eax

     cltq

     movl -80(%rbp,%rax,4), %eax

     movl %eax, %esi

     movl $.LC3, %edi

     movl $0, %eax

     call printf

     addl $1, -4(%rbp)

.L5:

     cmpl $15, -4(%rbp)

     jle .L7

     movl $10, %edi

     call putchar

     leave

     .cfi_def_cfa 7, 8

     ret

     .cfi_endproc

.LFE0:

     .size     main, .-main

     .ident    "GCC: (GNU) 4.8.5 20150623 (Red Hat 4.8.5-4)"

     .section .note.GNU-stack,"",@progbits

Coding: C

#include <stdio.h>

int main()

{

    int array[4*4];

    int i;

    for (i=0; i<16; i++) {

        if (i%4 == 0) printf ("Input row %d: ", (i/4)+1);

        scanf("%d", &array[i]);

    }

    for (i=0; i<16; i++) {

        if (i%4 == 0) printf (" Row %d:", (i/4)+1);

        printf(" %d", array[i]);

    }

    printf(" ");

}

Hire Me For All Your Tutoring Needs
Integrity-first tutoring: clear explanations, guidance, and feedback.
Chat Now And Get Quote