Files
nand2tetris/MARS/Simulationen/Simulation 14 Fakultät/Simulation 14.asm
2025-03-26 09:10:55 +01:00

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 ##################