This commit is contained in:
2026-09-13 15:47:54 -04:00
parent 5a78522d8e
commit 3b279e25af
3 changed files with 124 additions and 5 deletions
+94 -3
View File
@@ -1,10 +1,8 @@
.data .data
sp_start: .space 8 sp_start: .space 8
flag_h: .asciz "-h"
flag_helpo: .asciz "--help"
.section .text .section .text
.globl save_sp, fetch_argc, fetch_argv .globl save_sp, fetch_argc, fetch_argv, has_switch
save_sp: save_sp:
sd sp, sp_start, t0 # save the stack pointer sd sp, sp_start, t0 # save the stack pointer
@@ -94,6 +92,99 @@ fetch_argv:
addi sp, sp, 8 addi sp, sp, 8
ret ret
# Check if flag was given
# @param[in] a0: ptr to null-terminated switch 1 (ie. -h).
# @param[in] a1: ptr to null-terminated switch 2 (ie. --help) (optional).
# @param[out] a0: result code.
# @param[out] a1: was found (0-not found, 1-found).
has_switch:
addi sp, sp, -24 # store ra and s regs to stack
sd ra, 16(sp)
sd s1, 8(sp)
sd s0, 0(sp)
mv s0, a0
mv s1, a1
call fetch_argc
bnez a0, 1f
li t0, 2
blt a1, t0, 1f # if we have no commands other than the binary, we know there will be no switches
addi sp, sp, -24
sd s4, 16(sp)
sd s2, 8(sp)
sd s3, 0(sp)
li s2, 1 # load first non-base command arg
mv s4, a1 # put argc in s4
2:
mv a0, s2
call fetch_argv
mv s3, a1 # save argv buff addr
mv a0, s3 # load argv buff addr into a0 (string 0)
mv a1, s0 # move switch ptr 1 addr into a1 (string 1)
call _str_cmp
bnez a1, 5f # if the strings match, exit loop
mv a0, s3 # move argv buff addr into a0 (string 0)
mv a1, s1 # move switch ptr 2 addr into a1 (string 1)
call _str_cmp
bnez a1, 5f # if the strings match, exit loop
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
4:
li a0, 0
li a1, 0
j 3f
5:
li a0, 0
li a1, 1
3:
ld s3, 0(sp)
ld s2, 8(sp)
ld s4, 16(sp)
addi sp, sp, 24
1:
ld ra, 16(sp)
ld s1, 8(sp)
ld s0, 0(sp)
addi sp, sp, 24 # restore ra and s regs from stack
ret
# Compares two null terminated string buffers.
# @param[in] a0: str buffer 1
# @param[in] a1: str buffer 2
# @param[out] a0: result code.
# @param[out] a1: is equal (0-no, 1-yes).
_str_cmp:
li t2, 0
1:
add t0, a0, t2
add t1, a1, t2
lb t0, 0(t0)
lb t1, 0(t1)
bne t0, t1, 3f # first byte that isn't the same, branch to no match
beqz t0, 2f # jump to ret when null is read
addi t2, t2, 1
j 1b
3: # no match
li a0, 0
li a1, 0
ret
2: # match
li a0, 0
li a1, 1
ret
# Fetch argument value # Fetch argument value
# @param[in] a0: address of current argv. # @param[in] a0: address of current argv.
+1 -1
View File
@@ -2,7 +2,7 @@
cat_buf: .space 4096 cat_buf: .space 4096
.section .text .section .text
.globl cat_file, open_fd, file_exists .globl cat_file, open_fd
# 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.
+29 -1
View File
@@ -1,10 +1,20 @@
.data .data
argc: .space 8 argc: .space 8
cat_prefix: .asciz "cat: " cat_prefix: .asciz "cat: "
.equ CAT_PREFIX_LEN, . - cat_prefix .equ CAT_PREFIX_LEN, . - cat_prefix
file_err: .asciz ": No such file or directory\n" file_err: .asciz ": No such file or directory\n"
.equ FILE_ERR_LEN, . - file_err .equ FILE_ERR_LEN, . - file_err
help: .asciz "Usage: cat [OPTION]... [FILE]...\nConcatenate FILE(S) to standard output.\n"
.equ HELP_LEN, . - help
flag_h: .asciz "-h"
# .equ FLAG_H_LEN, . - flag_h
flag_help: .asciz "--help"
# .equ FLAG_HELP_LEN, . - flag_help
.section .text .section .text
.globl _start .globl _start
@@ -18,10 +28,20 @@ _start:
call save_sp call save_sp
call fetch_argc call fetch_argc
li t0, 1 li t0, 1
ble a1, t0, 1f # return 1 if no file given ble a1, t0, 1f # 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 a1, flag_help
call has_switch
bnez a0, 1f
beqz a1, .Lskip_disp_help
call _disp_help
j 2f
.Lskip_disp_help:
# 5: #iterate through and check that all files exist first # 5: #iterate through and check that all files exist first
# mv a0, s1 # mv a0, s1
# call fetch_argv # call fetch_argv
@@ -75,3 +95,11 @@ _start:
li a0, 0 li a0, 0
li a7, 93 li a7, 93
ecall # return 0 ecall # return 0
_disp_help:
la a0, 1
la a1, help
li a2, HELP_LEN
li a7, 64
ecall
ret