我正在试图用装配来弄清楚一些堆栈框架业务,我承认我不知道我在做什么......但我觉得我很接近?
我的程序调用一个从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 ######################################################################
答案 0 :(得分:1)
我能发现的第一个明显错误是你的
sw $s0, 8($s0) # save counter
行(2次出现)。鉴于您稍后从那里恢复sw $s0, 8($sp)
,您可能希望s0
。修复此问题并使用调试器查找更多错误(
更新:这也错了:
addu $fp, $sp, 32 # restore callers stack pointer
应该是addu $sp, $sp, 32
。