103 lines
1.7 KiB
ArmAsm
103 lines
1.7 KiB
ArmAsm
.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
|
|
|
|
|