############################################################ # Berechnung der Fakultaet von n, also n! # ############################################################ .data prompt: .asciiz "\nBitte geben Sie die Zahl ein, deren Fakultaet berechnet werden soll: n = " message: .asciiz "\n Die Fakultaet von n ist:\n n! = " .text main: # n einlesen und in $a0 ablegen la $a0, prompt # Laden der Adresse des Strings prompt li $v0, 4 # Der Wert 4 fuer den syscall bedeutet print string syscall # Ausgabe des Strings prompt li $v0, 5 # der Wert 5 fuer den syscall bedeutet read integer syscall # n in $v0 einlesen move $a0, $v0 # n in $a0 ablegen # Wert fuer die Abbruchbedingung li $s1, 1 # Aufruf des Unterprogramms fac jal fac move $t0, $v0 # in $v0 stand das Ergebnis, ablegen in $t0 la $a0, message # Laden der Adresse des Strings message li $v0, 4 # der Wert 4 fuer den syscall bedeutet print string syscall # Ausgabe des Strings message move $a0, $t0 # Laden des Ergebnisses in $a0 li $v0, 1 # der Wert 1 fuer den syscall bedeutet print integer syscall # Ausgabe des Ergebnisses # exit li $v0, 10 syscall #################### Unterprogramm fac ##################### fac: addi $sp, $sp, -8 # Auf dem Stack Platz fuer 2 Eintraege schaffen sw $s0, 0($sp) # Sichern des Registers $s0 sw $ra, 4($sp) # Sichern der Ruecksprungadresse add $s0,$zero,$a0 # laedt das Argument in $s0 beq $s0, $s1, done # wenn das Argument = 1 ist, springe zur Marke done, Abbruchbedingung addi $a0, $a0, -1 # dekrementiere das Argument (n-1) # rekursiver Aufruf mit n-1 jal fac # hierhin wird bei Rueckkehr aus fac gesprungen, wenn fac sich selbst aufgerufen hat mult $s0, $v0 # Ergebnis mit dem Argument multiplizieren mflo $v0 # Produkt als Ergebnis zurueckgeben j end # Sprung zur Marke end done: # diese Zeile wird nur einmal ausgefuehrt, wenn fac mit a0=1 aufgerufen wurde li $v0, 1 # ist das Argument = 1, wird 1 zurueckgegeben end: lw $s0, 0($sp) # Zuruecklesen des Registers $s0 vom Stack lw $ra, 4($sp) # Zuruecklesen der Ruecksprungsadresse vom Stack addi $sp, $sp, 8 # Stackpointer wieder auf den Wert vor Aufruf des Unterprogramms setzen jr $ra # Ruecksprung ################# Ende des Unterprogramms fac ##################