RISC-V 32-bit Architecture - My Stack Dump

Example One

# ======================================================================== # 32-bit architecture stack dump function # # print the stack from a higher memory address to a lower memory address # (top to bottom) For example: # # ------ high memory ------ # 4 0x7fffeff8 0x00000063 # 3 0x7fffeff4 0x0000002a # 2 0x7fffeff0 0x00000000 # 1 0x7fffefec 0x000abcde # 0 0x7fffefe8 0x000000ff # ------ low memory ------- <- sp/fp # # ======================================================================== # ------------------------------------------------------------------------ # data # ------------------------------------------------------------------------ .data newline: .asciz "\n" space2: .asciz " " space1: .asciz " " separator1: .asciz "------ high memory ------\n" separator2: .asciz "------ low memory ------- <-sp/fp\n" # macros .macro push(%reg) addi sp,sp,-4 sw %reg,0(sp) .end_macro .macro pop(%reg) lw %reg,0(sp) addi sp,sp,4 .end_macro # ------------------------------------------------------------------------ # text # ------------------------------------------------------------------------ .text .global main stack_dump: # -------------------------------------------------------------------- # function Prologue # -------------------------------------------------------------------- addi sp, sp, -12 # allocate space for a stack frame sw ra, 8(sp) # Save return address sw a0, 4(sp) # save char address (a0) sw a1, 0(sp) # save display count (a1) # -------------------------------------------------------------------- # fuction body # -------------------------------------------------------------------- # initialize loop variables # t0 = highest memory address of stack dump # t1 = countdowm counter addi t1, a1, -1 # change counter range (1 to 5 to 0 to 4) li t2, 4 # 4 bytes per word mul t2, t1, t2 # multiply counter by 4 bytes per word add t0, a0, t2 # new starting address # (highest memory address) # print separator 1 li a7, 4 # syscall code, print string la a0, separator1 # load address of string to print ecall # syscall stack_dump_loop: # end of loop? if counter < 0, exit loop blt t1, zero, end_stack_dump # print counter li a7, 1 # syscall code, print integer (decimal) mv a0, t1 # loop counter ecall # syscall # print spaces li a7, 4 # syscall code, print string la a0, space2 # load address of string into a0 ecall # syscall # print address li a7, 34 # syscall code, print integer (hexadecimal) mv a0, t0 # stack address ecall # syscall # print spaces li a7, 4 # syscall code, print string la a0, space2 # address of string ecall # syscall # print value li a7, 34 # syscall code, print integer (hexadecimal) lw a0, 0(t0) # load word from memory into a0 ecall # syscall # print newline li a7, 4 # syscall code, print string la a0, newline # address of string ecall # syscall # next stack location addi t0, t0, -4 # next stack word address addi t1, t1, -1 # decrement loop counter j stack_dump_loop # jump to beginning of loop end_stack_dump: # print separator 2 li a7, 4 # syscall code, print string la a0, separator2 # load address of string ecall # syscall # -------------------------------------------------------------------- # function epilogue # -------------------------------------------------------------------- lw ra, 8(sp) # restore return address lw a0, 4(sp) # restore a0 lw a1, 0(sp) # restore a1 addi sp, sp, 12 # deallocate stack space ret # return to caller # ------------------------------------------------------------------------ # main # ------------------------------------------------------------------------ main: # create stack of test values li t0, 99 push(t0) li t0, 42 push(t0) mv t0, zero push(t0) li t0, 0xABCDE push(t0) li t0, 0xff push(t0) # dump stack (sp or fp) mv a0, sp # sp or fp li a1, 5 # dump count call stack_dump # call function # exit program; returned code is zero li a0, 0 # returned code li a7, 93 # syscall code, exit program ecall # syscall

Example Two

# ======================================================================== # 32-bit architecture stack dump function # # print the stack from a lower memory address to a higher memory address # (top to bottom) For example: # # ------ low memory ------- <-sp/fp # 0 0x7fffefe8 0x000000ff # 1 0x7fffefec 0x000abcde # 2 0x7fffeff0 0x00000000 # 3 0x7fffeff4 0x0000002a # 4 0x7fffeff8 0x00000063 # ----- high memory ------- # # ======================================================================== # ------------------------------------------------------------------------ # data # ------------------------------------------------------------------------ .data newline: .asciz "\n" space2: .asciz " " space1: .asciz " " separator1: .asciz "------ low memory ------- <-sp/fp\n" separator2: .asciz "----- high memory -------\n" .macro push(%reg) addi sp,sp,-4 sw %reg,0(sp) .end_macro .macro pop(%reg) lw %reg,0(sp) addi sp,sp,4 .end_macro # ------------------------------------------------------------------------ # text # ------------------------------------------------------------------------ .text .global main dump_stack: # -------------------------------------------------------------------- # function Prologue # -------------------------------------------------------------------- addi sp, sp, -12 # allocate space for stack frame sw ra, 8(sp) # save return address sw a0, 4(sp) # save char address (a0) sw a1, 0(sp) # save display count (a1) # -------------------------------------------------------------------- # fuction body # -------------------------------------------------------------------- # print separator 1 li a7, 4 # syscall code, print string la a0, separator1 # load address of string to print ecall # syscall # initialize loop variables lw t0, 4(sp) # stack address lw t2, 0(sp) # display count addi t2, t2, -1 # change counter range (1 to 5 to 0 to 4) mv t1, zero # reverse counter print_stack_loop: # end of loop? if counter < 0, exit loop bgt t1, t2, end_stack_dump # print counter li a7, 1 # syscall code, print integer (in decimal) mv a0, t1 # loop counter ecall # syscall # print spaces li a7, 4 # syscall code, print string la a0, space2 # load address of string to print into a0 ecall # syscall li a7, 34 # syscall code, print integer (hexadecimal) mv a0, t0 # stack address ecall # syscall # print address li a7, 4 # syscall code, print string la a0, space2 # address of string ecall # syscall # print value li a7, 34 # syscall code, print integer (hexadecimal) lw a0, 0(t0) # load word from memory ecall # syscall # print newline li a7, 4 # syscall code, print string la a0, newline # address of string ecall # syscall # advance to the next stack value addi t0, t0, 4 # address next word in stck addi t1, t1, 1 # increment loop counter j print_stack_loop # jump to beginning of loop end_stack_dump: # print separator 2 li a7, 4 # syscall code, print string la a0, separator2 # load address of string to print ecall # syscall # -------------------------------------------------------------------- # function epilogue # -------------------------------------------------------------------- lw ra, 8(sp) # restore return address lw a0, 4(sp) # restore a0 lw a1, 0(sp) # restore a1 addi sp, sp, 12 # deallocate stack space ret # return to caller # ------------------------------------------------------------------------ # main # ------------------------------------------------------------------------ main: # create stack test values li t0, 99 push(t0) li t0, 42 push(t0) mv t0, zero push(t0) li t0, 0xABCDE push(t0) li t0, 0xff push(t0) # dump stack (sp or fp) mv a0, sp li a1, 5 call dump_stack # exit program, returned code is zero li a0, 0 # returned code li a7, 93 # syscall number, exit program ecall # syscall