1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
|
.data
eingabe: .asciiz "Geben Sie eine Zahl ein: "
ausgabe: .asciiz "Ergebnis: "
.text
main: la $a0, eingabe # "Geben Sie eine Zahl ein: " ausgeben
li $v0, 4
syscall
li $v0, 5 # Zahl einlesen
syscall
move $t0, $v0 # Eingabe sichern, $t0:=$v0, das heißt meine Eingabe steckt jetzt in $t0
move $a0, $t0 # in $a0 steckt mein Argument für den Prozeduraufruf, meine Eingabe
jal fak # Fakultäts- Prozedur aufrufen
la $a0, ausgabe # "Ergebnis: " ausgeben
li $v0, 4
syscall
move $a0, $v0 # $a0:=$v0 (in $v0 ist das Funktionsergebnis meiner Prozedur)
li $v0, 1 # Integer in $a0 wird ausgeben
syscall
li $v0, 10 # terminieren
syscall
fak: addi $sp, $sp -8 # $sp dekrementieren, auf dem Stack Platz für 2 Register machen
sw $ra, 8($sp) # $ra liegt auf dem erstem freien Platz, Rücksprungadresse wird auf den Stack gelegt
sw $a0, 4($sp) # $a0 liegt auf dem zweitem freien Platz, übergebenes Argument wird auf den Stack gelegt
bltz $a0, negativeZahl # n($a0) < 0
beqz $a0, null # n($a0) == 0
bgtz $a0, else # n($a0) > 0
addi $v0, $zero, 1 #
addi $sp, $sp, 8 # $sp wieder inkrementieren
jr $ra
negativeZahl: li $v0, -1 # return -1
jr $ra # jr ermöglicht den Sprung an eine erst zur Laufzeit ermittelte Stelle im Programm; $ra enthält nach Aufruf des Befehls jal die Rücksprungadresse
null: li $v0, 1 # return 1
jr $ra # jr ermöglicht den Sprung an eine erst zur Laufzeit ermittelte Stelle im Programm; $ra enthält nach Aufruf des Befehls jal die Rücksprungadresse
else: sub $a0, $a0, 1 # $a0:=$a0 - 1, n - 1
jal fak # rekursiver Aufruf mit $a -1 (n-1)
lw $ra, 8($sp)
lw $a0, 4($sp)
addi $sp, $sp, 8
mul $v0, $v0, $a0 # $v0:=$v0 * $a0, n * (n - 1) #??? ist das hier richtig? muss ich die multiplikation nicht vielleicht vor dem rekursiven aufruf haben? damit auch jedes n, n-1, -2 mitmultipliziert wird?
jr $ra
|