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