2013-04-13 55 views
0

我試圖找出一些堆棧框架業務與大會,我承認不知道我在做什麼......但我覺得我很接近?MIPS彙編子程序和堆棧,異常5壞數據地址,異常7存儲地址錯誤

我的程序調用一個從10開始倒數​​的子程序,然後退出。這實際上似乎工作正常,但我收到一些異常錯誤。

這裏是我的輸出

enter image description here

這裏是我的代碼:

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 ###################################################################### 

回答

1

第一個明顯的錯誤,我可以當場被你

sw $s0, 8($s0)    # save counter 

線(2次)。假設您稍後從那裏恢復s0,您可能需要sw $s0, 8($sp)。解決這個問題並使用調試器來查找更多錯誤。

更新:還這是錯誤的:

addu $fp, $sp, 32   # restore callers stack pointer 

大概應該是addu $sp, $sp, 32

+0

謝謝,我用櫃檯發現的第一個錯誤修復了所有錯誤。第二個變化似乎不會以任何方式影響程序。我的輸出看起來好多了,但現在當我的子程序退出時,它會在我的$ jr 31程序退出10次之前打印消息。 – SomeRandomDeveloper

+0

聽起來好像沒有正確保存我的返回地址,但我保存並恢復它,就像我應該,或者我認爲我應該反正。 – SomeRandomDeveloper

+0

此外'bgt $ s0,0,子程序'不應該跳回到函數的開始處,因爲它會再次完成整個框架設置。您應該跳回到您用「Count Down」標記的打印循環 – Jester