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 *)