Lösungen zur Assembler-Programmierung |
Befehlsliste
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:
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:
Zeile 30 nach <04> 3. Balken
Zeile 32 nach <05> 4. Balken
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.
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:
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
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.
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.
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.
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 |