Add help
This commit is contained in:
+94
-3
@@ -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
@@ -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
@@ -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
|
||||||
|
|||||||
Reference in New Issue
Block a user