#define c_print_int 1 #define c_print_str 4 #define c_atoi 5 #define c_sbrk 9 #define c_exit 10 #define c_print_char 11 #define c_openFile 13 #define c_readFile 14 #define c_writeFile 15 #define c_closeFile 16 #define c_exit2 17 #define c_fflush 18 #define c_feof 19 #define c_ferror 20 #define c_printHex 34 # ecall wrappers .globl print_int, print_str, atoi, sbrk, exit, print_char, fopen, fread, fwrite, fclose, exit2, fflush, ferror, print_hex, exit5 # helper functions .globl file_error, print_int_array, malloc .data error_string: .string "This library file should not be directly called!" .text # Exits if you run this file main: la a1 error_string jal print_str li a1 1 jal exit2 # End main exit5: la a1 error_string jal print_str li a1 1 jal exit2 # End main #================================================================ # void print_int(int a1) # Prints the integer in a1. # args: # a1 = integer to print # return: # void #================================================================ print_int: li a0 c_print_int ecall jr ra #================================================================ # void print_str(char *a1) # Prints the null-terminated string at address a1. # args: # a1 = address of the string you want printed. # return: # void #================================================================ print_str: li a0 c_print_str ecall jr ra #================================================================ # int atoi(char* a1) # Returns the integer version of the string at address a1. # args: # a1 = address of the string you want to turn into an integer. # return: # a0 = Integer representation of string #================================================================ atoi: li a0 c_atoi ecall jr ra #================================================================ # void *sbrk(int a1) # Allocates a1 bytes onto the heap. # args: # a1 = Number of bytes you want to allocate. # return: # a0 = Pointer to the start of the allocated memory #================================================================ sbrk: li a0 c_sbrk ecall jr ra #================================================================ # void noreturn exit() # Exits the program with a zero exit code. # args: # None # return: # No Return #================================================================ exit: li a0 c_exit ecall #================================================================ # void print_char(char a1) # Prints the ASCII character in a1 to the console. # args: # a1 = character to print # return: # void #================================================================ print_char: li a0 c_print_char ecall jr ra #================================================================ # int fopen(char *a1, int a2) # Opens file with name a1 with permissions a2. # args: # a1 = filepath # a2 = permissions (0, 1, 2, 3, 4, 5 = r, w, a, r+, w+, a+) # return: # a0 = file descriptor #================================================================ fopen: li a0 c_openFile ecall jr ra #================================================================ # int fread(int a1, void *a2, size_t a3) # Reads a3 bytes of the file into the buffer a2. # args: # a1 = file descriptor # a2 = pointer to the buffer you want to write the read bytes to. # a3 = Number of bytes to be read. # return: # a0 = Number of bytes actually read. #================================================================ fread: li a0 c_readFile ecall jr ra #================================================================ # int fwrite(int a1, void *a2, size_t a3, size_t a4) # Writes a3 * a4 bytes from the buffer in a2 to the file descriptor a1. # args: # a1 = file descriptor # a2 = Buffer to read from # a3 = Number of items to read from the buffer. # a4 = Size of each item in the buffer. # return: # a0 = Number of elements writen. If this is less than a3, # it is either an error or EOF. You will also need to still flush the fd. #================================================================ fwrite: li a0 c_writeFile ecall jr ra #================================================================ # int fclose(int a1) # Closes the file descriptor a1. # args: # a1 = file descriptor # return: # a0 = 0 on success, and EOF (-1) otherwise. #================================================================ fclose: li a0 c_closeFile ecall jr ra #================================================================ # void noreturn exit2(int a1) # Exits the program with error code a1. # args: # a1 = Exit code. # return: # This program does not return. #================================================================ exit2: li a0 c_exit2 ecall jr ra #================================================================ # int fflush(int a1) # Flushes the data to the filesystem. # args: # a1 = file descriptor # return: # a0 = 0 on success, and EOF (-1) otherwise. #================================================================ fflush: li a0 c_fflush ecall jr ra #================================================================ # int ferror(int a1) # Returns a nonzero value if the file stream has errors, otherwise it returns 0. # args: # a1 = file descriptor # return: # a0 = Nonzero falue if the end of file is reached. 0 Otherwise. #================================================================ ferror: li a0 c_ferror ecall jr ra #================================================================ # void print_hex(int a1) # # args: # a1 = The word which will be printed as a hex value. # return: # void #================================================================ print_hex: li a0 c_printHex ecall jr ra #================================================================ # void* malloc(int a0) # Allocates heap memory and return a pointer to it # args: # a0 is the # of bytes to allocate heap memory for # return: # a0 is the pointer to the allocated heap memory #================================================================ malloc: # Call to sbrk mv a1 a0 addi a0 x0 9 ecall jr ra #================================================================ # void print_int_array(int* a0, int a1, int a2) # Prints an integer array, with spaces between the elements # args: # a0 is the pointer to the start of the array # a1 is the # of rows in the array # a2 is the # of columns in the array # return: # void #================================================================ print_int_array: # Prologue addi sp sp -24 sw s0 0(sp) sw s1 4(sp) sw s2 8(sp) sw s3 12(sp) sw s4 16(sp) sw ra 20(sp) # Save arguments mv s0 a0 mv s1 a1 mv s2 a2 # Set outer loop index li s3 0 outer_loop_start: # Check outer loop condition beq s3 s1 outer_loop_end # Set inner loop index li s4 0 inner_loop_start: # Check inner loop condition beq s4 s2 inner_loop_end # t0 = row index * len(row) + column index mul t0 s2 s3 add t0 t0 s4 slli t0 t0 2 # Load matrix element add t0 t0 s0 lw t1 0(t0) # Print matrix element mv a1 t1 jal print_int # Print whitespace li a1 ' ' jal print_char addi s4 s4 1 j inner_loop_start inner_loop_end: # Print newline li a1 '\n' jal print_char addi s3 s3 1 j outer_loop_start outer_loop_end: # Epilogue lw s0 0(sp) lw s1 4(sp) lw s2 8(sp) lw s3 12(sp) lw s4 16(sp) lw ra 20(sp) addi sp sp 24 jr ra