Java/Modellrechner

Aus ZUM-Unterrichten

Ein Modellrechner, der bereits ein lauffähiges Programm im Speicher hat, ist folgendermaßen aufgebaut:

Nr.
Programmspeicher
Datenspeicher
0
2 (add)
0
1
5
1
2
3 (sub)
2
3
6
3
4
4 (cmp)
4
5
6
5 7
6
5 (jmp)
6 3
7
0
7
8
1
8
...
9
Befehle (Maschinensprache)

1 stp – Stoppt die Programmausführung

2 add X – addiert zu der mit X angegebenen Speicherstelle 1

3 sub X – subtrahiert von der mit X angegebenen Speicherstelle 1

4 cmp X – prueft, ob in der mit X angegebenen Speicherzelle der Wert 0 eingetragen. Wenn ja überspringt der Programmzähler 2 Schritte, wenn nein setzt er das Programm an der folgenden Stelle fort.

5 jmp X – Setzt den Programmzähler auf X

Aufgabe

Hinweis: JMP beinhaltet noch einen Bug!

Leseprobe zum Programm: Beim Programmaufruf wird folgendes ausgeführt:

add 5, da in Programmspeicher 0 der Befehl 2, also add, steht und in Programmspeicher 1 eine 5 eingetragen ist. Also wird Programmspeicher 5 um ein erhöht (in diesem Fall auf 8).

Anschließend steht der Programmzähler (angedeutet als blauer Pfeil) auf Position 2.


Das oben bereits eingetragene Programm führt die Addition von Datenspeicher 5 und 6 durch.

Dazu wird Speicherzelle 5 solange um 1 erhöht und Speicherzelle 6 solange um 1 verkleinert, bis Speicherstelle 6 den Wert 0 hat.


a) Ändern Sie das Maschinensprachenprogramm so, dass von der 7 die 3 abgezogen wird, also als Ergebnis eine 4 in Speicherplatz 5 steht.


b) Ist bei dem angegebenen Rechner die Anforderung an die „Von-Neumann-Architektur“ eingehalten? Begründen Sie!


c) Bei der Simulation in Java lässt sich die Programmausführung wie folgt simulieren (Quelltext z.T. angegeben).

c1) Beschreiben Sie, wie die Methode run() funktioniert.

c2) Schreiben Sie – analog zur unten angegebenen Methode addiereEins() - die Methode subtrahiereEins().

c3) Schreiben Sie die Methode springeAuf(), die den jmp X Befehl simulieren soll. Der nächste Programmplatz wird ausgelesen und der Programmzähler auf die entsprechende Position gesetzt.

c4) Schreiben Sie die Methode list(), die auf der Konsole den gesamten Inhalt des Programmspeichers ausgibt (siehe Abbildung mit einer Beispielabbildung).


d) Nehmen Sie Stellung zu der Frage, ob die Auswahl der Datentypen, also Array für den Datenspeicher und List für den Programmspeicher eine gute Wahl war. Wägen Sie Vor- und Nachteile ab und geben Sie Alternativen an.


Quelltext der Klasse Modellrechner

public class Modellrechner
{
    private List programmspeicher;
    private int[] speicher;
    
    public Modellrechner()
    {
        programmspeicher=new List();
        speicher = new int[10];
        for (int i=0;i<10;i++) speicher[i]=0;
        
        // Vorgegebene Werte im Speicher
        speicher[5]=7;
        speicher[6]=3;
        
        // Die etwas unelegante Programmeingabe
        programmspeicher.toLast();
        programmspeicher.insertBehind(2);
        programmspeicher.toLast();
        programmspeicher.insertBehind(5);
        programmspeicher.toLast();
        programmspeicher.insertBehind(3);
        programmspeicher.toLast();
        programmspeicher.insertBehind(6);
        programmspeicher.toLast();
        programmspeicher.insertBehind(4);
        programmspeicher.toLast();
        programmspeicher.insertBehind(6);
        programmspeicher.toLast();
        programmspeicher.insertBehind(5);
        programmspeicher.toLast();
        programmspeicher.insertBehind(0);
        programmspeicher.toLast();       
        programmspeicher.insertBehind(1);
        
    }
    
    public void run() {
        int zwischenspeicher;
        boolean stopflag=false;
        programmspeicher.toFirst();
        while (programmspeicher.isBehind()!=true && stopflag==false) {
            zwischenspeicher = (Integer) programmspeicher.getItem();
            System.out.println(zwischenspeicher);
            if (zwischenspeicher==1) stopflag=true;
            if (zwischenspeicher==2) addiereEins();
            if (zwischenspeicher==3) subtrahiereEins();
            if (zwischenspeicher==4) pruefeObNull();
            if (zwischenspeicher==5) springeAuf();
            programmspeicher.next();
        }
    }
    
    public void addiereEins() {
        int adzwischen;
        programmspeicher.next();
        adzwischen = (Integer) programmspeicher.getItem();
        speicher[adzwischen]++;
    }

    public void subtrahiereEins() {
        int adzwischen;
        programmspeicher.next();
        adzwischen = (Integer) programmspeicher.getItem();
        speicher[adzwischen]--;
    }
    
    public void pruefeObNull() {
        int adzwischen;
        programmspeicher.next();
        adzwischen = (Integer) programmspeicher.getItem();
        if (speicher[adzwischen]==0) {
            programmspeicher.next();
            programmspeicher.next();
        }
    }

    public void springeAuf() {
        int adzwischen;
        programmspeicher.next();
        adzwischen = (Integer) programmspeicher.getItem();
        programmspeicher.toFirst();
        for (int i=0;i<adzwischen;i++) programmspeicher.previous();
    }
    
    public void list() {
        int i=0;
        programmspeicher.toFirst();
        while (!programmspeicher.isBehind()) {
            System.out.println("Schritt:"+i+" - Befehl:"+(Integer) programmspeicher.getItem());
            programmspeicher.next();
            i++;
        }
        programmspeicher.toFirst();
    }
    
    public void zeigeSpeicher() {
        for (int i=0;i<10;i++) System.out.println("Zelle:"+i+" - Inhalt:"+speicher[i]);
    }
    
} // Ende der Klasse Modellrechner