Fakultät in assembler-code?

3 Antworten

Assembler schön und gut, aber welcher? Für welchen Prozessortyp?

Allgemein gesprochen (und meine Assemblertage sind ein wenig her) läuft das aus meiner Sicht nach folgendem Schema ab:

  1. Lade eine 1 in ein Register und die Zahl, von der die Fakultät gebildet werden soll in ein weiteres Register.
  2. Multipliziere beide Register und speichere das Ergebnis im 1. Register
  3. Dekrementiere das zweite Register um 1
  4. Wenn es größer ist als 0 gehe zu 2
  5. In Register 1 steht die Fakultät der Zahl
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

     li $v0, 10              # Programm beenden
     syscall


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
     

Ich garantiere nicht das es vollständig funktioniert.

Quelle: Link

Woher ich das weiß:Recherche

Wo ist das Problem? Rekursiv oder iterativ?

Kannst du es denn zB in Java oder einer anderen Sprache schreiben? Das Prinzip ist in Assembler gleich - nur sehen die Befehle etwas anders aus.

Woher ich das weiß:Studium / Ausbildung – Informatikstudium