Files
riscv-cat/src/file.S
T
2026-09-13 16:42:39 -04:00

108 lines
2.1 KiB
ArmAsm

.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