2013-04-30 2 views
0

Я пытаюсь отобразить факториал текущего значения индекса цикла в MIPS, но мой цикл не работает вообще. Он продолжает замерзать каждый раз, когда я запускаю код. Скажем, у меня есть цикл for такой, что (i = 1; i < = 5; i ++), для каждого значения i я хотел бы отобразить текущий факториал (i). Число 5, фактически предоставляется пользователем, другими словами, число может меняться (1-10). Я попытался выяснить, почему моя петля заставляет код замораживаться, но пока у меня нет никаких подсказок. Ваша помощь будет очень оценена. Код ниже.отображение факториала каждого значения индекса цикла не работает. MIPS

.data    # data declaration section; specifies values to be stored 
         # in memory and labels whereby the values are accessed 
Prompt: .asciiz "\nEnter the number to compute the factorial:\n" 
message: .asciiz "\nResult of computation is:\n" 

result: .word 0 


#-------------------------------- 
#  main function   | 
#-------------------------------- 

    .text    # Start of code section 
    .globl  main 
    main:    # Execution begins at label "main". The prompt is displayed. 


    li $v0, 4   # system call code for printing string = 4 
    la $a0, Prompt  # load address of string to be printed into $a0 
    syscall    # call operating system to perform operation; 
       # $v0 specifies the system function called; 
       # syscall takes $v0 (and opt arguments) 


# Read integer N    
    li $v0, 5 
    syscall 


    move $t0, $v0  #copy integer N into $t0 

    li $t1, 1  #initialize i=1 


loop: 
    blt $t0, $t1, exit_loop  # if number<1, exit... 
move $a0, $t0    # copy N into $ao 
jal fact    #else call fact 

sw $v0, result 


li $v0, 4   #Display message 
la $a0, message 
syscall 


li $v0, 1   #print result 
lw $a0, result 
syscall 

sub $t0, $t0, 1  #Decrement N by one, N-- 
j loop 



exit_loop: 
jr $ra #return address 



exit: #exit the program 
li $v0, 10 
syscall 


.globl fact 
.ent fact 
fact: 
    subu $sp, $sp, 8 
sw $ra, ($sp) 
sw $s0, 4($sp) 

li $v0, 1   #check base case 
beq $a0, 0, end_fact 

move $s0, $a0  #fact(n-1) 
sub $a0, $a0, 1 
jal fact 

mul $v0, $s0, $v0 #n*fact(n-1) 

end_fact: 

lw $ra ($sp) 
lw $s0, 4($sp) 
addu $sp,$sp, 8 
jr $ra 

#end of factorial function 

ответ

1

Ваша проблема заключается в инструкции на этикетке: exit_loop

exit_loop: 
    jr $ra #return address 

Вы снова прыгает в петлю, потому что вы не сохранили $ra в начале вашей основной функции, и вы также не восстанавливая его до выпуска jr

Фактически, ваш код, как есть, должен просто прекратить (syscall 10) и не выдавать прыжок, потому что вы выполняете главную функцию, а не функцию, вызываемую из других источников.

Таким образом, я бы изменить этот код на:

exit_loop: 
    li $v0, 10 
    syscall 

Глядя немного больше в код, у вас уже есть этот код (на этикетке exit), так что вы можете просто удалить код exit_loop и филиал до exit вместо exit_loop в отрасли, которая идет сразу после loop этикетки.

+0

Спасибо !!! он работает как ожидалось сейчас. – T4000

Смежные вопросы