Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/arrays/12.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Arrays Mips程序无限循环问题_Arrays_Loops_Mips - Fatal编程技术网

Arrays Mips程序无限循环问题

Arrays Mips程序无限循环问题,arrays,loops,mips,Arrays,Loops,Mips,我现在正试图弄明白为什么我的火星程序创建阵列会陷入无限循环。我正在尝试使用不同的函数创建一个数组,在create array函数中,程序应该跳入一个get number函数并返回值以将其存储到数组中,但计数器似乎没有递减,它只是不断为数组请求一个元素。代码如下: .data str5: .asciiz "Please enter a number of elements for the array between 0 and 20: " str6: .asciiz "Please

我现在正试图弄明白为什么我的火星程序创建阵列会陷入无限循环。我正在尝试使用不同的函数创建一个数组,在create array函数中,程序应该跳入一个get number函数并返回值以将其存储到数组中,但计数器似乎没有递减,它只是不断为数组请求一个元素。代码如下:

.data   
str5:   .asciiz "Please enter a number of elements for the array between 0 and 20: "

str6:   .asciiz "Please enter an element: "

array:  .word 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0

.text

main:   

begin:
    li $v0, 4
    la $a0, str5
    syscall

    jal readnum
    add $a0, $v0, $0
    jal verify
    add $a0, $v0, $0
    jal createarray
    la $s1, array
    jal printarray

    li $v0, 10
    syscall

printarray:


createarray:
    add $t0, $ra, $0
    add $s0, $a0, $0
    add $t9, $0, $0

    la $s1, array

loop:
    beq $s0, 0, done

    li $v0, 4
    la $a0, str6
    syscall

    jal readnum
    add $t1, $v0, $0

    sw $t1, 0($s1)
    addi $s1, $s1, 4

    addi $s0, $s0, -1
    addi $t9, $t9, 1

    j loop

done:
    add $ra, $t0, $0
    jr $ra

verify:
    add $s0, $a0, $0

    bge $s0, 20, begin
    ble $s0, 0, begin

    add $v0, $s0, $0

    jr $ra

readnum:
    li $v0, 5
    syscall

    jr $ra

编辑:重新读取代码后,导致错误的实际上是以下代码:

jal printarray
您从未在printarray中执行过以下代码:

jr $ra
因此,它将返回到其他函数


使用
$sp
(在函数中调用函数时处理
$ra
的正确方法) 以下部分是问题的原因:

更具体地说是日航的呼叫。在函数中调用函数需要执行更多步骤

首先,了解
jal
指令在做什么。简而言之,
jal
指令标记您当前所在的位置,并将其存储在
$ra
寄存器中。然后,它将跳转到该函数

但是有一个问题:你已经希望
$ra
注册器记住你曾经在哪里,因为你实际上调用了
createarray

因此,您调用了
createarray
,使
$ra
存储在您曾经所在的位置,然后在该函数中调用了
readnum
,使
$ra
存储在
createarray
中**但是现在,您已经失去了以前被称为
createarray
的位置。因此,它将继续循环回到
$ra
以前的状态,它位于
createarray
函数中

幸运的是,
$sp
寄存器正是您所需要的

如何使用
$sp
寄存器 要存储我们所在的位置,我们推到堆栈:

addi    $sp,    $sp,    -4 # by convention, we use negative numbers when pushing
sw      $ra,    ($sp)
lw      $ra,    ($sp)
addi    $sp,    $sp,    4 # by convention, we use positive numbers when popping
为了在调用函数(首先替换了我们的
$ra
)后获得我们曾经的位置,我们弹出堆栈:

addi    $sp,    $sp,    -4 # by convention, we use negative numbers when pushing
sw      $ra,    ($sp)
lw      $ra,    ($sp)
addi    $sp,    $sp,    4 # by convention, we use positive numbers when popping
因此,在大范围内,以下是您所做的:

# push to the stack
addi    $sp,    $sp,    -4
sw      $ra,    ($sp)

jal     theFunctionWeWantToCallInOurFunction

# pop the stack, get back our $ra
lw      $ra,    ($sp)
addi    $sp,    $sp,    4
让我们将此解决方案应用于您的代码库:

.data   
str5:   .asciiz "Please enter a number of elements for the array between 0 and 20: "

str6:   .asciiz "Please enter an element: "

array:  .word 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0

.text

main:   

begin:
    li $v0, 4
    la $a0, str5
    syscall

    jal readnum
    add $a0, $v0, $0
    jal verify
    add $a0, $v0, $0
    jal createarray
    la $s1, array
    jal printarray # comment off this line and you won't have an infinite loop

    li $v0, 10
    syscall

printarray:


createarray:
    add $t0, $ra, $0
    add $s0, $a0, $0
    add $t9, $0, $0

    la $s1, array

loop:
    beq $s0, 0, done

    li $v0, 4
    la $a0, str6
    syscall

    # store where we wish to come back to so that $ra can be overriden without losing data.
    addi $sp, $sp, -4
    sw $ra, ($sp)

    # call the function. jal will replace our current $ra
    jal readnum

    # retrieve what our $ra once was
    lw $ra, ($sp)
    addi $sp, $sp, 4 

    add $t1, $v0, $0

    sw $t1, 0($s1)
    addi $s1, $s1, 4

    addi $s0, $s0, -1
    addi $t9, $t9, 1

    j loop

done:
    add $ra, $t0, $0
    jr $ra

verify:
    add $s0, $a0, $0

    bge $s0, 20, begin
    ble $s0, 0, begin

    add $v0, $s0, $0

    jr $ra

readnum:
    li $v0, 5
    syscall

    jr $ra

编辑:重新读取代码后,导致错误的实际上是以下代码:

jal printarray
您从未在printarray中执行过以下代码:

jr $ra
因此,它将返回到其他函数


使用
$sp
(在函数中调用函数时处理
$ra
的正确方法) 以下部分是问题的原因:

更具体地说是日航的呼叫。在函数中调用函数需要执行更多步骤

首先,了解
jal
指令在做什么。简而言之,
jal
指令标记您当前所在的位置,并将其存储在
$ra
寄存器中。然后,它将跳转到该函数

但是有一个问题:你已经希望
$ra
注册器记住你曾经在哪里,因为你实际上调用了
createarray

因此,您调用了
createarray
,使
$ra
存储在您曾经所在的位置,然后在该函数中调用了
readnum
,使
$ra
存储在
createarray
中**但是现在,您已经失去了以前被称为
createarray
的位置。因此,它将继续循环回到
$ra
以前的状态,它位于
createarray
函数中

幸运的是,
$sp
寄存器正是您所需要的

如何使用
$sp
寄存器 要存储我们所在的位置,我们推到堆栈:

addi    $sp,    $sp,    -4 # by convention, we use negative numbers when pushing
sw      $ra,    ($sp)
lw      $ra,    ($sp)
addi    $sp,    $sp,    4 # by convention, we use positive numbers when popping
为了在调用函数(首先替换了我们的
$ra
)后获得我们曾经的位置,我们弹出堆栈:

addi    $sp,    $sp,    -4 # by convention, we use negative numbers when pushing
sw      $ra,    ($sp)
lw      $ra,    ($sp)
addi    $sp,    $sp,    4 # by convention, we use positive numbers when popping
因此,在大范围内,以下是您所做的:

# push to the stack
addi    $sp,    $sp,    -4
sw      $ra,    ($sp)

jal     theFunctionWeWantToCallInOurFunction

# pop the stack, get back our $ra
lw      $ra,    ($sp)
addi    $sp,    $sp,    4
让我们将此解决方案应用于您的代码库:

.data   
str5:   .asciiz "Please enter a number of elements for the array between 0 and 20: "

str6:   .asciiz "Please enter an element: "

array:  .word 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0

.text

main:   

begin:
    li $v0, 4
    la $a0, str5
    syscall

    jal readnum
    add $a0, $v0, $0
    jal verify
    add $a0, $v0, $0
    jal createarray
    la $s1, array
    jal printarray # comment off this line and you won't have an infinite loop

    li $v0, 10
    syscall

printarray:


createarray:
    add $t0, $ra, $0
    add $s0, $a0, $0
    add $t9, $0, $0

    la $s1, array

loop:
    beq $s0, 0, done

    li $v0, 4
    la $a0, str6
    syscall

    # store where we wish to come back to so that $ra can be overriden without losing data.
    addi $sp, $sp, -4
    sw $ra, ($sp)

    # call the function. jal will replace our current $ra
    jal readnum

    # retrieve what our $ra once was
    lw $ra, ($sp)
    addi $sp, $sp, 4 

    add $t1, $v0, $0

    sw $t1, 0($s1)
    addi $s1, $s1, 4

    addi $s0, $s0, -1
    addi $t9, $t9, 1

    j loop

done:
    add $ra, $t0, $0
    jr $ra

verify:
    add $s0, $a0, $0

    bge $s0, 20, begin
    ble $s0, 0, begin

    add $v0, $s0, $0

    jr $ra

readnum:
    li $v0, 5
    syscall

    jr $ra