0

I am trying to display the factorial of the current value of the index of a loop in MIPS but, my loop does not work at all. It keeps freezing every time I run the code. Let say I have a for loop such that (i=1; i<=5; i++), for each value of i, I would like to display the current factorial(i). The number 5, is actually provided by the user, in other words, the number can change(1-10). I have tried to figure out why my loop causes the code to freeze, but I have no clues so far. Your help will be very appreciated. The code is bellow.

    .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
4

1 回答 1

1

您的问题在exit_loop标签的说明中:

exit_loop:
   jr $ra   #return address

您再次跳入循环,因为您没有$ra在 main 函数开始时保存,并且在发出之前也没有恢复它jr

实际上,您的代码应该只是终止(syscall10)而不是发出跳转,因为您正在实现 main 函数而不是要从其他地方调用的函数。

所以,我将该代码更改为:

exit_loop:
  li $v0, 10
  syscall

再看看你的代码,你已经有了那个代码(在 label 上exit),所以你可能只是删除你的 exit_loop 代码并分支到exit而不是exit_looplooplabel 之后的分支中。

于 2013-04-30T16:01:29.607 回答