Das folgende Programm ist in DC-Code zu übersetzen.
int x = 25; int y = 13; int z = 0; z = x * 2 - y + 1; System.out.print(z);
Lösung im DC-Code:
0 JMP 4 1 DEF 25 2 DEF 13 3 DEF 0 4 LDA 1 5 STA 3 7 ADD 3 8 SUB 2 10 INC 11 STA 3 15 OUT 3 16 END
Das folgende Programm ist in DC-Code zu übersetzen.
int x = 13; int y = 0; int z = 0; y = (x - 1) * 3; z = (y + 1) * 2 - x; System.out.print(z);
Lösung im DC-Code:
0 JMP 4 1 DEF 13 2 DEF 0 3 DEF 0 4 LDA 1 5 DEC 6 STA 2 7 ADD 2 8 ADD 2 9 STA 2 10 INC 11 STA 3 12 ADD 3 13 SUB 1 14 STA 3 15 OUT 3 16 END
Das folgende Programm ist in DCL-Code zu übersetzen.
int x = 13; int y = 0; int z = 0; y = (x - 1) * 3; z = (y + 1) * 2 - x; System.out.print(z);
Lösung im DCL-Code:
JMP Anfang x DEF 13 ; Variablen-Deklaration y DEF 0 z DEF 0 Anfang LDA x DEC STA y ; y = x - 1 ADD y ADD y STA y ; y = (x - 1) * 3 LDA y ; eigentlich unnoetig INC STA z ; z = y + 1 ADD z SUB x STA Z ; z = (y + 1) * 2 - x OUT Z ; gibt 61 aus END
Führt man den Einzelschrittmodus für den ersten Befehl 0 JMP 5 aus, ergibt sich folgender Ablauf:
Kurzform | Beschreibung |
---|---|
PC --> AR | Der Program-Counter PC (hier 0) wird über den Adressbus AB in das Adressregister AR geladen. |
rd (read) | Der Inhalt der Speicherstelle mit der AR-Nummer (hier 0) wird in das Datenregister DR gelesen (hier 516= 000100 0000100). |
PC = PC + 1 | Der PC wird um 1 erhöht (hier nun 1). |
DR --> IR | Der Inhalt des Datenregisters DR (516) wird über den Datenbus zum Instruction-Register IR (hier: 000100 0000100) transportiert. |
Adr.(IR) --> PC | Der Adressanteil im IR (0000100=4) wird zum PC (nun 0000100=4) transferiert. |
Führt man den Einzelschrittmodus auch für die anderen Befehle (DEF ist kein Befehl!) des obigen Programmes aus, ergibt sich folgende Aufstellung:
Befehl | Befehlsholphase | Befehlsausführungsphase |
---|---|---|
0 JMP 5 | PC --> AR / rd / PC = PC+1 / DR --> IR | Adr.(IR) --> PC |
5 LDA 1 | PC --> AR / rd / PC = PC+1 / DR --> IR | Adr.(IR) --> AR /rd / DR --> ALU --> AC |
6 ADD 2 | PC --> AR / rd / PC = PC+1 / DR --> IR | Adr.(IR) --> AR /rd / DR --> ALU --> AC --> ALU |
7 STA 3 | PC --> AR / rd / PC = PC+1 / DR --> IR | AC --> DR / Adr.(IR) --> AR / wr |
8 OUT 3 | PC --> AR / rd / PC = PC+1 / DR --> IR | Adr.(IR) --> AR / rd / DR --> Output(Ausgabe) |
9 END | PC --> AR / rd / PC = PC+1 / DR --> IR | Adr.(IR) --> PC |
Man erkennt, dass der erste Teil immer gleich ist.
Das ist die Befehlsholphase: PC --> AR / rd / PC = PC+1 / DR --> IR
Was passiert hierbei (siehe auch oben)? Jede Speicherstelle ist über zwei sogenannte Register erreichbar.
Im Adressregister AR muss die Adresse der Speicherstelle stehen, damit ihr Wert gelesen (oder auch verändert) werden kann.
Beim Lesen landet der Wert im Datenregister DR, von wo er weitergegeben werden kann.
Um einen Befehl zu holen, wird also die Adresse, wo der Befehl steht, in das AR geladen. Im PC steht immer diese Adresse,
weil im PC immer steht, wo es weitergeht. Nach dem Transfer des PC ins AR kann der PC um 1 erhöht werden, d.h. beim
Befehl in der nächsten Speicherstelle geht es weiter. Der Speicherinhalt wird nun über das Datenregister DR und den
Datenbus DB in das Instruction-Register geladen, wo der Befehl ausgewertet wird.
Zur Orientierung und Wiederholung seien erst einmal vier Schleifen in Java-Code angegeben.
public class SchleifenEinfach { public SchleifenEinfach() { schleifeA(); schleifeB(); schleifeC(); schleifeD(); } public void schleifeA() { // Zahlen von 1 bis 10 absteigend mit do-while-Schleife int i; i = 10; do { System.out.print(i + " "); i = i - 1; } while (i > 0); System.out.println(); } public void schleifeB() { // Zahlen von 1 bis 10 aufsteigend mit do-while-Schleife int i; i = 1; do { System.out.print(i + " "); i = i + 1; } while (i <= 10); // } while (i - 10 <= 0); System.out.println(); } public void schleifeC() { // Zahlen von 1 bis 10 absteigend mit while-Schleife int i; i = 10; while (i > 0) { System.out.print(i + " "); i = i - 1; } System.out.println(); } public void schleifeD() { // Zahlen von 1 bis 10 aufsteigend mit while-Schleife int i; i = 1; while (i <= 10) // while (i - 10 <= 0); { System.out.print(i + " "); i = i + 1; } System.out.println(); } }
Hinweis 1: Eine Bedingung wie (i <= 10) kann durch Subtraktion von 10 auf beiden Seiten der Ungleichung in die Bedingung (i - 10 <= 0) umgeformt werden und ist damit eher geeignet, direkt in DCL-Code umgeformt zu werden.
Hinweis 2: Bei einer do-while-Schleife wird am Ende der Schleife geprüft und bei wahrer Bedingung erfolgt ein bedingter Sprung an den Anfang.
Hinweis 3: Bei einer while-Schleife wird am Anfang der Schleife geprüft und bei falscher Bedingung erfolgt ein bedingter Sprung hinter das Ende der Schleife. Am Ende der Schleife (schließende geschweifte Klammer) erfolgt ein unbedingter Sprung an den Anfang der Schleife.
Das folgende kleine Mini-Java-Programm simuliert sozusagen eine Ausgabe wie "Die Zahl ist positiv." bzw. "Die Zahl ist nicht positiv." durch die Ausgabe von 1 (true) bzw. 0 (false).
int x = 23; // irgendeine Zahl int y = 0; if (x > 0) y = 1; print(y);
Hinweis 1: Übersetzt in Maschinensprache muss an der Stelle, an der die Bedingung getestet wird, bei falscher Bedingung ein bedingter Sprung an das Ende des Ja-Zweiges erfolgen, denn bei wahrer Bedingung geht das Programm einfach weiter in den Ja-Zweig hinein.
Hinweis 2: Eine Bedingung wie (i == 10) kann durch Subtraktion von 10 auf beiden Seiten der Ungleichung in die Bedingung (i - 10 == 0) umgeformt werden und ist damit eher geeignet, direkt in DCL-Code umgeformt zu werden.