64 lines
2.3 KiB
NASM
64 lines
2.3 KiB
NASM
############################################################
|
|
# 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 ##################
|