# # Autor(s) : Jordi Ferrer Plana # e-mail : jferrerp@eia.udg.es # Branch : Estructura i Tecnologia de Computadors (ETIS/ETIG) # # Working Group : Departament d'Electrònica, Informàtica i Automàtica # Project : Exemples # # Homepage : http://eia.udg.es/etc/ # # Module : Càlcul del factorial recursivament en assemblador # de MIPS (SPIM). # # File : fact_pila.s # Date : 16/05/2003 - 16/05/2003 # Encoding : ISO-8859-1 (Latin-1) # # Compiler : SPIM >= ver. 6.5 # Libraries : - # # Notes : - Realitza el factorial d'un valor d'entrada utilitzant # una funció recursiva. # - Exemple de càlcul del factorial passant l'únic # paràmetre 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'activació 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 és generat a ma, es reserva l'espai # just (8 bytes). # # ---------------------------------------------------------------------------- # # Copyright (C) 2002-2003, Jordi Ferrer Plana # # This program is free software; you can redistribute it and/or # modify it under the terms of the GNU General Public License # as published by the Free Software Foundation; either version 2 # of the License, or (at your option) any later version. # # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. # # See the GNU General Public License (http://www.gnu.org/copyleft/) # for more details. # # ---------------------------------------------------------------------------- # .text # Primer segment de text (codi) main: # Funció 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 modificarà sw $fp, 4($sp) # Salvar el Frame Pointer ja que es modificarà addu $fp, $sp, 8 # Establir el Frame Pointer per 'main' la $a0, Cadena # Adreça de la cadena a $a0 li $v0, 4 # Funció escriure cadena (print_string) syscall # Crida al sistema # Cridar 'Fact' per calcular el factorial de 10 li $t0, 10 # Paràmetre de 'Fact': 10 addi $sp, $sp, -4 # Reservar espai de pila pel paràmetre sw $t0, 0($sp) # Escriure el paràmetre a la pila jal Fact # Crida a 'Fact' addi $sp, $sp, 4 # Eliminar l'espai de pila reservat pel paràmetre # 'Fact' ha retornat el resultat a $v0 move $a0, $v0 # El resultat és el paràmetre de print_int li $v0, 1 # Funció 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: # Funció '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 modificarà sw $fp, 4($sp) # Salvar el Frame Pointer ja que es modificarà addu $fp, $sp, 8 # Establir el Frame Pointer per 'Fact' # El registre $fp apuntarà al darrer paràmetre lw $t0, 0($fp) # Obtenir el paràmetre '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 funció 'Fact' Recursiu: lw $t0, 0($fp) # Carregar 'n' salvat a la pila subu $t0, $t0, 1 # Calcular n - 1 a $t0 => Nou paràmetre de 'Fact' addi $sp, $sp, -4 # Reservar espai a la pila pel paràmetre sw $t0, 0($sp) # Guardar el paràmetre a la pila jal Fact # Crida recursiva addi $sp, $sp, 4 # Eliminar l'espai de pila reservat pel paràmetre # '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 és " .end