Add STDIN functionality #1

Merged
Lexzach merged 1 commits from stdin into master 2026-09-13 20:43:34 +00:00
3 changed files with 64 additions and 45 deletions
Showing only changes of commit fcd9109ef6 - Show all commits
+16 -11
View File
@@ -107,9 +107,9 @@ has_switch:
mv s1, a1 mv s1, a1
call fetch_argc call fetch_argc
bnez a0, 1f bnez a0, .LHasSwitchNoParse
li t0, 2 li t0, 2
blt a1, t0, 1f # if we have no commands other than the binary, we know there will be no switches blt a1, t0, .LSwitchNotFoundNoParse # if we have no commands other than the binary, we know there will be no switches
addi sp, sp, -24 addi sp, sp, -24
sd s4, 16(sp) sd s4, 16(sp)
@@ -118,7 +118,7 @@ has_switch:
li s2, 1 # load first non-base command arg li s2, 1 # load first non-base command arg
mv s4, a1 # put argc in s4 mv s4, a1 # put argc in s4
2: .LSwitchProcessNextArg:
mv a0, s2 mv a0, s2
call fetch_argv call fetch_argv
mv s3, a1 # save argv buff addr mv s3, a1 # save argv buff addr
@@ -126,32 +126,37 @@ has_switch:
mv a0, s3 # load argv buff addr into a0 (string 0) mv a0, s3 # load argv buff addr into a0 (string 0)
mv a1, s0 # move switch ptr 1 addr into a1 (string 1) mv a1, s0 # move switch ptr 1 addr into a1 (string 1)
call _str_cmp call _str_cmp
bnez a1, 5f # if the strings match, exit loop bnez a1, .LSwitchFound # if the strings match, exit loop
mv a0, s3 # move argv buff addr into a0 (string 0) mv a0, s3 # move argv buff addr into a0 (string 0)
mv a1, s1 # move switch ptr 2 addr into a1 (string 1) mv a1, s1 # move switch ptr 2 addr into a1 (string 1)
call _str_cmp call _str_cmp
bnez a1, 5f # if the strings match, exit loop bnez a1, .LSwitchFound # if the strings match, exit loop
addi s2, s2, 1 # if string doesn't match we inc to the next arg addi s2, s2, 1 # if string doesn't match we inc to the next arg
blt s2, s4, 2b # keep going while we have untested args blt s2, s4, .LSwitchProcessNextArg # keep going while we have untested args
4: .LSwitchNotFound:
li a0, 0 li a0, 0
li a1, 0 li a1, 0
j 3f j .LSwitchFreeSP
5: .LSwitchNotFoundNoParse:
li a0, 0
li a1, 0
j .LHasSwitchNoParse
.LSwitchFound:
li a0, 0 li a0, 0
li a1, 1 li a1, 1
3: .LSwitchFreeSP:
ld s3, 0(sp) ld s3, 0(sp)
ld s2, 8(sp) ld s2, 8(sp)
ld s4, 16(sp) ld s4, 16(sp)
addi sp, sp, 24 addi sp, sp, 24
1: .LHasSwitchNoParse:
ld ra, 16(sp) ld ra, 16(sp)
ld s1, 8(sp) ld s1, 8(sp)
ld s0, 0(sp) ld s0, 0(sp)
+27 -6
View File
@@ -2,7 +2,7 @@
cat_buf: .space 4096 cat_buf: .space 4096
.section .text .section .text
.globl cat_file, open_fd .globl cat_file, open_fd, cat_stdin
# Cat out the given file to stdout # Cat out the given file to stdout
# @param[in] a0: ptr to null-terminated file str. # @param[in] a0: ptr to null-terminated file str.
@@ -17,12 +17,12 @@ cat_file:
addi sp, sp, 8 addi sp, sp, 8
mv t0, a1 # put fd in t0 mv t0, a1 # put fd in t0
beqz a0, .LReadBlock # if we don't have an error, jump to reading beqz a0, .LReadFileBlock # if we don't have an error, jump to reading
li a0, 1 li a0, 1
j .LRet j .LCatFileRet
.LReadBlock: .LReadFileBlock:
mv a0, t0 mv a0, t0
la a1, cat_buf la a1, cat_buf
li a2, 4096 li a2, 4096
@@ -35,16 +35,37 @@ cat_file:
la a1, cat_buf la a1, cat_buf
li a7, 64 li a7, 64
ecall ecall
j .LReadBlock j .LReadFileBlock
.LCloseFD: .LCloseFD:
mv a0, t0 mv a0, t0
li a7, 57 # close fd li a7, 57 # close fd
ecall ecall
.LRet: .LCatFileRet:
ret 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 # Open fd
# @param[in] a0: ptr to null-terminated file str. # @param[in] a0: ptr to null-terminated file str.
+21 -28
View File
@@ -10,6 +10,7 @@ file_err: .asciz ": No such file or directory\n"
help: help:
.ascii "Usage: cat [OPTION]... [FILE]...\n" .ascii "Usage: cat [OPTION]... [FILE]...\n"
.ascii "Concatenate FILE(S) to standard output.\n\n" .ascii "Concatenate FILE(S) to standard output.\n\n"
.ascii "With no FILE, or when FILE is -, read standard input.\n\n"
.ascii " -h, --help | Show this help page.\n\n" .ascii " -h, --help | Show this help page.\n\n"
.asciz "Written by lexzach in RISC-V assembly: <https://git.lexza.ch/Lexzach/riscv-cat>\n" .asciz "Written by lexzach in RISC-V assembly: <https://git.lexza.ch/Lexzach/riscv-cat>\n"
.equ HELP_LEN, . - help .equ HELP_LEN, . - help
@@ -29,45 +30,37 @@ _start:
call save_sp call save_sp
call fetch_argc call fetch_argc
li t0, 1
ble a1, t0, .Lreturn_err # return 1 if no args
mv s0, a1 # store argc mv s0, a1 # store argc
li s1, 1 li s1, 1
la a0, flag_h la a0, flag_h
la a1, flag_help la a1, flag_help
call has_switch call has_switch
bnez a0, .Lreturn_err bnez a0, .LMainReturnErr
beqz a1, .Lskip_disp_help beqz a1, .LSkipDispHelp
call _disp_help call _disp_help
j .Lreturn_ok j .LMainReturnOk
.Lskip_disp_help: .LSkipDispHelp:
li t0, 1
# 5: #iterate through and check that all files exist first ble s0, t0, .LProcessStdin # return 1 if no args
# mv a0, s1
# call fetch_argv .LProcessFile:
# bnez a0, 1f # error if failed
# mv a0, a1
# call file_exists
# bnez a0, 4f
# addi s1, s1, 1
# blt s1, s0, 5b
# li s1, 1 # reset counter now that we've verified all files exist, skip command
.Lprocess_file:
mv a0, s1 mv a0, s1
call fetch_argv call fetch_argv
bnez a0, .Lreturn_err # error if failed bnez a0, .LMainReturnErr # error if failed
mv a0, a1 mv a0, a1
call cat_file call cat_file
bnez a0, .Lreturn_file_err # error if failed bnez a0, .LReturnFileErr # error if failed
addi s1, s1, 1 addi s1, s1, 1
blt s1, s0, .Lprocess_file blt s1, s0, .LProcessFile
j .Lreturn_ok j .LMainReturnOk
.Lreturn_file_err: .LProcessStdin:
call cat_stdin
j .LMainReturnOk
.LReturnFileErr:
li a0, 2 li a0, 2
la a1, cat_prefix la a1, cat_prefix
li a2, CAT_PREFIX_LEN li a2, CAT_PREFIX_LEN
@@ -88,12 +81,12 @@ _start:
ecall ecall
.Lreturn_err: #1 .LMainReturnErr: #1
li a0, 1 li a0, 1
li a7, 93 li a7, 93
ecall # return 1 ecall # return 1
.Lreturn_ok: #2 .LMainReturnOk: #2
li a0, 0 li a0, 0
li a7, 93 li a7, 93
ecall # return 0 ecall # return 0