.data cat_buf: .space 4096 .section .text .globl cat_file, open_fd, cat_stdin # Cat out the given file to stdout # @param[in] a0: ptr to null-terminated file str. # @param[out] a0: result code. cat_file: mv a1, a0 # since the function takes in a0, move it to a1 for syscall addi sp, sp, -8 sd ra, 0(sp) call open_fd ld ra, 0(sp) addi sp, sp, 8 mv t0, a1 # put fd in t0 beqz a0, .LReadFileBlock # if we don't have an error, jump to reading li a0, 1 j .LCatFileRet .LReadFileBlock: mv a0, t0 la a1, cat_buf li a2, 4096 li a7, 63 ecall blez a0, .LCloseFD # if we haven't read any bytes, EOF, close FD mv a2, a0 # move bytes read into bytes needed to write li a0, 1 la a1, cat_buf li a7, 64 ecall j .LReadFileBlock .LCloseFD: mv a0, t0 li a7, 57 # close fd ecall .LCatFileRet: ret # Cat out stdin to stdout # @param[in] a0: Not used. # @param[out] a0: result code. cat_stdin: .LReadStdinBlock: li a0, 0 la a1, cat_buf li a2, 4096 li a7, 63 ecall blez a0, .LCatStdinRet # if we haven't read any bytes, EOF, close FD mv a2, a0 # move bytes read into bytes needed to write li a0, 1 la a1, cat_buf li a7, 64 ecall j .LReadStdinBlock .LCatStdinRet: ret # Open fd # @param[in] a0: ptr to null-terminated file str. # @param[out] a0: result code. (0-exists 1-doesn't exist) # @param[out] a1: fd. open_fd: mv a1, a0 # since the function takes in a0, move it to a1 for syscall li a0, -100 # relative/absolute path li a2, 0 # readonly li a7, 56 # open ecall bltz a0, 1f # file doesn't exist mv a1, a0 # move fd to a1 li a0, 0 j 2f 1: li a0, 1 2: ret # # Check if the given file exists without opening fd # # @param[in] a0: ptr to null-terminated file str. # # @param[out] a0: result code (0-exists 1-doesn't exist). # file_exists: # mv a1, a0 # li a0, -100 # relative/absolute path # li a2, 0 # li a7, 48 # ecall # beqz a0, 1f # li a0, 1 # ret # 1: # li a0, 0 # ret