Beispiele zur Mikroprozessor-Simulation


do-while-Schleife (1)

; PROGRAM Schleifd.dcl
; Zahlen von 1 bis 100 ausgeben abwaerts
        JMP Anfang

k       DEF 000
eins    DEF 001
hundert DEF 100

Anfang
         LDA hundert
         STA k            ; k = 100
Schleife                  ; do
         LDA k
         OUT k            ;      print (k)
         DEC
         STA k            ;      k := k-1
         JNZ Schleife     ; while (k > 0)
         END


do-while-Schleife (2)

; PROGRAM Schleifu.dcl
; Zahlen von 1 bis 100 ausgeben (aufwaerts)
        JMP Anfang

k       DEF 000
eins    DEF 001
hundert DEF 100

Anfang
         LDA eins
         STA k            ; k = 1
Schleife                  ; do
         LDA k
         OUT k            ;      print (k)
         INC
         STA k            ;      k = k+1
         SUB hundert
         JNP Schleife     ; while (k - 100 <= 0)
         END

while-Schleife (1)

; SCHLEIFW.DCL
;
; Die ganzen Zahlen von STARTWERT bis ENDWERT werden ausgegeben
;                       mit einer WHILE-Schleife

        JMP Anfang

K         DEF 000
StartWert DEF 003
EndWert   DEF 010

Anfang
         LDA StartWert    ;
         STA K            ; K := StartWert

WhileAnfang
         LDA K            ;
         SUB EndWert      ; WHILE (K-EndWert) <= 0 DO BEGIN
         JPL WhileEnde    ;      (* IF Akku > 0 THEN GOTO WhileEnde *)
         LDA K            ;
         OUT K            ;      Write (K)
         INC              ;
         STA K            ;      K := K+1
         JMP WhileAnfang  ;      (* GOTO WhileAnfang *)
WhileEnde                 ; END (* WHILE *)

         END

while-Schleife (2)

; PROGRAM Summe.dcl
;
; Die ganzen Zahlen von 1 bis k werden addiert
;                       mit einer WHILE-Schleife
        JMP Anfang

null    DEF 000
summe   DEF 000
k       DEF 50

Anfang
         LDA null         ;
         STA summe        ;

WhileAnfang
         LDA k            ;
         JNP WhileEnde    ; while (k > 0)
         LDA summe        ;
         ADD k            ;
         STA summe        ;      summe = summe + k
         LDA k
         DEC
         STA k
         JMP WhileAnfang  ;
WhileEnde                 ; end while
         OUT summe
         END

Unterprogramm (Methode)

; PROGRAM SummeJSR.DCL
; Die ganzen Zahlen von 1 bis k werden addiert
; mit einer WHILE-Schleife in einer Methode Addiere
        JMP Anfang

null    DEF 000
summe   DEF 000
k       DEF 5

Anfang
         JSR Addiere
         OUT summe
         END
addiere                   ; void addiere()
         LDA null         ;
         STA summe        ;
WhileAnfang
         LDA k            ;
         JNP WhileEnde    ; while (k > 0)
         LDA summe        ;
         ADD k            ;
         STA summe        ;      summe = summe + k
         LDA k
         DEC
         STA k
         JMP WhileAnfang  ;
WhileEnde                 ; end while
         RTN              ; end addiere

Unterprogramm (Methode mit Parameterübergabe)

; PROGRAM SumJSRPA.DCL
; Die ganzen Zahlen von 1 bis k werden addiert
; mit einer WHILE-Schleife in einer Methode Addiere
; inklusive Parameteruebergabe

        JMP Anfang

null    DEF 000
summe   DEF 000
k       DEF 5

Anfang
         INM k            ; read (k)
         LDA k
         PSH              ; k auf Stack
         JSR Addiere
         POP              ; k vernichten
         OUT summe
         END
addiere                     ; void addiere(int zahl)
         zahl       EQUAL 2 ; SP + 2
         RSprAdr    EQUAL 1 ; SP + 1
         LDA null         ;
         STA summe        ; ergebnis = 0
WhileAnfang
         LDAS zahl        ;
         JNP WhileEnde    ; while (zahl > 0)
         LDA summe        ;
         ADDS zahl        ;
         STA summe        ;      summe = summe + zahl
         LDAS zahl
         DEC
         STAS zahl
         JMP WhileAnfang  ;
WhileEnde                 ; end while
         RTN              ; end addiere

Unterprogramm (Methode mit Parameterübergabe und Rückgabewert, lokale Variable)

; PROGRAM SumJSRSt.DCL
; Die ganzen Zahlen von 1 bis k werden addiert
; mit einer WHILE-Schleife in einer Methode Addiere
; inklusive Parameteruebergabe und Rueckgabewert

        JMP Anfang

null    DEF 000
summe   DEF 000
k       DEF 5

Anfang
         INM k            ; read (k)
         LDA k
         PSH              ; Platz fuer Funktionserg.
         PSH              ; k auf Stack
         JSR Addiere
         POP              ; k vernichten
         POP              ; Funtionsergebnis vom Stack
         STA summe        ; summe = addiere (k)
         OUT summe
         END
addiere                     ; int addiere(int zahl)
         PSH                ; int ergebnis (Platz fuer lokale Variable)
         returnwert EQUAL 4 ; SP + 4
         zahl       EQUAL 3 ; SP + 3
         RSprAdr    EQUAL 2 ; SP + 2
         ergebnis   EQUAL 1 ; SP + 1
         LDA null         ;
         STAS ergebnis    ; ergebnis = 0
WhileAnfang
         LDAS zahl        ;
         JNP WhileEnde    ; while (zahl > 0)
         LDAS ergebnis    ;
         ADDS zahl        ;
         STAS ergebnis    ;      ergebnis = ergebnis + zahl
         LDAS zahl
         DEC
         STAS zahl
         JMP WhileAnfang  ;
WhileEnde                 ; end while
         LDAS ergebnis
         STAS returnwert  ; return addiere
         POP              ; zahl vernichten
         RTN              ; end addiere

Unterprogramm (Methode mit Parameterübergabe und Rückgabewert, lokale Variable)

; PROGRAM Quadrat.dcl
; Das Quadrat einer DC-Zahl X mit X < 45 ist zu berechnen. Negative
; Zahlen seien dabei zugelassen. Zu Beginn soll die Basis bei negati-
; vem Vorzeichen durch ihren Betrag ersetzt wird.
; Auch ein zweiter Programmlauf mit anderem X sollte moeglich sein.
; Hier :
; Simulation einer Methode int quadrat(int zahl) mit Parameteruebergabe ueber den
; Stack. Auch das Funktionsergebnis wird ueber den Stack zurueckgeliefert.

         JMP Anfang
null     DEF 00       ; final int null = 0
x        DEF 00       ; int   x
quad     DEF 00       ; int   quad

Anfang   INM x         ; readint (x)
         LDA x
         JNM EndIf1    ; IF x < 0 THEN
         NEG           ;     x = -x
         STA x         ;
EndIf1
         PSH           ; Platz fuer Funktionsergebnis schaffen
         PSH           ; x ueber Stack an Function uebergeben.
         JSR Quadrat
         POP           ; x vernichten
         POP           ; Funktionsergebnis vom Stack holen
         STA quad      ; und speichern
                       ; quad = quadrat(x)
         OUT quad      ; print (quad)
         END           ; end (* HAUPTPROGRAMM *)


quadrat                ; int quadrat (int Zahl)
                       ; Lokale Variablen auf Stack von oben:
quaderg  EQUAL 5       ;  quaderg             <- SP + 5
zahl     EQUAL 4       ;  zahl                <- SP + 4
                       ;  ruecksprungadresse  <- SP + 3
zaehler  EQUAL 2       ;  zaehler             <- SP + 2
ergebnis EQUAL 1       ;  ergebnis            <- SP + 1
                       ;                      <- SP
                       ; BEGIN (* FUNCTION *)
         PSH           ; Platz fuer Zaehler     (lokale Variable)
         PSH           ; Platz fuerr Ergebnis   (lokale Variable)
         LDA Null
         STAS ergebnis ; ergebnis = 0
         LDAS zahl     ; zahl vom Stack
         STAS zaehler  ; zaehler = zahl
WhileAnf
         JNP EndWhile  ; while (zaehler > 0)
         LDAS ergebnis ;
         ADDS zahl
         STAS ergebnis ;     ergebnis = ergebnis + zahl (auf Stack)
         LDAS zaehler
         DEC           ;     zaehler  = zaehler - 1
         STAS zaehler
         JMP WhileAnf  ; end // while
EndWhile
         LDAS ergebnis
         STAS quaderg  ; Ergebnis auf Stack zurueckliefern
         POP           ; Ergebnis vernichten (Platz freigeben)
         POP           ; Zaehler  vernichten
         RTN           ; END (* Quadrat *)

Unterprogramm (Methode mit Rekursion)

; PROGRAM Umkehr.dcl
                             ; BEGIN (* Hauptprogramm *)
         JSR Umkehr          ;   Umkehr;
         END                 ; END.  (* Hauptprogramm *)

Umkehr                       ;PROCEDURE Umkehr;
                             ;    Ruecksprungadresse  BP+2
                             ;VAR Zahl : INTEGER;     BP+1
    Zahl EQUAL 1             ;                        BP = SP
         PSH                 ;BEGIN (* Platz fuer Zahl schaffen *)
         SPBP                ; SP -> BP
         INB Zahl            ;  Read (Zahl);
         OUTB Zahl           ;  Write (Zahl);
         LDAB Zahl           ;
         JZE EndIf           ;  IF (Zahl <> 0) THEN
                             ;       BEGIN
         JSR Umkehr          ;       Umkehr rekursiv aufrufen.
         SPBP                ; SP -> BP
         OUTB Zahl           ;       Write (Zahl);
                             ;       END
EndIf
         POP                 ; (* Platz fuer Zahl freigeben *)
         RTN                 ;END; (* Umkehr *)


Unterprogramm (Methode mit Rekursion und Parametern)

; Fibonacci-Zahlen rekursiv berechnen fuer DC
; Parameter, Zwischen- und Funktionsergebnis auf Stack
; Version mit BasePointer BP (ab Version 6.1)
            JMP Anfang
Null        DEF 000               ; CONST Null = 0
Eins        DEF 001               ;       Eins = 1
Zwei        DEF 002               ;       Zwei = 2
EndWert     DEF 005               ; VAR   EndWert,
K           DEF 000               ;       K,
FiboResult  DEF 000               ;       FiboResult : DCINTEGER;

            ; BEGIN (* Hauptprogramm *)
Anfang
            INM EndWert           ; Read (Endwert);
            LDA Eins
            STA K
WhileAnfang
            LDA K                 ; WHILE (K <= EndWert) DO BEGIN
            SUB EndWert
            JPL WhileEnde
            PSHM K                ;      Parameter K auf Stack
            JSR Fibo              ;      Aufruf
            POPM FiboResult       ;      FiboResult := Fibo (K)
            OUT FiboResult        ;      Write (FiboResult)
            LDA K
            INC
            STA K                 ;       K := K + 1;
            JMP WhileAnfang       ; END; (* WHILE *)
WhileEnde
            END                   ; End. (* Hauptprogramm *)

                                  ; (* -------------------------------- *)
Fibo                              ; FUNCTION Fibo (N : INTEGER) : INTEGER;
            N      EQUAL 3        ;        N        BP + 3
                                  ;        RSA      BP + 2
            Ablage EQUAL 1        ;        Ablage   BP + 1
                                  ; BEGIN
            PSH                   ; Platz fuer Ablage schaffen
            SPBP
            LDAB N
            JNZ Else1             ; IF N = 0 THEN
            LDA Null              ;      BEGIN
            STAB N                ;      Fibo := 0;
            JMP EndIf1            ;      END
Else1                             ; ELSE BEGIN
            LDAB N
            SUB Eins
            JNZ Else2             ;      IF (N = 1) THEN
            LDA Eins              ;           BEGIN
            STAB N                ;           Fibo := 1;
            JMP EndIf2            ;           END
Else2
            LDAB N                ;      ELSE BEGIN
            DEC                   ;           Berechne  N - 1
            PSH
            JSR Fibo              ;           Aufruf
            POP
            SPBP
            STAB Ablage           ;           Ablage := Fibo (N-1)
            LDAB N
            SUB Zwei              ;           Berechne N - 2
            PSH
            JSR Fibo              ;           Aufruf
            POP                   ;           Accu := Fibo (N-2)
            SPBP
            ADDB Ablage           ;           Accu := Accu + Ablage
            STAB N                ;           Fibo := Fibo (N - Eins) +
                                  ;                   Fibo (N - Zwei);
       EndIf2                     ;           END
EndIf1
            POP                   ;   (* Platz fuer Ablage wieder frei *)
            RTN                   ; END; (* Fibo *)

Unterprogramm (Methode mit Rekursion und Parametern)

; ************************************************************
; *********** Tuerme von Hanoi fuer DC (ab Version 6.1) ******
; ************************************************************
; Bei Anfangshoehe > 3 sollte bei OUTB Ziel ein
; Breakpoint gesetzt werden, um die Ausgabe verfolgen zu
; koennen. Erst ab ca. 16-17 Scheiben laeuft der Stack in den
; Codebereich.
; Version fuer DC mit BasePointer BP und Mini-Assembler

; PROGRAM Tuerme_von_Hanoi_rekursiv_mit_DC;

           JMP Anfang
GlobalStart  DEF 01          ; CONST GlobalStart   = 1
GlobalAblage DEF 02          ;       GlobalAblage  = 2
GlobalZiel   DEF 03          ;       GlobalZiel    = 3
GlobalHoehe  DEF 00          ; VAR   GlobalHoehe

                             ; BEGIN (* Hauptprogramm *)
Anfang
           INM  GlobalHoehe  ;   Read (GlobalHoehe)
                             ;   (* Parameter auf Stack legen *)
           PSHM GlobalHoehe  ;   PUSH GlobalHoehe
           PSHM GlobalStart  ;   PUSH GlobalStart
           PSHM GlobalZiel   ;   PUSH GlobalZiel
           PSHM GlobalAblage ;   PUSH GlobalAblage
                             ;   (* und Aufruf der Rekursion *)
           JSR  Transport    ;   Transportiere (GlobalHoehe, GlobalStart,
                             ;                  GlobalZiel, GlobalAblage)
                             ;    (* Von 1 nach 3 ueber 2 *)
           END               ; END  (* Hauptprogramm *)

Transport
                             ; PROCEDURE Transportiere (Hoehe, Start,
                             ;                          Ziel, Ablage);
                             ; BEGIN (* Transportiere *)
        Hoehe   EQUAL 5      ; BP + 5
        Start   EQUAL 4      ; BP + 4
        Ziel    EQUAL 3      ; BP + 3
        Ablage  EQUAL 2      ; BP + 2
        RSpAdr  EQUAL 1      ; BP + 1
           SPBP              ; SP --> BP. SP nach BP, da SP sich bei
                             ; den nachfolgenden PSH-Anweisungen ver-
                             ; veraendert. So bleibt Zugriff auf
                             ; die Parameter auf dem Stack gewaehrleistet.
           LDAB Hoehe
           DEC
                             ;   IF Hoehe-1 > 0 THEN (* Rekursion *)
                             ;        BEGIN
           JNP  EndIf1       ;        (* Parameter auf Stack legen *)
           PSH               ;        PUSH Hoehe-1
           LDAB Start
           PSH               ;        PUSH Start
           LDAB Ablage
           PSH               ;        PUSH Ablage
           LDAB Ziel
           PSH               ;        PUSH Ziel
           JSR  Transport    ;        Transportiere (Hoehe-1, Start,
                             ;                       Ablage, Ziel);
                             ;   END; (* IF *)
EndIf1     SPBP              ; SP --> BP (* neu setzen, da durch  *)
                             ;           (* Rekursion veraendert. *)
           OUTB Start        ;   Write ('Lege Scheibe von Turm  ');
           OUTB Ziel         ;   Write ('             auf Turm .');

           LDAB Hoehe
           DEC
                             ;   IF Hoehe-1 > 0 THEN (* Rekursion *)
                             ;        BEGIN
           JNP  EndIf2       ;        (* Parameter auf Stack legen *)
           PSH               ;        PUSH Hoehe-1
           LDAB Ablage
           PSH               ;        PUSH Ablage
           LDAB Ziel
           PSH               ;        PUSH Ziel
           LDAB Start
           PSH               ;        PUSH Start
           JSR  Transport    ;        Transportiere (Hoehe-1, Ablage,
                             ;                       Ziel, Start);
                             ;        END; (* IF *)
                             ;   Stack am Prozedurende bis auf
                             ;   Ruecksprungadresse vernichten
EndIf2     SPBP              ;   SP --> BP (* siehe oben *)
           LDAB RSpAdr       ;   Ruecksprungadresse an die Spitze
           STAB Hoehe
           POP               ;   vier lokale Variablen vernichten
           POP
           POP
           POP
           RTN               ;  END (* PROCEDURE Transport *)