.globl _start .option rvc # enable compressed instructions .option norelax .section .rodata space: .ascii " " newline: .ascii "\n" .text _start: # arguments are passed on the stack: # --bottom of stack-- # dd argc # dd argv[0] # dd ... # dd 0 # dd envp[0] # dd ... # dd 0 ld s0, 0(sp) # get argc add s1, sp, 8 # TODO: iovec # allocate stack space for #argc iovecs #slli t0, s0, 2 #sub tp, sp, t0 beqz s0, end # skip argv[0] addi s0, s0, -1 addi s1, s1, 8 beqz s0, end # loop over argv # write each argument li s11, 0 mv s2, s0 la s8, space loop: # get argv[i] slli t0, s11, 3 add t0, t0, s1 ld a1, 0(t0) # check for null pointer, just in case beqz a1, step # compute length of string mv t1, a1 strlen: lbu t0, 0(t1) addi t1, t1, 1 bnez t0, strlen addi t1, t1, -1 # NUL sub a2, t1, a1 li a7, 64 # sys_write li a0, 1 # stdout # a1 & a2 already set ecall bltz a0, write_error # increment index # if this was the last argument, break addi s11, s11, 1 bge s11, s0, end # not the last argument, so print a space and loop li a7, 64 # sys_write li a0, 1 # stdout mv a1, s8 # space li a2, 1 # size ecall bltz a0, write_error j loop step: # increment index and loop addi s11, s11, 1 blt s11, s0, loop end: # print a newline at the end, # regardless of whether there were any arguments or not li a7, 64 # sys_write li a0, 1 # stdout la a1, newline li a2, 1 # size ecall bltz a0, write_error li a7, 93 # exit li a0, 0 ecall write_error: li a7, 93 # exit li a0, 1 ecall