#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 останется прежним и будет сохранен после инициализации. Но я смог сделать это сам, так что все хорошо.