153 lines
3.3 KiB
ArmAsm
153 lines
3.3 KiB
ArmAsm
.data
|
|
mod_buf_0: .space 36864
|
|
mod_buf_1: .space 36864
|
|
|
|
.section .text
|
|
.globl cat_file, open_fd
|
|
|
|
# Cat out the given file to stdout
|
|
# @param[in] a0: ptr to null-terminated file str. 0 = stdin
|
|
# @param[out] a0: result code.
|
|
cat_file:
|
|
addi sp, sp, -32
|
|
sd s0, 0(sp)
|
|
sd ra, 8(sp)
|
|
sd s1, 16(sp) # next modbuf to WRITE TO (inverse is read) 0=modbuf_0, 1=modbuf_1
|
|
sd s2, 24(sp) # current modbuf byte count
|
|
|
|
mv a1, a0 # since the function takes in a0, move it to a1 for syscall
|
|
li s1, 1
|
|
li s2, 0
|
|
|
|
beqz a0, 1f
|
|
call open_fd
|
|
j 2f
|
|
1:
|
|
li s0, 0 # stdin fd
|
|
2:
|
|
|
|
mv s0, a1 # put fd in s0
|
|
|
|
beqz a0, .LReadFileBlock # if we don't have an error, jump to reading
|
|
li a0, 1
|
|
j .LCatFileRet
|
|
|
|
.LReadFileBlock:
|
|
mv a0, s0
|
|
la a1, mod_buf_0
|
|
li a2, 4096
|
|
li a7, 63
|
|
ecall
|
|
blez a0, .LCloseFD # if we haven't read any bytes, EOF, close FD
|
|
mv s2, a0
|
|
li s1, 1
|
|
|
|
la t1, number_nonblank
|
|
lb t1, 0(t1)
|
|
beqz t1, .LNoNonblankNumbers
|
|
|
|
mv a1, s2 # load mod buf size to a1
|
|
|
|
beqz s1, 1f
|
|
la a0, mod_buf_0 # load mod_buf_0 as read buf
|
|
la a2, mod_buf_1 # load mod_buf_1 as write buf
|
|
j 2f
|
|
1:
|
|
la a0, mod_buf_1 # load mod_buf_1 as read buf
|
|
la a2, mod_buf_0 # load mod_buf_0 as write buf
|
|
2:
|
|
|
|
call add_line_numbers
|
|
xori s1, s1, 1 # flip the mod buf to write to
|
|
mv s2, a1 # update the current byte count
|
|
j .LNoNumbers # -n and -b are exclusive
|
|
.LNoNonblankNumbers:
|
|
|
|
la t1, number
|
|
lb t1, 0(t1)
|
|
beqz t1, .LNoNumbers
|
|
|
|
mv a1, s2 # load mod buf size to a1
|
|
|
|
beqz s1, 1f
|
|
la a0, mod_buf_0 # load mod_buf_0 as read buf
|
|
la a2, mod_buf_1 # load mod_buf_1 as write buf
|
|
j 2f
|
|
1:
|
|
la a0, mod_buf_1 # load mod_buf_1 as read buf
|
|
la a2, mod_buf_0 # load mod_buf_0 as write buf
|
|
2:
|
|
|
|
call add_line_numbers
|
|
xori s1, s1, 1 # flip the mod buf to write to
|
|
mv s2, a1 # update the current byte count
|
|
.LNoNumbers:
|
|
|
|
la t1, show_ends
|
|
lb t1, 0(t1)
|
|
beqz t1, .LNoEndings
|
|
|
|
mv a1, s2 # load mod buf size to a1
|
|
|
|
beqz s1, 1f
|
|
la a0, mod_buf_0 # load mod_buf_0 as read buf
|
|
la a2, mod_buf_1 # load mod_buf_1 as write buf
|
|
j 2f
|
|
1:
|
|
la a0, mod_buf_1 # load mod_buf_1 as read buf
|
|
la a2, mod_buf_0 # load mod_buf_0 as write buf
|
|
2:
|
|
|
|
call add_endings
|
|
xori s1, s1, 1 # flip the mod buf to write to
|
|
mv s2, a1 # update the current byte count
|
|
.LNoEndings:
|
|
|
|
beqz s1, 1f
|
|
la a1, mod_buf_0
|
|
j 2f
|
|
1:
|
|
la a1, mod_buf_1
|
|
2:
|
|
|
|
mv a2, s2 # load the amount of bytes read in previous step into bytes needed to write
|
|
li a0, 1
|
|
li a7, 64
|
|
ecall
|
|
j .LReadFileBlock
|
|
|
|
.LCloseFD:
|
|
mv a0, s0
|
|
li a7, 57 # close fd
|
|
ecall
|
|
|
|
.LCatFileRet:
|
|
ld s0, 0(sp)
|
|
ld ra, 8(sp)
|
|
ld s1, 16(sp)
|
|
ld s2, 24(sp)
|
|
addi sp, sp, 32
|
|
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
|