我正在尝试通过组装找出一些堆栈框架业务,我承认我不知道我在做什么......但我认为我很接近?
我的程序调用一个从 10 开始倒计时然后退出的子程序。这实际上似乎工作正常,但我收到一些异常错误。
这是我的输出
这是我的代码:
main: ######################################################################
################### SAVE STACK ###################
subu $sp, $sp, 32 # create 32 byte stack frame
########## save ra and fp
sw $ra, 0($sp) # save return address
sw $fp, 4($sp) # save frame pointer
#addu $fp, $sp, 28 # setup new frame pointer ?????
########## save general purpose registers
sw $s0, 8($s0) # save counter
##################################################
########## Begin Message
li, $v0, 4 # sys call #4, print string
la, $a0, STR_BEGIN # load string
syscall # execute call
li, $s0, 10 # init loop counter
########## Print Starting Point
li $v0, 1 # sys call #1, print int
move $a0, $s0 # load starting count
syscall # execute call
########## Call Subroutine
jal subroutine # call subroutine
# print something to show when it returns
########## END Message
#li, $v0, 4 # sys call #4, print string
#la, $a0, STR_END # load string
#syscall # execute call
################## RESTORE STACK #################
########## restore general purpose registers
lw $s0, 8($sp) # restore counter
########## restore ra and fp
lw $ra, 0($sp) # restore return address
lw $fp, 4($sp) # restore frame pointer
addu $fp, $sp, 32 # restore callers stack pointer
##################################################
ending: jr $31 # stop the program, why does this loop if i uncomment the above syscall?
subroutine: ######################################################################
################### SAVE STACK ###################
subu $sp, $sp, 32 # create 32 byte stack frame
########## save ra and fp
sw $ra, 0($sp) # save return address
sw $fp, 4($sp) # save frame pointer
addu $fp, $sp, 28 # setup new frame pointer ?????? why am i doing this?
########## save general purpose registers
sw $s0, 8($s0) # save counter
##################################################
sub $s0, $s0, 1 # decrement by one
########## Count Down
li, $v0, 4 # sys call #4, print string
la, $a0, STR_ELIPS # load string
syscall # execute call
li $v0, 1 # sys call #1, print int
move $a0, $s0 # load starting count
syscall # print output
########## subroutine condition
bgt $s0, 0, subroutine # if count < 10, then loop
################## RESTORE STACK #################
########## restore general purpose registers
lw $s0, 8($sp) # restore counter
########## restore ra and fp
lw $ra, 0($sp) # restore return address
lw $fp, 4($sp) # restore frame pointer
addu $fp, $sp, 32 # restore callers stack pointer
##################################################
jr $ra # return to caller
# END subroutine ######################################################################