# Multiply Two Random Matrices And Then Find Sum, Min And Max Value In The Product Matrix Assignment Solution.

## Instructions

Objective
Write a program to multiply two random matrices and then find sum, min and max value in the product matrix.

## Requirements and Specifications

The two operand matrices will be implemented as a single 2D array. Each cell in this array is a structure of two values: x and y. Hence, we have an x and a y matrix. This 2D array is NN, where N is specified by the user through the command prompt. The matrices are randomly populated with integers less than or equal to 100.
First, the 2D matrix with each cell is printed with a pair of values "(X,y)". Then, display the x matrix and the y matrix separately.
Second, calculate the multiplication of matrix x and y and store the product (x*y) matrix in a new 2D array.
Display the product matrix.
Third, Calculate the sum, max, and min values in the product matrix and store the values in a structure.
Finally display the summary structure.
Screenshots of output

Source Code
.equ      pos_x, 0     // position of the x field in structure
.equ      pos_y, 4    // position of the y field in structure
.equ     st_sum, 0    // position of the sum in structure
.equ      st_max, 4    // position of the max in structure
.equ      st_min, 8    // position of the min in structure
.data
num:      .word 0 // variable to save read N
struct:      .space 16     // allocate space for result structure
.section .rodata
prompt:      .string "Matrix dimension N?: "
nerror:     .string "Error: N must be positive\n"
memerror:      .string "Error: out of memory\n"
matrixmsg:      .string "\nMatrix contents:\n"
matxmsg:     .string "Matrix X contents:\n"
matymsg:     .string "Matrix Y contents:\n"
mulmsg:      .string "Result of multiplication X*Y:\n"
summsg:     .string "X*Y sum: %d\n"
maxmsg:      .string "X*Y max: %d\n"
minmsg:     .string "X*Y min: %d\n"
intfmt:      .string "%d"
mat2fmt:      .string "(%d,%d) "
mat1fmt:      .string "%d "
nline:     .string "\n"
.text
// Main function
.type main,%function
.global main
main:
stp x29, x30, [sp, -16]!      // save fp and lr in stack
// initialize random seed
mov w0, wzr     // load zero in afunction argument
bl time     // call time(0)
bl srand     // call srand(time(0)) to initialize random seed
bl printf // print prompt string
ldr x1, =num      // read in variable
bl scanf     // read the input number
ldr w19, [x1]      // load variable value
cmp w19, 0     // see if it's a valid number
ble badinput // if not, print error
// create new matrix of structures (x,y)
mov w0, w19     // copy read N
mul w0, w0, w19     // N*N
lsl w0, w0, 3      // multiply N*N by 8, the size of one structure
bl malloc      // allocate space in heap
cmp x0, 0     // if error allocating
beq outmem     // print error
mov x20, x0     // save allocated memory pointer in x20
// fill x,y maxtrix with random values
mov x21, 0     // i = 0
fori1:
mov x22, 0     // j = 0
forj1:
mul x0, x21, x19     // i*N
lsl x0, x0, 3      // (i*N + j) * (size of structure = 8)
bl generate_num      // generate random number
str w0, [x23, pos_x]     // save in position x
bl generate_num     // generate random number
str w0, [x23, pos_y]      // save in position y
add x22, x22, 1      // increment j
cmp w22, w19      // if j
blt forj1      // repeat
add x21, x21, 1      // increment i
cmp w21, w19      // if i
blt fori1     // repeat
bl printf      // print string
// print x,y matrix
mov x21, 0     // i = 0
fori2:
mov x22, 0     // j = 0
forj2:
mul x0, x21, x19      // i*N
lsl x0, x0, 3      // (i*N + j) * (size of structure = 8)
ldr w1, [x23, pos_x]     // load x
ldr w2, [x23, pos_y]     // load y
ldr x0, =mat2fmt     // load format to print a matrix element
bl printf      // print matrix element
add x22, x22, 1     // increment j
cmp w22, w19     // if j
blt forj2      // repeat
ldr x0, =nline      // load format to print a newline
bl printf     // print newline
add x21, x21, 1     // increment i
cmp w21, w19     // if i
blt fori2     // repeat
ldr x0, =nline      // load format to print a newline
bl printf      // print newline
bl printf     // print string
// print x matrix
mov x21, 0      // i = 0
fori3:
mov x22, 0      // j = 0
forj3:
mul x0, x21, x19     // i*N
lsl x0, x0, 3      // (i*N + j) * (size of structure = 8)
ldr w1, [x23, pos_x]      // load x
ldr x0, =mat1fmt     // load format to print a matrix element
bl printf     // print matrix element
add x22, x22, 1      // increment j
cmp w22, w19     // if j
blt forj3      // repeat
ldr x0, =nline     // load format to print a newline
bl printf      // print newline
add x21, x21, 1      // increment i
cmp w21, w19      // if i
blt fori3      // repeat
ldr x0, =nline      // load format to print a newline
bl printf     // print newline
bl printf      // print string
// print y matrix
mov x21, 0     // i = 0
fori4:
mov x22, 0     // j = 0
forj4:
mul x0, x21, x19     // i*N
lsl x0, x0, 3     // (i*N + j) * (size of structure = 8)
ldr w1, [x23, pos_y]      // load y
ldr x0, =mat1fmt     // load format to print a matrix element
bl printf     // print matrix element
add x22, x22, 1 // increment j
cmp w22, w19      // if j
blt forj4     // repeat
ldr x0, =nline      // load format to print a newline
bl printf     // print newline
add x21, x21, 1      // increment i
cmp w21, w19      // if i
blt fori4      // repeat
ldr x0, =nline     // load format to print a newline
bl printf      // print newline
// create new matrix to hold product
mul w0, w19, w19      // N*N
lsl w0, w0, 2      // multiply N*N by 4, the size of one word
bl malloc      // allocate space in heap
cmp x0, 0      // if error allocating
beq outmem      // print error
mov x24, x0      // save pointer
// calculate product x*y
mov x1, 0      // i = 0
fori5:
mov x2, 0     // j = 0
forj5:
mov w7, 0      // sum = 0
mov x3, 0     // k = 0
fork5:
mul x4, x1, x19      // i*N
lsl x4, x4, 3      // (i*N + k) * (size of structure = 8)
ldr w5, [x4, pos_x]     // load x
mul x4, x3, x19      // k*N
lsl x4, x4, 3      // (k*N + j) * (size of structure = 8)
ldr w6, [x4, pos_y]     // load y
mul w4, w5, w6      // x[i][k] * y[k][j]
add w7, w7, w4      // sum += x[i][k] * y[k][j]
add x3, x3, 1      // increment k
cmp w3, w19      // if k
blt fork5      // repeat
mul x4, x1, x19      // i*N
lsl x4, x4, 2     // (i*N + j) * (size of array element = 4)
str w7, [x4]      // save multiplication result
add x2, x2, 1      // increment j
cmp w2, w19      // if j
blt forj5      // repeat
add x1, x1, 1      // increment i
cmp w1, w19      // if i
blt fori5      // repeat
bl printf     // print string
// print multiplication result
mov x21, 0     // i = 0
fori6:
mov x22, 0     // j = 0
forj6:
mul x0, x21, x19      // i*N
lsl x0, x0, 2      // (i*N + j) * (size of element = 4)
ldr w1, [x0]     // load arr[i][j]
ldr x0, =mat1fmt      // load format to print a matrix element
bl printf      // print matrix element
add x22, x22, 1     // increment j
cmp w22, w19     // if j
blt forj6      // repeat
ldr x0, =nline      // load format to print a newline
bl printf      // print newline
add x21, x21, 1      // increment i
cmp w21, w19      // if i
blt fori6      // repeat
ldr x0, =nline      // load format to print a newline
bl printf      // print newline
// calculate sum, max and min and save in structure
mov w4, 0      // sum = 0
ldr w5, [x24]      // max = first element
ldr w6, [x24]      // min = first element
ldr x7, =struct      // point to start of structure
str w4, [x7, st_sum]     // save initial sum
str w5, [x7, st_max]      // save initial max
str w6, [x7, st_min]     // save initial min
mov x1, 0      // i = 0
fori7:
mov x2, 0     // j = 0
forj7:
mul x3, x1, x19      // i*N
lsl x3, x3, 2     // (i*N + j) * (size of array element = 4)
ldr x7, =struct      // point to start of structure
ldr w4, [x7, st_sum]     // load sum
ldr w5, [x7, st_max]      // load max
ldr w6, [x7, st_min]      // load min
ldr w0, [x3]      // load multiplication element [i][j]
add w4, w4, w0     // sum += mul[i][j]
cmp w0, w5      // compare with max
ble chkmin      // if <= max, check minimum
mov w5, w0     // else, set as maximum
b skip
chkmin:
cmp w0, w6     // compare with min
bge skip     // if >= min, skip
mov w6, w0 // else, set as minimum
skip:
str w4, [x7, st_sum]        // save sum
str w5, [x7, st_max]      // save max
str w6, [x7, st_min]     // save min
add x2, x2, 1          // increment j
cmp w2, w19      // if j
blt forj7     // repeat
add x1, x1, 1     // increment i
cmp w1, w19      // if i
blt fori7     // repeat
// print results
ldr x2, =struct      // point to start of structure
ldr w1, [x2, st_sum]     // load sum result
bl printf     // print string
ldr x2, =struct      // point to start of structure
ldr w1, [x2, st_max]     // load max result
bl printf      // print string
ldr x2, =struct      // point to start of structure
ldr w1, [x2, st_min]      // load min result
bl printf      // print string
// delete the created matrices
mov x0, x24     // load multiplication array pointer
bl free      // free all allocated memory
mov x0, x20      // load array pointer
bl free      // free all allocated memory
b return     // terminate program
bl printf          // print error string
b return          // terminate program
outmem:
bl printf      // print error string
return:
mov w0, wzr      // return 0
ldp x29, x30, [sp], 16     // load fp and lr from stack
.size main, (. - main)
// Function to generate a number between 1 and 100
// Returns w0 = random number
.type generate_num, %function
generate_num:
stp x29, x30, [sp, -16]!      // save fp and lr in stack
bl rand      // generate random number
mov w1, 100      // load 100 to make division
udiv w2, w0, w1      // divide random num by 100 to get remainder 0
msub w0, w2, w1, w0     // get remainder = randnum - quotient*100
add w0, w0, 1     // get number 1<=x<=100
ldp x29, x30, [sp], 16      // load fp and lr from stack
ret      // return
.size generate_num, (. - generate_num)