Schlagwort-Liste: Simulator 4-Bit-Rechner - Assembler - Programmier-Beispiele

    Lösungen zur Assembler-Programmierung

Befehlsliste

Aufgabe 1

Lösung mit anderer UP-Struktur gegenüber Programm b11_neu1.asi.

Programm b11_3.asi

Das Unterprogramm wird 4 mal aufgerufen. Bis auf die Speicherung der Werte 1 oder 0 auf die Speicherplätze 02 … 05 (die Darstellung der Balken), wird alles im UP organisiert. Das ist ein technisches Problem (siehe unten).

67 Speicherplätze werden nur noch gebraucht, das ist gegenüber 126 vom alten Programm ganz schön wenig!
Es sind nun aber auch einige spezielle Aktionen, man kann schon sagen Tricks, genutzt worden.
Das UP soll 4 mal genutzt werden und es soll so viel wie möglich erledigen.
Die erste Aktion ist die Bearbeitung der Maske. Es soll immer die vorhandene Maske verändert werden nicht neu angelegt. Das geht durch verschieben:

Wenn man 1000 anlegt und verschiebt alle Bits einmal nach rechts, erhält man 0100.
Dezimal betrachtet ist das eine Division durch 2 ( 8 / 2 = 4), d.h. jedes Mal wenn das
UP aufgerufen wird, wird zunächst die Maske so verändert.
Ein Problem gibt es mit dem ersten Wert, denn der müsste 10000 sein, das geht nicht!
Unser Prozessor hat aber auch einen zyklischen Verschiebebefehl, aus 0001 zyklisch
nach rechts ergibt sich 1000! Deshalb laden wir in Zeile 23 und 24 eine 1 auf den
Speicherplatz <maske>. Das UP macht in den Zeilen 7, 8, 9 beim ersten Aufruf daraus
eine 8 also 1000.

Die zweite Aktion holt von <ret> den eingegebenen Wert, also muss zuvor im HP dieser Wert dahin gespeichert werden (Zeile 22).
Da nun schon mal die aktuelle Maske auf <maske> vorhanden ist kann sie auch gleich für die Ermittlung ob negativ oder nicht genutzt werden (Zeilen 11 und 12, natürlich darf jetzt nichts auf <maske> gespeichert werden, dann wäre sie für die nächste Aktion unbrauchbar).

Nun hat unser Prozessor ein Problem, denn es müsste bei jeder Nutzung auch die Ausgabeadresse weitergezählt werden – das geht nicht. Dazu brauchten wir eine indizierte Adressierung, also so <02 + i>. Mit Veränderung von i könnte man auch die Adresse verändern, für so einen Befehl war kein Platz mehr.
Man kann das so lösen:

Im UP legt man entsprechend der Entscheidung eine 1 oder 0 in den Akku und verlässt
danach sofort das UP. Als erste Aktion nach dem Rücksprung wird im HP der Akku
auf den vereinbarten Speicherplatz ausgegeben
Zeile 26 nach <02> 1. Balken
Zeile 28 nach <03> 2. Balken

Zeile 30 nach <04> 3. Balken
Zeile 32 nach <05> 4. Balken

Danach geht es wieder von vorn los.

An dem Beispiel sieht man auch, dass das UP 4 mal aufgerufen wird und dafür jedes Mal auch eine andere Rücksprungadresse gebraucht wird. Das geschieht immer beim UP-Aufruf, denn der Befehl speichert immer die Adresse des nächsten Befehls in die Speicherplätze FA und FB. Nun werden die beiden dem Befehl folgenden Werte in den Befehlszähler geladen und das Programm da fortgesetzt, das ist die Adresse 20, der Beginn des UP.
Beim Rücksprung wird einfach die Adresse aus FA und FB in den Befehlszähler geladen und schon haben wir wieder die richtige Adresse.
Das kann man beim Simulator sehen, denn bei der Eingabe wartet der Rechner. Auf <FB> steht der Wert 6, auf <FA> 0, also die letzte Rücksprungadresse war 60. Wenn man bei der Abarbeitung des Programms auf diese Plätze achten, sieht man, dass sie sich ständig verändern.

zurück Aufgaben


Aufgabe 2

Hier soll nur das Programm beschrieben werden, zunächst aber die zugehörende LST-Datei

Teil 1:

Teil 2:

Wie immer gibt es am Anfang Vereinbarungen, die müssen nicht sein, aber es geht so übersichtlicher. Dazu werden auf die Speicherplätze:

0A der Wert 0; (ist da eigentlich schon)
0B der Wert 1
0C der Wert 2 und
0D der Wert 3

Gespeichert. Die nächsten Vereinbarungen sind für die Übersichtlichkeit, die eben genannten Speicherplätze bekommen eine symbolische Adresse, die auf den Inhalt Bezug nimmt:

null: equ 0A
eins: equ 0B
zwei: equ 0C
drei: equ 0D

Jetzt kann man ohne Probleme schreiben:

SUB zwei ;Akku = Akku – 2

Würde man das wie folgt schreiben gibt es auch keine Fehlermeldung, es ist aber logisch falsch!

SUB 2

Die Schreibweise ist tolerant, denn der Assembler macht daraus 02, denn hinter SUB muss immer eine Adresse stehen. Bei arithmetischen Operationen steht der eine Operand im Akku und der andere im Speicher, also eine Adresse und die ist 8 Bit lang. Auf der Adresse <zwei> steht der Wert 2! Wenn man diesen Unterschied nicht beachtet, gibt es immer schwierig zu findende logische Fehler, der Assembler findet keine Fehler!

Die Bezeichnung „ret“ ist ebenfalls nur eine symbolische Adresse für einen Speicherplatz.

Nun beginnt das Programm.

Zunächst erfolgt wieder die Tastatureingabe, der Wert wird sofort gerettet, denn als nächsten Schritt wollen wir die Balken vom Versuch löschen, es sollen auf die Speicherplätze 02 … 08 die Werte 0 geschrieben werden. Das wissen wir eigentlich schon, Transporte gehen immer über den Akku, also wird der alte Inhalt zerstört, deswegen retten.
Diese Aktion muss sein, da die alten Anzeigen ja nicht gelöscht (auf 0 gesetzt) werden, das muss der Nutzer vor der Ausgabe machen oder dann auch die 0 ausgeben!
Nun erfolgt die Auswertung der Tastatureingabe, dazu muss der Wert erst mal aus <ret> wieder in den Akku geholt werden.

Die Vergleiche werden wieder über die Subtraktion ausgeführt. Diesmal wird aber das Z-Flag ausgewertet. Wenn

Akku SUB zwei

das Z-Flag setzt, muss im Akku eine 2 gestanden haben. Also führt man einen Sprung aus zu einer Marken ab der die Darstellung der 2 im Versuch 1 erfolgt (Zeilen 60 bis 67). Zeile 68 realisiert einen Sprung zum Programm-Ende, denn weitere Auswertungen sind für diesen Fall nicht mehr notwendig, wären sogar falsch.
So geht das mit allen Vergleichen bis Nichts gepasst hat (Zeile 39).
Ab hier wir die Fehlermeldung vorbereitet, einmal für die Ausgabe (Zeilen 39 bis 42):

Ausg. C ; die nächste Ausgabe realisiert ein Textzeichen
Ausg. 7 ; Textzeichen F wird ausgegeben

Zum anderen die Ausgabe eines F im Versuch 1 (Zeilen 43 bis 47).

Alles andere sollte nun verständlich sein!?

Im Folgenden noch einmal das Prinzip der Fragerei.
Immer bei der Antwort „nein“ (Z-Flag = 0) folgt die nächste Frage, bis alles abgefragt wurde, dann war der Wert bei „nein“ falsch. Bei „ja“ wird sofort die Fragerei verlassen, der Fall bearbeitet und ans Ende des Programms gesprungen. Ginge natürlich auch an den Anfang, dies Arbeitweise ist exakter, entspricht einer Blockstruktur.

zurück Aufgaben


Aufgabe 3

Das Beispielprogramm in der Beschreibung des Rechners funktioniert richtig, jedoch hapert es mit der Ausgabe. Der Rechner kann nur dezimale Zahlen ausgeben. Es gibt aber die Möglichkeit mit dem Buchstaben C eine Textausgabe anzuweisen. Die nun folgenden Zahlen erzeugen einen Buchstaben.
Das Problem ist nun, herauszufinden, was ein Buchstabe ist?
Das geht auch recht simpel, man subtrahiert von der Zahl den Wert a (10). Die Auswertung macht eine Unterscheidung möglich, denn, ist das Ergebnis negativ, war es eine Zahl von 0 bis 9. Ist es hingegen nicht negativ, also 0 und größer als 0, ist es ein Buchstabe. Man macht den Sprung abhängig vom N-Flag, also der Befehl SPN.
Ist das N-Flag 1 kann der Wert so ausgegeben werden, sonst muss die Textausgabe erfolgen. Da gibt es aber noch ein Problem, es muss der Wert für das Zeichen ermittelt werden.
Das ist ganz einfach, denn genialer Weise hat das a den Wert 0, b = 1 usw. aber das bringt genau die Subtraktion Wert – a als Ergebnis, der Wert muss nur gespeichert werden und nach der Ausgabe von c ebenfalls ausgegeben werden.

Diese Aktionen sind in den Zeilen 16 bis 26 enthalten.
Das Weiterzählen erfolgt ab Zeile 27. Hier sieht man, das es wichtig ist den Akku zu retten, denn durch die Subtraktion hat er garantiert einen falschen Wert, also holen wir ihn wieder und addieren 1 dazu.

Das Ende des Programms wird über das Carry-Flag ermittelt, denn 15 +1 ist 0 aber das C wird auf 1 gesetzt.

Bevor es weiter geht wird eine Eingabe programmiert, die jedoch nicht ausgewertet wird (der Akku muss zuvor natürlich wieder gerettet werden), sie dient nur dazu, den Rechner zu stoppen, damit wir die Werte auch sehen.

zurück Aufgaben


Aufgabe 4

Das ist relativ einfach, denn wir übernehmen das Programm b11_3.asi und ändern es etwas. In dem Programm wurden schon mit Masken die einzelnen Bits herausgefiltert und dargestellt. Das können wir übernehmen.
Und es wird sogar noch günstiger, denn die Ausgabe ist immer die Adresse 01, also kann das nun auch noch ins Unterprogramm.

Um die gesamte Bitfolge darzustellen, müssen wir aber nun auch noch im UP die Ausgabeposition ändern – das geht auch, es muss der Buchstabe a ausgegeben werden und danach die Position (0 ist Standard, ganz rechts, 1 eine Stelle nach links.
Und ganz wichtig – die eingestellte Position bleibt für die nächsten Ausgaben bestehen!

Wir wollen die Schritte im Up beschreiben:

Von Zeile 16 bis 20 wird die Position der Ausgabe vorbereitet. Da das UP für alle vier Ausgaben allgemeingültig sein muss, müssen wir auch beim ersten Durchlauf durch Subtraktion auf die Position kommen, das muss 3 sein, also speichern wir vor erstem Aufruf des UP den Wert 4 (Zeile 42, 43) auf pos, dann kommt sicher 3 heraus.
Das kann man dann auch gleich ausgeben (Zeile 21).
Die Maske wird durch zyklisches Verschieben an die Situation angepasst. Wir speichern vor erstem Aufruf 1 (0001), die zyklisch nach rechts ergibt 8 (1000) (Zeilen 22 bis 24).
Danach wird mit AND und SUB ermittelt ob es eine 1 oder 0 ist, die dann auch im UP ausgegeben wird.

Im HP braucht man dieses UP nur noch 4 mal aufrufen und schon haben wir die digitale Ausgabe des eingegebenen Wertes

denkste, es geht gar nichts!

Das sind die übelsten Fehler, der Assembler sagt ok, aber es geht dennoch nicht, das sind logische Fehler. Um es gleich zu sagen, den Fehler hat der Programmierer gemacht!

Man muss sich die LST Datei schon sehr genau ansehen, um festzustellen, dass das UP bis zur Adresse 4E geht! Wir haben aber angewiesen dass das HP an Adresse 40 beginnt!

Was passiert?

Der Assembler übersetzt das UP ordnungsgemäß, erhält nun eine Anweisung, dass die weitere Übersetzung ab Adresse 40 abgelegt werden soll – also wird ab 40 das UP überschrieben.

Das Ergebnis ist, es funktioniert nicht wie es soll,

aber, wie schon zu Anfang gesagt,
jede Bitkombination kann Daten oder Befehl sein, haben wir die Richtigkeit bewiesen, denn das Programm läuft ja, völlig falsch, aber es geht.
Solche Fehler, die dann noch annähernd das Richtige machen, fallen manchmal kaum auf, haben aber späte schlimme Folgen, dies gilt natürlich vorrangig für reale Rechner und Systeme.

Der Fehler lässt sich ganz leicht beseitigen, indem das Hauptprogramm z.B. ab Adresse 50 übersetzt wird, siehe unten.

zurück Aufgaben


Aufgabe 5

Die Anzeige eines Balkens rotieren lassen, bedeutet nichts anderes, als der Reihe nach die Balken ansteuern und den vorhergehenden ausschalten.

Der obere Balken wird über den Speicherplatz 02 und der „rote“ über 03 angesteuert. Auf 03 wird eine 1 gespeichert, auf 02 eine 0. Das muss man so der Reihe nach für alle 6 Balken organisieren.

Um die Anzeige gut sichtbar zu machen, sollten die Ausgaben immer etwas verzögert werden. Das macht das Unterprogramm „verz“. Da muss man irgendetwas tun, was Zeit braucht. Ich gebe einfach mal einen Wert aus, man kann auch Hochzählen bis zu einer Grenze usw.

zurück zur Start-Seite
zurück zu Aufgaben