### Demo-Programm für MIPS für die Vorlesung ###
###        "Grundlagen der Informatik"       ###
###               Jörg Roth                  ###
###
### fakultaet: Berechnung von x!
### Die Berechnung erfolgt rekursiv durch die Regel
### - fakultaet(x) = 1 für x=1
### - fakultaet(x) = x*fakultaet(x-1) für x>1
### Wichtig hierbei: da fakultaet sich selbst rekursiv aufruft, muss
### vor dem Aufruf auch $ra gesichert werden. Das wäre nicht notwendig
### wenn im Inneren von fakultaet kein weiteres Unterprogramm mehr
### aufgerufen wird.
###

	.text

fakultaet:

     addi $sp,$sp,-12        # Auf dem Stapel Platz für 3 Register freimachen
     sw $s0,0($sp)           # Sichern der Register $s0,$s1, $ra auf den Stapel
     sw $s1,4($sp)
     sw $ra,8($sp)           # Wichtig: auch die Rücksprungadresse sichern

     ### Hier beginnt die eigentliche Arbeit des Unterprogramms fakultaet ###

     or $s0,$zero,$a0        # Lade Argument in $s0
     li $s1,1                # Lade 1 in $s1
     beq $s0,$s1,result1     # Ist das Argument=1 fertig
     addi $a0,$a0,-1         # Ansonsten: das neue Argument-1

     jal fakultaet           # fakultaet rekursiv aufrufen

     mult $s0,$v0            # Ergebnis mit dem Argument multiplizeren
     mflo $v0                # und als Ergebnis zurückliefern
     j end     

result1:
     li $v0,1                # Im Falle Argument=1: 1 zu zurückliefern
end:

     ### Hier endet die eigentliche Arbeit des Unterprogramms fakultaet ###

     lw $s0,0($sp)           # Zurücklesen der Register $s0,$s1, $ra von dem Stapel
     lw $s1,4($sp)
     lw $ra,8($sp)
     addi $sp,$sp,12         # Stapelzeiger auf Wert vor dem Aufruf setzen

     jr $ra                  # Rücksprung zum Aufrufer
     
main:
     li $v0, 5               # Eingabe einlesen
     syscall
     or $a0, $zero, $v0      # $a0 := Eingabe 

### Hier beginnt die Berechnung ###

     jal fakultaet 

### Hier endet die Berechnung ###

     or $a0, $zero, $v0      # in $v0 stand das Ergebnis
     li $v0, 1               # Resultat ausgeben
     syscall

