# # Exemple de calcul del factorial passant l'unic parametre per la pila, per # tant, no se segueix el conveni MIPS o gcc. # # El compilador de MIPS sempre reserva un espai de 32 bytes pel "bloc # d'activacio de les funcions" a on es guarden els registres $ra i $fp, tot # i que no s'ocupi del tot ($ra es guarda. # Com que aquest codi es generat a ma, es reserva l'espai just (8 bytes). # .text # Primer segment de text (codi) main: # Funcio principal 'main' subu $sp, $sp, 8 # Reservar espai pels registres a salvar sw $ra, 0($sp) # Salvar l'adreça de retorn ja que es modificara sw $fp, 4($sp) # Salvar el Frame Pointer ja que es modificara addu $fp, $sp, 8 # Establir el Frame Pointer per 'main' la $a0, Cadena # Adreça de la cadena a $a0 li $v0, 4 # Funcio escriure cadena (print_string) syscall # Crida al sistema # Cridar 'Fact' per calcular el factorial de 10 li $t0, 10 # Parametre de 'Fact': 10 addi $sp, $sp, -4 # Reservar espai de pila pel parametre sw $t0, 0($sp) # Escriure el parametre a la pila jal Fact # Crida a 'Fact' addi $sp, $sp, 4 # Eliminar l'espai de pila reservat pel parametre # 'Fact' ha retornat el resultat a $v0 move $a0, $v0 # El resultat es el parametre de print_int li $v0, 1 # Funcio escriure enter (print_int) syscall # Crida al sistema or $v0, $0, $0 # Retornar un 0 al Sistema Operatiu (Spim) lw $ra, 0($sp) # Restaurar l'adreça de retorn salvada lw $fp, 4($sp) # Restaurar l'antic Frame Pointer salvat addu $sp, $sp, 8 # Eliminar espai de pila reservat j $ra # Retorn al Sistema Operatiu (Spim) .end .text # Segon segment de text (codi) Fact: # Funcio 'Fact ( n )' que calcula el factorial subu $sp, $sp, 8 # Reservar espai pels registres a salvar sw $ra, 0($sp) # Salvar l'adreça de retorn ja que es modificara sw $fp, 4($sp) # Salvar el Frame Pointer ja que es modificara addu $fp, $sp, 8 # Establir el Frame Pointer per 'Fact' # El registre $fp apuntara al darrer parametre lw $t0, 0($fp) # Obtenir el parametre 'n' a partir de $fp bgtz $t0, Recursiu # Si n > 0 => Crida recursiva li $v0, 1 # n == 0 => fact ( 0 ) = 1 j FiFact # Sortir de la funcio 'Fact' Recursiu: lw $t0, 0($fp) # Carregar 'n' salvat a la pila subu $t0, $t0, 1 # Calcular n - 1 a $t0 => Nou parametre de 'Fact' addi $sp, $sp, -4 # Reservar espai a la pila pel parametre sw $t0, 0($sp) # Guardar el parametre a la pila jal Fact # Crida recursiva addi $sp, $sp, 4 # Eliminar l'espai de pila reservat pel parametre # 'Fact' ha retornat el resultat a $v0 lw $t0, 0($fp) # Obtenir 'n' guardat a la pila a $t0 mul $v0, $v0, $t0 # Calcular Fact ( n - 1 ) * n FiFact: lw $31, 0($sp) # Restaurar adreça de retorn salvada lw $fp, 4($sp) # Restaurar el Frame Pointer salvat addu $sp, $sp, 8 # Eliminar espai de pila reservat j $31 # Retornar de 'Fact' .end .data # Segment de dades: La cadena Cadena: .asciiz "El factorial de 10 es " .end