MIPS: Бесконечная петля с ответвлениями

#mips #infinite-loop #mars-simulator

Вопрос:

Поэтому у меня есть программа, которая принимает входные данные от пользователя (целое число выше 0) и суммирует все четные числа ниже него, чтобы получить ответ (например: ввод: 7; ответ: 2 4 6 = 12).

Проблема с этой программой заключается в том, что она предназначена для выхода из цикла на основе того, что моя «активная четная переменная» ($t1) > вход. Хотя моя программа, похоже, никогда должным образом не интерпретирует ветвь и циклы бесконечно, пока не переполнится $t1 (я проверил отладчик и знаю, что программа каждый раз запускает ветвь). Ниже приведен мой код:

 .data    N: .word 0 Result: .word 0   .text      .globl main initialize:  li $v0, 5 #getting arg1 from user  syscall  la $t0, N  sw $v0, 0($t0)    li $t1, 2  li $t2, 0 main:   blt $t0, $t1, fin2 fori:  add $t2, $t2, $t1 #t2  = t1  add $t1, $t1, 2 #t1  = 2    slt $t5, $t1, $t0  bne $t5, $zero, fori fin:      li $v0,1 #prints return value  move $a0, $t2  syscall    li $v0, 10  syscall  fin2:      li $v0,1 #prints return value  move $a0, $zero  syscall    li $v0, 10  syscall  

Ответ №1:

Поэтому я не знаю, нужно ли вам использовать хранилище слов и тому подобное, но на самом деле вы просто слишком усложняли это, делая это. Все, что вам было нужно, — это простой цикл, в котором счетчик увеличивается на 2, проверяет, больше ли он начального значения, а затем добавляет это общее значение к результату

 .text  .globl main  initialize:   li $v0, 5 # Getting arg1 from user  syscall # System call  move $t0, $v0 # Store the input value in $t0    li $t1, 0 # Initializing the result register  li $t2, 0 # Initializing the addition/counter register main:   loop:  add $t2, $t2, 2 # Increase the value to be added by 2 (next even value)  bge $t2, $t0, fin # Check if the increment is larger than or equal to the initial input, if so break to finish  add $t1, $t1, $t2 # Increment the result by adding the even value  j loop # jump bak to the top of the loop  fin:  li $v0,1 # let the system know an integer is going to be printed  move $a0, $t1 # Load the result into the $a0 register (the register that prints values)  syscall # System Call   li $v0, 10 # Let the system know the program is going to exit  syscall # System Call  

Так что, как вы можете видеть $t2 , каждый раз увеличивается на 2. После каждого приращения он сравнивается с входным значением. Если ввод ( $t0 ) , $t2 то добавьте значение $t2 в результат ( $t1 ). Таким образом, существует счетчик приращений, который также используется для добавления необходимого четного значения к результату.


Редактировать:

Не уверен, что это полностью то, что вы имели в виду, но я просто добавил несколько загрузок и сохранений, используя регистры s, поскольку именно они должны использоваться при сохранении значений.

 .data  N: .word 0 Result: .word 0  .text   .globl main  initialize:  li $v0, 5 # Getting arg1 from user  syscall # System Call  la $s0, N # Load the address of N into $s0  sw $v0, 0($s0) # Store the input value in 0 index of N    li $t2, 0 # Initializing the addition/counter register   la $s1, Result # Load the address of Result into $s1 main:   sw $t2, 0($s1) # Setting the 0 index of Result to 0 loop:  add $t2, $t2, 2 # Increase the value to be added by 2 (next even value)  lw $t4, 0($s0) # Loading the input value into the $t4 register  bge $t2, $t4, fin # Check if the increment is larger than or equal to the initial input, if so break to finish  lw $t4, 0($s1) # Loading the current result into the $t4 register  add $t4, $t4, $t2 # Increment the result by adding the even value  sw $t4, 0($s1) # Saving the new current result into the $t4 register  j loop # jump bak to the top of the loop  fin:  li $v0,1 # let the system know an integer is going to be printed  lw $a0, 0($s1) # Load the result into the $a0 register (the register that prints values)  syscall # System Call   li $v0, 10 # Let the system know the program is going to exit  syscall # System Call  

Комментарии:

1. Спасибо в пять раз, эта переработанная петля, казалось, сделала свое дело. Откровенно говоря, мне нужны были переменные, поскольку они были требованиями к моей программе (для загрузки/сохранения в N и результата), но ваше решение избавило меня от проблемы бесконечного цикла, с которой я столкнулся.

2. @CalebErnst, мое удовольствие 🙂 но вы должны были установить N для пользовательского ввода, а результат-для конечного результата или периодически обновлять его?

3. Нет необходимости периодически обновлять его, просто получите окончательный ответ и сохраните его в «Результате», N останется прежним и будет сохранен после инициализации. Но я смог сделать это сам, так что все хорошо.