.globl _start .option rvc # enable compressed instructions .option norelax .section .rodata space_or_newline: .ascii " ", "\n" .text _start: # arguments are passed on the stack: # --bottom of stack-- # dd argc # dd argv # dd argv[0] # dd ... # dd 0 # dd envp[0] # dd ... # dd 0 ld s0, 0(sp) # get argc #ld s1, 8(sp) # get argv 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 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 # if not the last argument, print a space # otherwise print a newline # # a1 = space_or_newline + (argc-s11 < 2) la a1, space_or_newline sub t0, s0, s11 sltiu t0, t0, 2 add a1, a1, t0 li a7, 64 # sys_write li a0, 1 # stdout #la a1, newline or space li a2, 1 # size ecall bltz a0, write_error step: # increment index and loop addi s11, s11, 1 blt s11, s0, loop end: li a7, 93 # exit li a0, 0 ecall write_error: li a7, 93 # exit li a0, 1 ecall