85 lines
1.7 KiB
ArmAsm
85 lines
1.7 KiB
ArmAsm
.globl _start
|
|
.option rvc # enable compressed instructions
|
|
#.option norelax
|
|
|
|
.data
|
|
sigaction:
|
|
.dword segv # sa_handler
|
|
.dword 0 # sa_flags
|
|
.dword 0 # sa_mask
|
|
|
|
.data
|
|
buf: .zero 8
|
|
|
|
.text
|
|
_start:
|
|
# set up the gp register so that relaxed loads work
|
|
.option norelax
|
|
la gp, __global_pointer$
|
|
.option relax
|
|
# the following is what the la instruction above gets expanded to,
|
|
# but writing it out explicitly like this causes ld to segfault
|
|
#auipc gp, %pcrel_hi(__global_pointer$)
|
|
#addi gp, gp, %pcrel_lo(__global_pointer$)
|
|
|
|
# set up a signal handler for SIGSEGV
|
|
# XXX we don't actually need this because write will
|
|
# return EFAULT if the address isn't mapped
|
|
li a7, 134 # sys_rt_sigaction
|
|
li a0, 11 # SIGSEGv
|
|
la a1, sigaction # action
|
|
li a2, 0 # oldact = NULL
|
|
li a3, 8 # signal set size (bytes)
|
|
ecall
|
|
|
|
# save sp
|
|
la s7, buf
|
|
sd sp, 0(s7)
|
|
|
|
# print sp
|
|
li a7, 64 # sys_write
|
|
li a0, 1 # fd = stdout
|
|
mv a1, s7 # pointer to string
|
|
li a2, 8 # size of data
|
|
ecall
|
|
bltz a0, write_error
|
|
|
|
# round sp down to multiple of 512
|
|
# and move to s0
|
|
andi s0, sp, -512
|
|
|
|
loop:
|
|
# print sp
|
|
sd s0, 0(s7)
|
|
li a7, 64 # sys_write
|
|
li a0, 1 # fd = stdout
|
|
mv a1, s7 # pointer to string
|
|
li a2, 8 # size of data
|
|
ecall
|
|
bltz a0, write_error
|
|
|
|
# print 512 bytes of stack
|
|
li a7, 64 # sys_write
|
|
li a0, 1
|
|
mv a1, s0
|
|
li a2, 512
|
|
ecall
|
|
bltz a0, write_error
|
|
|
|
# increment sp by 512
|
|
addi s0, s0, 512
|
|
|
|
beqz s0, segv
|
|
j loop
|
|
|
|
write_error:
|
|
li a7, 93 # exit
|
|
li a0, 1
|
|
ecall
|
|
|
|
|
|
segv:
|
|
li a7, 93 # exit
|
|
li a0, 0
|
|
ecall
|