0x00400014处的运行时异常:地址超出范围0x7fbffffc

时间:2018-03-24 19:21:38

标签: assembly mips

我正在尝试编写一个递归函数,打印从1到X的数字,但是我得到了这个错误,特别是在sw $a0, 0($sp)

.data

.text

# Getting user input
li $v0, 5
syscall
move $a0, $v0

PrintUp: 
     addi $sp, $sp, -8   #make a stack for two element 
     sw   $ra, 4($sp)    #save the address
     sw   $a0, 0($sp)    #save the argument 
     beq  $t0, 0, EqZero  #if X=0, go to EqZero
     addi $sp, $sp, 8  #pop the elements
     jr   $ra    #return
EqZero:
     addi $a0, $a0, -1    #decrement i
     jal  PrintUp  #call the recursive function
     lw   $a0, 0($sp)
     lw   $a0, 4($sp)
     addi $sp, $sp, 8  #pop the elements
     li $v0, 1       
     syscall 
     jr   $ra    #return

1 个答案:

答案 0 :(得分:0)

我已经创建了两个版本的程序。一个带有bug的注释。一个清理和工作版本。请原谅无偿的风格清理。

以下是带注释的版本:

    .data

    .text

    # Getting user input
    li      $v0,5
    syscall
    move    $a0,$v0

# NOTE/BUG: doing fallthrough to PrintUp -- needs "jal PrintUp"

PrintUp:
    addi    $sp,$sp,-8              # make a stack for two element
    sw      $ra,4($sp)              # save the address
    sw      $a0,0($sp)              # save the argument

# NOTE/BUG: $t0 never set to anything -- should this be $a0?
    beq     $t0,0,EqZero            # if X=0, go to EqZero

# NOTE/BUG: does not restore $ra/$a0
    addi    $sp,$sp,8               # pop the elements
    jr      $ra                     # return

EqZero:
    addi    $a0,$a0,-1              # decrement i

    jal     PrintUp                 # call the recursive function

    lw      $a0,0($sp)

# NOTE/BUG: this should be $ra and not $a0
    lw      $a0,4($sp)
    addi    $sp,$sp,8               # pop the elements

# NOTE/BUG: this will only print the zero value
    li      $v0,1
    syscall

    jr      $ra                     # return

以下是更正后的版本:

    .data
nl:         .asciiz     "\n"

    .text
    .globl  main
main:

    # Getting user input
    li      $v0,5
    syscall
    move    $a0,$v0

    jal     PrintUp

    # exit program
    li      $v0,10
    syscall

PrintUp:
    addi    $sp,$sp,-8              # make a stack for two element
    sw      $ra,4($sp)              # save the address
    sw      $a0,0($sp)              # save the argument

    bne     $a0,0,NeZero            # if X!=0, go to NeZero

    addi    $sp,$sp,8               # pop the elements
    jr      $ra                     # return

NeZero:
    addi    $a0,$a0,-1              # decrement i

    jal     PrintUp                 # call the recursive function

    lw      $a0,0($sp)
    lw      $ra,4($sp)
    addi    $sp,$sp,8               # pop the elements

    li      $v0,1
    syscall
    move    $t0,$a0

    li      $v0,4
    la      $a0,nl
    syscall

    move    $a0,$t0
    jr      $ra                     # return