我不断得到一个地址超出范围错误,我无法弄清楚原因

时间:2016-09-10 01:42:55

标签: arrays mips runtimeexception mars-simulator

我正在进行一个接受命令行参数的赋值,并通过解析将其转换为两个“软”数组。我的意思是它们没有在MIPS中声明为数组。

无论如何,我正在尝试做的是获取第一个数组并将第二个数组中的相应元素添加到第一个数组中的相同元素,使用就地添加。读取元素并获取元素总和没有问题,但每当我尝试将元素放回$s1时,我都会遇到address out of range错误。

# $s0 contains the number of elements per array
# $s1 contains the address of the first array of integers
# $s2 contains the address of the second array of integers

# Your job is to implement array addition in-place.
# When the program ends, the first array should contain
# the the sum of each pair of elements.
#
# E.g. (here the value in $s0 would be 3)
# value of the arrays before:
# [1 2 3] [4 5 6]
# value of the arrays after:
# [5 7 9] [4 5 6]

# YOUR SOLUTION GOES HERE

#Counter at $t2 and $t5
addi $t5, $zero, 0

array1Loop:
beq $t5, $s0, exit
lbu $t4, 0($s1)
lbu $t6, 0($s2)

add $t7, $t4, $t6
move $s4, $t7
move $s1, $s4


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



addi $s1, $s1, 4 #increases index by 4
addi $s2, $s2, 4 #increases index by 4
addi $s4, $s4, 4

addi $t5, $t5, 1 #increased counter $t5
j array1Loop


exit:
# exit cleanly
li $v0, 10
syscall 

我从lbu $t4, 0($s1)收到错误。我正在尝试将$s1替换为$s4,但这会导致错误。

1 个答案:

答案 0 :(得分:0)

您的程序有一些错误。但是,我已经检查了你的循环逻辑,这是正确的。

lbu错了。 但是,只会产生不正确的结果而会导致崩溃。

通常,程序启动时的寄存器值可以。因此,除了显示的内容之外,某些代码必须先设置s0, s1, s2,然后才能输入 发布的代码。

因此,如果您遇到崩溃,那是因为这些寄存器在进入您的代码时 未正确设置。你有其他代码[你做了帖子],这是问题的根本原因。

您提到您正在解析命令行选项并创建" soft"阵列。我不确定你的意思[尽管有你的解释],因为它们必须放在[可访问的]内存中(例如sbrk系统调用?)。

并且,我非常熟悉mars [我甚至破解了它的java代码]。如果指定要传递给程序的命令行参数,则会禁用GUI [和调试器等]。因此,尝试使用argcargv可能很难调试[因为您无法使用调试器 - 类似于捕获22]。

您的代码正在打印总和,但实际上并未根据需要将其存储到第一个数组中。

我创建了两个版本。一个用bug注释的。并且,一个完全清理和工作的版本,有一些示例代码用于设置s*寄存器[请原谅无偿的样式清理]

以下是带注释的版本:

# $s0 contains the number of elements per array
# $s1 contains the address of the first array of integers
# $s2 contains the address of the second array of integers
#
# Your job is to implement array addition in-place.
# When the program ends, the first array should contain
# the the sum of each pair of elements.
#
# E.g. (here the value in $s0 would be 3)
# value of the arrays before:
# [1 2 3] [4 5 6]
# value of the arrays after:
# [5 7 9] [4 5 6]

    # YOUR SOLUTION GOES HERE

    # Counter at $t2 and $t5
    # NOTE: $t2 is unused
    # NOTE: this is used like index variable
    addi    $t5,$zero,0

array1Loop:
    beq     $t5,$s0,exit            # done yet? if so, fly

    # NOTE/BUG: the arrays are integers, so the inst is "lw" and _not_ "lbu"
    lbu     $t4,0($s1)              # fetch from 1st array
    lbu     $t6,0($s2)              # fetch from 2nd array

    add     $t7,$t4,$t6             # sum the array values

    # NOTE/BUG: we're saving the the results in a register but _not_ writing
    # back to the first array
    move    $s4,$t7                 # save the sum
    move    $s1,$s4                 # save the sum

    # print the sum
    # NOTE/BUG: we should output a space to separate the numbers first
    li      $v0,1
    move    $a0,$s4
    syscall

    # NOTE: these are _pointers_ and not indexes
    # NOTE/BUG: when adding addresses/pointers, use the unsigned add to
    # prevent possible overflow exceptions
    addi    $s1,$s1,4               # increases index by 4
    addi    $s2,$s2,4               # increases index by 4

    # NOTE/BUG: this is not needed
    addi    $s4,$s4,4               # what???

    # NOTE: this is an index variable
    addi    $t5,$t5,1               # increased counter $t5
    j       array1Loop

exit:
    # exit cleanly
    li      $v0,10
    syscall

这是清理后的工作版本:

# $s0 contains the number of elements per array
# $s1 contains the address of the first array of integers
# $s2 contains the address of the second array of integers
#
# Your job is to implement array addition in-place.
# When the program ends, the first array should contain
# the the sum of each pair of elements.
#
# E.g. (here the value in $s0 would be 3)
# value of the arrays before:
# [1 2 3] [4 5 6]
# value of the arrays after:
# [5 7 9] [4 5 6]

    .globl  main
main:
    li      $s0,7
    la      $s1,arr1
    la      $s2,arr2

    # YOUR SOLUTION GOES HERE

    # registers:
    #   t4 -- value from first array
    #   t5 -- array index
    #   t6 -- value from second array
    #   t7 -- sum of array values
    li      $t5,0

array1Loop:
    beq     $t5,$s0,exit            # done yet? if so, fly

    lw      $t4,0($s1)              # fetch from 1st array
    lw      $t6,0($s2)              # fetch from 2nd array

    add     $t7,$t4,$t6             # sum the array values

    sw      $t7,0($s1)              # store sum back into first array

    # print the sum
    li      $v0,1
    move    $a0,$t7
    syscall

    # print a newline
    li      $v0,4
    la      $a0,newline
    syscall

    addiu   $s1,$s1,4               # advance first array's pointer
    addiu   $s2,$s2,4               # advance second array's pointer

    addi    $t5,$t5,1               # advance array index
    j       array1Loop

exit:
    # exit cleanly
    li      $v0,10
    syscall

    .data
arr1:       .word 1,2,3,4,5,6,7
arr2:       .word 11,22,33,44,55,66,77
newline:        .asciiz     "\n"