rekursion.asm

Aus C64-Wiki
Zur Navigation springenZur Suche springen


 ;####################################################################
 ;# Programm:      Beispiel für Rekursion
 ;# Dateiname:     rekursion.asm
 ;#
 ;# Assembler:     ACME
 ;# Assemblierung: acme -f cbm -o rekursion.prg rekursion.asm
 ;#
 ;# Laden mit:     LOAD"rekursion.prg",8,1
 ;#
 ;# Speicher:      Belegt den Bereich $c000 bis $c047
 ;#                Benutzt den Bereich $c100 bis c10f
 ;#
 ;# Aufruf mit:    jsr $c000; das Ergebnis liegt im Speicher im
 ;#                Bereich $c100 bis $c10f
 ;#
 ;# Quelltext:     * Kleinschreibung (bis auf Kommentare)
 ;#                * nur Leerzeichen, keine Tabulatoren
 ;#                * Labels immer in eigener Zeile
 ;#                * Befehle zwei Zeichen eingerückt
 ;#                * Kommentare i.d.R. nach den Befehlen
 ;#
 ;# Beschreibung:  Dieses Programm demonstriert den rekursiven Aufruf
 ;#                einer Funktion. Nach dem ersten Aufruf ruft sich
 ;#                die Funktion siebenmal selbst auf.
 ;#                
 ;#                In G-Pascal sieht das Programm folgendermaßen
 ;#                aus:
 ;#                
 ;#                PROCEDURE REC(I,V);
 ;#                BEGIN
 ;#                  WRITELN (V);
 ;#                  IF I < 8 THEN
 ;#                    REC(I + 1, V * 2);
 ;#                  V := V XOR 255;
 ;#                  WRITELN (V);
 ;#                END ;
 ;#                
 ;#                BEGIN
 ;#                  REC(1, 1);
 ;#                END .
 ;#                
 ;#                Die Berechnungen für v (Multiplikation mit zwei
 ;#                und Invertierung mit xor 255) sind so gewählt,
 ;#                dass man in der binären Darstellung den Verlauf
 ;#                der Rekursion gut erkennen kann.
 ;#                
 ;# Ergebnis:      $c100: 00000001 ($01)
 ;#                $c101: 00000010 ($02)
 ;#                $c102: 00000100 ($04)
 ;#                $c103: 00001000 ($08)
 ;#                $c104: 00010000 ($10)
 ;#                $c105: 00100000 ($20)
 ;#                $c106: 01000000 ($40)
 ;#                $c107: 10000000 ($80)
 ;#                $c108: 01111111 ($7f)
 ;#                $c109: 10111111 ($bf)
 ;#                $c10a: 11011111 ($df)
 ;#                $c10b: 11101111 ($ef)
 ;#                $c10c: 11110111 ($f7)
 ;#                $c10d: 11111011 ($fb)
 ;#                $c10e: 11111101 ($fd)
 ;#                $c10f: 11111110 ($fe)
 ;#                
 ;####################################################################
 
 
 ; -- Startadresse --
 
   *=$c000
 
 
 ;####################################################################
 ;#
 ;# Speicherstellen
 ;#
 ;####################################################################
 
   !addr out = $c100
   !addr v =   $0334
   !addr x =   $0335
 
 
 ;####################################################################
 ;#
 ;# Programmstart
 ;#
 ;####################################################################
   
   jmp start
 
 
 ;####################################################################
 ;#
 ;# Rekursiv aufgerufene Funktion
 ;#
 ;####################################################################
 
 rec
   lda v      ; print(v)
   sta out,y
   iny
 
   ldx x      ; if i < 8
   cpx #8
   bcs +
 
   ; Bevor die Funktion sich selbst aufruft, müssen
   ; alle Variablen (Inhalte der Speicherstellen)
   ; auf dem Stack gesichert werden
   pha        ; v retten
   txa        ; i retten
   pha
 
   ; Aufruf: rec(i+1, v*2)
   lda v      ; v = v * 2
   asl
   sta v
   inx        ; i = i + 1
   stx x
   jsr rec
 
   ; Nach dem Aufruf müssen die gesicherten Variablen
   ; wieder vom Stack geholt und die Speicherstellen
   ; geschrieben werden.
   pla        ; i wieder holen
   tax
   stx x
   pla        ; v wieder holen
   sta v
 
 +
   lda v      ; v = v ^ 255 (v invertieren)
   eor #$ff
   sta v
   sta out,y  ; print(v)
   iny
 
   rts
 
 
 ;####################################################################
 ;#
 ;# Hauptprogramm
 ;#
 ;####################################################################
 
 start
   ldy #0     ; globaler Index für die Ausgabe
   lda #1
   sta v
   ldx #1
   stx x
   jsr rec
   rts