	.data
LC:
	.asciiz "El factorial de 5 es: "

RET:
	.asciiz "\n"
	
	.text
	# ***** Loader *****
	
	jal main
	
	# stop
	li $v0, 10
	syscall
	
main:
        # ***** Prologo *****
	li $t0, 32
	subu $sp, $sp, $t0 	# Stack frame es de 32 bytes
	sw $ra, 20($sp) 	# Guarda la dirección de regreso
	sw $fp, 16($sp) 	# Guarda el frame pointer anterior
	addiu $fp, $sp, 28 	# Pone el frame pointer
	
	# ***** Codigo *****
        li $a0, 5               # Guarda el argumento (5) en $a0
        jal fact                # Llama a la función factorial
	la $a0, LC 		# Guarda el string de formato en $a0
	move $a1, $v0 		# Mueve el resultado de fact a $a1
        jal printf              # Llama a la función para imprimir
	
	# ***** Epilogo *****
	lw $ra, 20($sp) 	# Restaura $ra
	lw $fp, 16($sp) 	# Restaura el frame pointer
	addiu $sp, $sp, 32 	# Saca (pop) el stack frame
	jr $ra			# Regresa al llamador

fact:
        # ***** Prologo *****
	li $t0, 32
	subu $sp, $sp, $t0 	# Stack frame es de 32 bytes
	sw $ra, 20($sp) 	# Salva la dirección de regreso
	sw $fp, 16($sp) 	# Salva el frame pointer
	addiu $fp, $sp, 28 	# Pone el frame pointer
	sw $a0, 0($fp) 		# Salva el argumento (n)
	
	# ***** Codigo *****
	lw $v0, 0($fp) 		# Carga n
	bgtz $v0, L2 		# Brinca si n > 0
        li $v0,1                # Regresa 1
        j L1                    # Brinca para regresar
L2: 	lw $v1, 0($fp) 		# Carga n
	subu $v0, $v1, 1 	# Calcula n - 1
	move $a0, $v0 		# Mueve el valor a $a0
        jal fact                # Llama a fact
	lw $v1, 0($fp) 		# Carga n
	mul $v0, $v0, $v1 	# Calcula fact(n-1) * n

# ***** Epilogo *****
L1:                             # Resultado está en $v0
	lw $ra, 20($sp) 	# Restaura $ra
	lw $fp, 16($sp) 	# Restaura $fp
	addiu $sp, $sp, 32 	# Pop stack
	jr $ra 			# Regresa a main

printf:
        li $v0, 4               # PrintString
	syscall
	
        li $v0, 1               # PrintInteger
	move $a0, $a1
	syscall
	
	la $a0, RET
        li $v0, 4               # PrintString
	syscall

	jr $ra
