×
Samples Blogs Make Payment About Us Reviews 4.9/5 Order Now

Transform Matrix In MIPS Assembly Language Assignment Solution

July 09, 2024
Rehana Magnus
Rehana Magnus
🇨🇦 Canada
Assembly Language
Rehana Magnus, PhD in Computer Science from the esteemed Acadia Institute of Technology, Canada. With 6 years of experience, specializes in assembly language programming. Proficient in low-level coding, optimizing performance, and enhancing system functionality.
Key Topics
  • Instructions
  • Requirements and Specifications
Tip of the day
Use Python libraries effectively by importing only what you need. For example, if you're working with data, using libraries like pandas and numpy can save time and simplify complex tasks like data manipulation and analysis.
News
In 2024, the Biden-Harris Administration has expanded high-dosage tutoring and extended learning programs to boost academic achievement, helping programming students and others recover from pandemic-related setbacks. These initiatives are funded by federal resources aimed at improving math and literacy skills​

Instructions

Objective

Write a MIPS assignment program in assembly language to transform matrices.

Requirements and Specifications

### Part 1 -- Initialize Data Structure

**int initialize(char\* filename, Buffer\* buffer)**

This function takes two arguments -- a string *filename* and the address of a data structure *buffer* (as defined above). The function will read the content in *filename*, parse it and store the contents in *buffer*. The contents in *buffer* should be in the format defined for the data structure above. So, the first two elements should be the no. of rows and columns of a matrix and the remaining elements should be the integers of the matrix. One way to do this is to read the file one character at a time, and store them in the buffer as integers in appropriate positions.

If the file is read without any errors and the buffer is initialized properly, then the function should return 1 in *$v0*.

The function should return -1 in *$v0* if an error occurs during initialization. When this happens the *buffer* data structure should remain unchanged. You should assume the buffer contains all zeros before initialization. 

Initialization errors can occur due to the following reasons:

  • File I/O error.
  • The first two lines are not [1-10].
  • The file has more than X lines (excluding the first two lines), where X is the no. of rows in the first line.
  • The file has more than Y columns (excluding the first two lines), where Y is the no. of columns in the second line.
  • Lines 3 and after have non-numeric characters.
  • Numbers in lines 3 and after (except the last number) do not end with exactly one whitespace.

**Note that this function must handle newline characters in both Windows and UNIX-based systems**. On Windows, line endings are terminated with a combination of carriage return (*\r*) and newline (*\n*) characters, also referred to as CR/LF. On UNIX-based systems, line endings are just the newline character (*\n*).

### Part 2 -- Write Buffer To File

**void write_file(char\* filename, Buffer\* buffer)**

This function takes two arguments -- a string filename and the address of the buffer data structure (as defined above). It should write the data in *buffer* to the file in *filename*. The format of the file is the same as defined previously.

### Part 3 -- Rotate Clockwise By 90

**void rotate_clkws_90(Buffer\* buffer, char\* filename)**

This function takes two arguments -- the address of the *buffer* data structure and a string *filename*. It rotates the matrix in *buffer* clockwise by 90 degrees and writes it to *filename*.

### Part 4 -- Rotate Clockwise By 180

**void rotate_clkws_180(Buffer\* buffer, char\* filename)**

This function takes two arguments -- the address of the *buffer* data structure and a string *filename*. It rotates the matrix in *buffer* clockwise by 180 degrees and writes it to *filename*.

### Part 5 -- Rotate Clockwise By 270

**void rotate_clkws_270(Buffer\* buffer, char\* filename)**

This function takes two arguments -- the address of the *buffer* data structure and a string *filename*. It rotates the matrix in *buffer* clockwise by 270 degrees and writes it to *filename*.

### Part 6 -- Mirroring

**void mirror(Buffer\* buffer, char\* filename)**

This function takes two arguments -- the address of the *buffer* data structure and a string *filename*. It creates a mirror of the matrix in *buffer* writes it to *filename*. For example, consider the following matrix with 2 rows and 3 columns:

### Part 7 -- Duplicates

**(int, int) duplicate(Buffer\* buffer)**

This function takes the data structure *buffer* as an argument. Assume that the matrix in *buffer* contains only binary values 0 and 1. The function checks to see if the matrix has any duplicate rows. If a duplicate row exists in the matrix then the function returns 1 in *$v0* and the index (starting at 1) of the first duplicate row in *$v1*. If the matrix has no duplicate rows then the function returns -1 in *$v0* and 0 in *$v1*

Assume that buffer points to a valid Buffer struct. You do not need to validate the buffer.

Screenshots of output

Program to transform matrix in Mips assembly
Program to transform matrix in Mips assembly 1
Program to transform matrix in Mips assembly 2
Program to transform matrix in Mips assembly 3

Source Code

######### FULL NAME ########## ######### SBU ID ########## ######### NET ID ########## ######## DO NOT ADD A DATA SECTION ########## ######## DO NOT ADD A DATA SECTION ########## ######## DO NOT ADD A DATA SECTION ########## .text read_char: addi $sp, $sp, -1 # allocate space in stack to read a char li $v0, 14 # syscall to read a file move $a1, $sp # read in stack li $a2, 1 # read 1 char syscall # read file blt $v0, $0, rc_exit # if < 0, it's an error beq $v0, $0, rc_exit # if = 0, return lb $v0, 0($sp) # load read char rc_exit: addi $sp, $sp, 1 # restore stack jr $ra # return # read an integer from the file # Receives: $a0 = file descriptor # Returns: $v0 = integer, $v1 = next char if no errors, < 0 if error read_integer: addi $sp, $sp, -16 # allocate space on stack sw $ra, 0($sp) # save registers on stack sw $s0, 4($sp) sw $s1, 8($sp) sw $s2,12($sp) move $s2, $a0 # save file descriptor li $s1, 0 # number of digits li $s0, 0 # start number in zero ri_loop: move $a0, $s2 # pass file descriptor jal read_char # read a char blt $v0, $0, ri_exit # if < 0, it's an error beq $v0, $0, ri_exit # if = 0, return li $t0, 48 # load ascii code for '0' blt $v0, $t0, ri_exit # if not a digit, end li $t0, 57 # load ascii code for '9' bgt $v0, $t0, ri_exit # if not a digit, end addi $v0, $v0, -48 # convert ascii to decimal digit li $t0, 10 mul $s0, $s0, $t0 # multiply old number by 10 add $s0, $s0, $v0 # add digit addi $s1, $s1, 1 # increment number of digits j ri_loop # repeat loop ri_exit: bne $s1, $0, ri_ok # if at least a digit was read, it's ok li $v0, -1 # else, it's an error ri_ok: move $v1, $v0 # set code to last char or error move $v0, $s0 # return number lw $s2,12($sp) lw $s1, 8($sp) lw $s0, 4($sp) lw $ra, 0($sp) addi $sp, $sp, 16 # restore stack jr $ra write_char: addi $sp, $sp, -1 # allocate space in stack to write a char sb $a1, 0($sp) # save char to write in stack li $v0, 15 # syscall to write a file move $a1, $sp # write from stack li $a2, 1 # write 1 char syscall # write file addi $sp, $sp, 1 # restore stack jr $ra # return # write an integer to a file # Receives: $a0 = file descriptor, $a1 = integer to write # Returns: $v0 < 0 if error, number of chars written if success write_integer: addi $sp, $sp, -12 # allocate space on stack sw $ra, 0($sp) # save registers on stack sw $s0, 4($sp) sw $s1, 8($sp) # convert number to a string of chars li $t0, 0 # insert a marker in the stack addi $sp, $sp, -1 # push value to stack sb $t0, 0($sp) li $t1, 10 # load 10 for divisions wi_conv_num: div $a1, $t1 # divide number by 10 mflo $a1 # save quotient in a1 mfhi $t0 # load remainder in t0 [0-9] addi $t0, $t0, 48 # convert digit to ascii addi $sp, $sp, -1 # push digit to stack sb $t0, 0($sp) bne $a1, $0, wi_conv_num # repeat until number is zero # save converted number in file move $s0, $a0 # save file descriptor li $s1, 0 # number of written chars is zero wi_loop: lb $a1, 0($sp) # load char to write addi $sp, $sp, 1 # pop from stack beq $a1, $0, wi_exit # if end of number, return move $a0, $s0 # pass file descriptor jal write_char # write a char blt $v0, $0, wi_error # if < 0, it's an error add $s1, $s1, $v0 # increment number of written chars j wi_loop # repeat loop wi_error: li $s1, -1 # return error wi_exit: move $v0, $s1 # return number of chars written lw $s1, 8($sp) lw $s0, 4($sp) lw $ra, 0($sp) addi $sp, $sp, 12 # restore stack jr $ra .globl initialize initialize: addi $sp, $sp, -24 # allocate space on stack sw $ra, 0($sp) # save registers on stack sw $s0, 4($sp) sw $s1, 8($sp) sw $s2, 12($sp) sw $s3, 16($sp) sw $s4, 20($sp) move $s0, $a1 # save buffer pointer in s0 li $v0, 13 # syscall to open a file li $a1, 0 # open for reading li $a2, 0 # mode = 0 syscall # open file move $s1, $v0 # save file descriptor blt $v0, $0, init_error # if < 0, there was an error # read rows move $a0, $s1 # pass file descriptor jal read_integer # read integer blt $v1, $0, init_error # if < 0, there was an error move $s2, $v0 # save rows blt $s2, 1, init_error # if rows < 1, it's an error bgt $s2, 10, init_error # if rows > 10, it's an error sw $s2, 0($s0) # save in buffer beq $v1, 10, init_rd_cols # if ending char was a \n, read cols bne $v1, 13, init_error # if not a \r, it's an error # if \r, read the \n move $a0, $s1 # pass file descriptor jal read_char # read char blt $v0, $0, init_error # if < 0, there was an error bne $v0, 10, init_error # if not a \n, it's an error init_rd_cols: # read cols move $a0, $s1 # pass file descriptor jal read_integer # read integer blt $v1, $0, init_error # if < 0, there was an error move $s3, $v0 # save cols blt $s3, 1, init_error # if cols < 1, it's an error bgt $s3, 10, init_error # if cols > 10, it's an error sw $s3, 4($s0) # save in buffer beq $v1, 10, init_rd_mat # if ending char was a \n, read matrix bne $v1, 13, init_error # if not a \r, it's an error # if \r, read the \n move $a0, $s1 # pass file descriptor jal read_char # read char blt $v0, $0, init_error # if < 0, there was an error bne $v0, 10, init_error # if not a \n, it's an error init_rd_mat: add $s0, $s0, 8 # advance pointer to start of matrix init_rows: move $s4, $s3 # load number of columns init_cols: # read matrix number move $a0, $s1 # pass file descriptor jal read_integer # read integer blt $v1, $0, init_error # if < 0, there was an error sw $v0, 0($s0) # save in buffer add $s0, $s0, 4 # advance pointer to next position in matrix beq $s4, 1, init_nxt_col # if last val, skip test bne $v1, 32, init_error # if not a space after number, it's an error init_nxt_col: addi $s4, $s4, -1 # decrement remaining cols bne $s4, $0, init_cols # if not zero, repeat beq $v1, 10, init_nxt_row # if \n space after number, read next row bne $v1, 13, init_error # if not a \r, it's an error # if \r, read the \n move $a0, $s1 # pass file descriptor jal read_char # read char blt $v0, $0, init_error # if < 0, there was an error bne $v0, 10, init_error # if not a \n, it's an error init_nxt_row: addi $s2, $s2, -1 # decrement remaining rows bne $s2, $0, init_rows # if not zero, repeat # read end of file move $a0, $s1 # pass file descriptor jal read_char # read char blt $v0, $0, init_error # if < 0, there was an error bne $v0, $0, init_error # if not end of file, it's an error li $v0, 16 # system call for close file move $a0, $s1 # file descriptor to close syscall # close file li $v0, 1 # return without error j init_exit init_error: li $v0, -1 # return error code init_exit: lw $s4, 20($sp) # load register values from stack lw $s3, 16($sp) lw $s2, 12($sp) lw $s1, 8($sp) lw $s0, 4($sp) lw $ra, 0($sp) addi $sp, $sp, 24 # restore stack jr $ra .globl write_file write_file: addi $sp, $sp, -28 # allocate space on stack sw $ra, 0($sp) # save registers on stack sw $s0, 4($sp) sw $s1, 8($sp) sw $s2, 12($sp) sw $s3, 16($sp) sw $s4, 20($sp) sw $s5, 24($sp) move $s0, $a1 # save buffer pointer in s0 li $v0, 13 # syscall to open a file li $a1, 1 # open for writing li $a2, 0 # mode = 0 syscall # open file move $s1, $v0 # save file descriptor blt $v0, $0, wf_error # if < 0, there was an error li $s2, 0 # number of written chars = 0 # write rows move $a0, $s1 # pass file descriptor lw $a1, 0($s0) # load rows from buffer jal write_integer # write integer blt $v0, $0, wf_error # if < 0, there was an error add $s2, $s2, $v0 # add written chars # write a newline move $a0, $s1 # pass file descriptor li $a1, 13 # cr char jal write_char # write char blt $v0, $0, wf_error # if < 0, there was an error add $s2, $s2, $v0 # add written chars move $a0, $s1 # pass file descriptor li $a1, 10 # newline char jal write_char # write char blt $v0, $0, wf_error # if < 0, there was an error add $s2, $s2, $v0 # add written chars # write cols move $a0, $s1 # pass file descriptor lw $a1, 4($s0) # load cols from buffer jal write_integer # write integer blt $v0, $0, wf_error # if < 0, there was an error add $s2, $s2, $v0 # add written chars # write a newline move $a0, $s1 # pass file descriptor li $a1, 13 # cr char jal write_char # write char blt $v0, $0, wf_error # if < 0, there was an error add $s2, $s2, $v0 # add written chars move $a0, $s1 # pass file descriptor li $a1, 10 # newline char jal write_char # write char blt $v0, $0, wf_error # if < 0, there was an error add $s2, $s2, $v0 # add written chars lw $s3, 0($s0) # load rows lw $s4, 4($s0) # load cols add $s0, $s0, 8 # advance pointer to start of matrix wf_rows: move $s5, $s4 # load number of columns wf_cols: # write matrix number move $a0, $s1 # pass file descriptor lw $a1, 0($s0) # load value from buffer add $s0, $s0, 4 # advance pointer to next position in matrix jal write_integer # write integer blt $v0, $0, wf_error # if < 0, there was an error add $s2, $s2, $v0 # add written chars beq $s5, 1, wf_nxt_col # if last val, skip space write # write a space move $a0, $s1 # pass file descriptor li $a1, 32 # space char jal write_char # write char blt $v0, $0, wf_error # if < 0, there was an error add $s2, $s2, $v0 # add written chars wf_nxt_col: addi $s5, $s5, -1 # decrement remaining cols bne $s5, $0, wf_cols # if not zero, repeat # write a newline move $a0, $s1 # pass file descriptor li $a1, 13 # newline char jal write_char # write char blt $v0, $0, wf_error # if < 0, there was an error add $s2, $s2, $v0 # add written chars move $a0, $s1 # pass file descriptor li $a1, 10 # newline char jal write_char # write char blt $v0, $0, wf_error # if < 0, there was an error add $s2, $s2, $v0 # add written chars addi $s3, $s3, -1 # decrement remaining rows bne $s3, $0, wf_rows # if not zero, repeat li $v0, 16 # system call for close file move $a0, $s1 # file descriptor to close syscall # close file move $v0, $s2 # return number of chars written j wf_exit wf_error: li $v0, -1 # return error code wf_exit: lw $s5, 24($sp) # load register values from stack lw $s4, 20($sp) lw $s3, 16($sp) lw $s2, 12($sp) lw $s1, 8($sp) lw $s0, 4($sp) lw $ra, 0($sp) addi $sp, $sp, 28 # restore stack jr $ra .globl rotate_clkws_90 rotate_clkws_90: addi $sp, $sp, -4 # allocate space on stack sw $ra, 0($sp) # save registers on stack move $fp, $sp # point to current sp lw $t0, 0($a0) # load rows lw $t1, 4($a0) # load cols mul $t2, $t0, $t1 # rows*cols sll $t2, $t2, 2 # rows*cols*4 add $t2, $t2, 8 # add 2 words (rows, cols) sub $sp, $sp, $t2 # allocate space in stack to save a new buffer move $t2, $sp # point to buffer sw $t1, 0($t2) # save cols as rows for rotated matrix sw $t0, 4($t2) # save rows as cols for rotated matrix sll $t3, $t0, 2 # rows*4 = line size for rotated matrix # rotation move $t4, $a0 # point to initial buffer move $t7, $t0 # load rows r90_rows: move $t8, $t1 # load cols addi $t5, $t7, -1 # (rows -1) sll $t5, $t5, 2 # current (rows -1) * 4 add $t5, $t5, $t2 # address of mat[rows-1] r90_cols: lw $t6, 8($t4) # load value from initial buffer sw $t6, 8($t5) # save value in end buffer addi $t4, $t4, 4 # advance to next position add $t5, $t5, $t3 # advance to next position addi $t8, $t8, -1 # decrement remaining columns bne $t8, $0, r90_cols # repeat loop while not zero addi $t7, $t7, -1 # decrement remaining rows bne $t7, $0, r90_rows # repeat loop while not zero # write matrix move $a0, $a1 # pass filename move $a1, $sp # pass buffer in stack jal write_file # write the file move $sp, $fp # restore stack pointer lw $ra, 0($sp) addi $sp, $sp, 4 # restore stack jr $ra .globl rotate_clkws_180 rotate_clkws_180: addi $sp, $sp, -4 # allocate space on stack sw $ra, 0($sp) # save registers on stack move $fp, $sp # point to current sp lw $t0, 0($a0) # load rows lw $t1, 4($a0) # load cols mul $t2, $t0, $t1 # rows*cols sll $t2, $t2, 2 # rows*cols*4 add $t2, $t2, 8 # add 2 words (rows, cols) sub $sp, $sp, $t2 # allocate space in stack to save a new buffer move $t2, $sp # point to buffer sw $t0, 0($t2) # save rows for rotated matrix sw $t1, 4($t2) # save cols for rotated matrix addi $t3, $t0, -1 # (rows -1) mul $t3, $t3, $t1 # (rows -1) * cols addi $t5, $t1, -1 # (cols -1) add $t5, $t5, $t3 #current (rows -1) * cols + (cols -1) sll $t5, $t5, 2 # ((rows -1) * cols + (cols -1)) * 4 add $t5, $t5, $t2 # address of mat[rows-1][cols-1] # rotation move $t4, $a0 # point to initial buffer move $t7, $t0 # load rows r180_rows: move $t8, $t1 # load cols r180_cols: lw $t6, 8($t4) # load value from initial buffer sw $t6, 8($t5) # save value in end buffer addi $t4, $t4, 4 # advance to next position addi $t5, $t5, -4 # advance to next position addi $t8, $t8, -1 # decrement remaining columns bne $t8, $0, r180_cols # repeat loop while not zero addi $t7, $t7, -1 # decrement remaining rows bne $t7, $0, r180_rows # repeat loop while not zero # write matrix move $a0, $a1 # pass filename move $a1, $sp # pass buffer in stack jal write_file # write the file move $sp, $fp # restore stack pointer lw $ra, 0($sp) addi $sp, $sp, 4 # restore stack jr $ra .globl rotate_clkws_270 rotate_clkws_270: addi $sp, $sp, -4 # allocate space on stack sw $ra, 0($sp) # save registers on stack move $fp, $sp # point to current sp lw $t0, 0($a0) # load rows lw $t1, 4($a0) # load cols mul $t2, $t0, $t1 # rows*cols sll $t2, $t2, 2 # rows*cols*4 add $t2, $t2, 8 # add 2 words (rows, cols) sub $sp, $sp, $t2 # allocate space in stack to save a new buffer sw $t1, 0($sp) # save cols as rows for rotated matrix sw $t0, 4($sp) # save rows as cols for rotated matrix addi $t2, $t1, -1 # (cols -1) mul $t2, $t2, $t0 # current (cols -1) * rows sll $t2, $t2, 2 # current (cols -1) * rows * 4 add $t2, $t2, $sp # address of mat[cols-1][0] sll $t3, $t0, 2 # rows*4 = line size for rotated matrix # rotation move $t4, $a0 # point to initial buffer move $t7, $t0 # load rows r270_rows: move $t8, $t1 # load cols move $t5, $t2 # load current mat[cols -1][row] position r270_cols: lw $t6, 8($t4) # load value from initial buffer sw $t6, 8($t5) # save value in end buffer addi $t4, $t4, 4 # advance to next position sub $t5, $t5, $t3 # advance to next position addi $t8, $t8, -1 # decrement remaining columns bne $t8, $0, r270_cols # repeat loop while not zero addi $t2, $t2, 4 # advance to next col in rotated matrix addi $t7, $t7, -1 # decrement row bne $t7, $0, r270_rows # repeat loop while not zero # write matrix move $a0, $a1 # pass filename move $a1, $sp # pass buffer in stack jal write_file # write the file move $sp, $fp # restore stack pointer lw $ra, 0($sp) addi $sp, $sp, 4 # restore stack jr $ra .globl mirror mirror: addi $sp, $sp, -4 # allocate space on stack sw $ra, 0($sp) # save registers on stack move $fp, $sp # point to current sp lw $t0, 0($a0) # load rows lw $t1, 4($a0) # load cols mul $t2, $t0, $t1 # rows*cols sll $t2, $t2, 2 # rows*cols*4 add $t2, $t2, 8 # add 2 words (rows, cols) sub $sp, $sp, $t2 # allocate space in stack to save a new buffer sw $t0, 0($sp) # save rows for rotated matrix sw $t1, 4($sp) # save cols for rotated matrix addi $t2, $t1, -1 # (cols -1) sll $t2, $t2, 2 # (cols -1) * 4 add $t2, $t2, $sp # address of mat[0][cols-1] sll $t3, $t1, 2 # cols * 4 = linesize # mirroring move $t4, $a0 # point to initial buffer move $t7, $t0 # load rows mirror_rows: move $t8, $t1 # load cols move $t5, $t2 # load current mat[row][cols -1] position mirror_cols: lw $t6, 8($t4) # load value from initial buffer sw $t6, 8($t5) # save value in end buffer addi $t4, $t4, 4 # advance to next position addi $t5, $t5, -4 # advance to next position addi $t8, $t8, -1 # decrement remaining columns bne $t8, $0, mirror_cols # repeat loop while not zero add $t2, $t2, $t3 # advance to next col in mirrored matrix addi $t7, $t7, -1 # decrement row bne $t7, $0, mirror_rows # repeat loop while not zero # write matrix move $a0, $a1 # pass filename move $a1, $sp # pass buffer in stack jal write_file # write the file move $sp, $fp # restore stack pointer lw $ra, 0($sp) addi $sp, $sp, 4 # restore stack jr $ra .globl duplicate duplicate: addi $sp, $sp, -8 # allocate space on stack sw $s0, 0($sp) # save registers on stack sw $s1, 4($sp) lw $t0, 0($a0) # load rows lw $t1, 4($a0) # load cols addi $t0, $t0, -1 # rows - 1 sll $t2, $t1, 2 # cols *4 = line size move $t3, $a0 # point to initial buffer li $t4, 0 # current rows dup_findrow: addi $t6, $t4, 1 # initial rows = curr row + 1 add $t5, $t3, $t2 # point to next row j dup_cmp # jump to comparison dup_rows: move $t7, $t1 # load cols move $s0, $t3 # save current row move $s1, $t5 # save current row dup_cols: lw $t8, 8($t3) # load value from initial row lw $t9, 8($t5) # load value from curr row bne $t8, $t9, no_dup # if not equal, is not a duplicate addi $t3, $t3, 4 # advance to next position addi $t5, $t5, 4 # advance to next position addi $t7, $t7, -1 # decrement remaining columns bne $t7, $0, dup_cols # repeat loop while not zero # it will end here if duplicate li $v0, 1 # duplicate found add $v1, $t6, 1 # return row index j dup_exit no_dup: addi $t6, $t6, 1 # increment row move $t3, $s0 # restart initial row add $t5, $s1, $t2 # advance to next row dup_cmp: ble $t6, $t0, dup_rows # repeat loop while <= rows-1 add $t3, $t3, $t2 # advance to next row addi $t4, $t4, 1 # increment row blt $t4, $t0, dup_findrow # repeat loop while < rows-1 # it will end here if no duplicate li $v0, -1 # no duplicate found li $v1, 0 # return 0 dup_exit: lw $s0, 0($sp) lw $s1, 4($sp) addi $sp, $sp, 8 # restore stack jr $ra

Related Samples

Discover our curated collection of free Assembly Language assignment samples. These resources offer practical examples and solutions to enhance your understanding of low-level programming concepts. Explore real-world applications and coding techniques to excel in your Assembly Language projects.