| Einsendeaufgaben zur Kurseinheit 1 | Einsendeaufgaben zur Kurseinheit 3 |
Hinweis: In dieser Aufgabe soll die Arbeit mit dem Assembler und dem Terminalprogramm geübt werden. In der Vorlagedatei 1_VORL.ASM finden Sie ein Programm, welches das folgende Problem löst. Die Datei enthält jedoch Assemblerfehler wie auch logische Fehler. Ihre Aufgabe ist es, das Programm so zu ändern, daß es fehlerfrei assembliert wird, und dazu ein paar Fragen zu beantworten.
Einige Fehler werden Ihnen vielleicht sofort ins Auge fallen. "Selbstgemachte" Fehler haben jedoch vor allem die Eigenschaft, nicht sofort aufzufallen. Daher sollen Sie die Fehler anhand der Assemblerausgaben finden und berichtigen.
Das Problem: Schreiben Sie ein Programm, welches in der Anzeige eine Uhr simuliert. Dabei sollen an den Stellen S5..S4 der Siebensegmentanzeige die Stunden angezeigt werden und an den Stellen S3..S2 die Minuten. Die Weiterschaltung der Uhrsoll im Sekundentakt erfolgen, d.h. eine Minute wird auf eine Sekunde verkürzt. Solange die Taste "+" gedrückt wird, soll das Weiterschalten ohne Zeitverzögerung, also so schnell wie möglich geschehen. Alle anderen Tasten sollen keine Bedeutung haben.
Diese fehlerhafte Lösung finden Sie in der Datei 1_VORL.ASM:
**********************************************************************
* fehlerhaftes Programm folgt
**********************************************************************
ORG $0400 ;Beginn des Programmbereichs
JSR CLRDSP ;Anzeige loeschen
LDY #3E8 ;Y mit 1 Sek. Pause laden
CLR STUNDE ;Stundenzaehler auf Null setzen
CLR MINUTE ;Minutenzaehler auf Null setzen
ANZEIGE LDB STUNDEN ;Stundenzaehler laden...
LDX #4 ;...und an S5-S4...
JSR SHOWB7SG ;...ausgeben
LDB MINUTEN ;Minutenzaehler laden...
LDX #2 ;...und an S3-S2...
JSR SHOWB7SG ;...ausgeben
INCMIN TFR B,A ;Minuten nach A kopieren,
INC ;inkrementieren,
DAA ;und BCD-Korrektur.
CMP A,#$60 ;60 Minuten erreicht?
BEQ ERH;Ouml;HE ;ja, Stunde erhoehen
STA MINUTEN ;nein, also Minuten speichern...
BRA TASTEN ;...und zur Tastaturabfrage
ERHÖHE CLR MINUTEN ;Minutenzaehler auf Null
LDA STUNDEN ;Stundenzaehler laden,
INCA ;inkrementieren,
DAA ;und BCD-Justage
STA STUNDEN ;Stunden speichern
CMPA #24 ;24 Stunden erreicht?
BNZ TASTE ;nein, also zur Tastaturabfrage
CLR STUNDEN ;ja, also auf Null setzen
TASTE JSR KEY ;ist eine Taste gedrueckt?
CMPB #$80 ;ist die Taste "+" gedrueckt?
BEQ ANZEIGE ;ja, sofort weiter mit dem Hochzaehlen
*
* Nun Tasten <> "+" abarbeiten, also 1 Sekunde Pause
*
JSR DLY1MS ;bei anderen oder keiner Taste eine Sekunde warten
BRA ANZEIGE ;und dann zurueck
*
* Daten
*
MINUTEN RMB 1 ;Speicher fuer Minutenzaehler
STUNDEN RMB 2 ;Speicher fuer Stundenzaehler
U_END ORG * ;Ende des Programmbereichs
Assemblieren Sie das fehlerhafte Programm. Beantworten Sie folgende Fragen:
Berichtigen Sie die Fehler. (Hinweis: Um die Vorlagedatei nicht zu zerstören, sollten Sie sich eine Kopie der Vorlagedatei erstellen, z.B. unter dem Namen "1A.ASM", und dann mit dieser Datei arbeiten.)
Assemblieren Sie nun diese berichtigte Datei. Wenn Sie alle Fehler aus Teil a) berichtigt haben, erscheint nun als Ausgabe ein Listing, in dem weitere Fehler angezeigt werden. (Falls Sie wie in Teil a) nur eine kurze Liste der fehlerhaften Zeilen ohne Listing bekommen, müssen Sie sich weiter mit diesen Fehlern auseinandersetzen, bis das Listing erscheint.) Beantworten Sie folgende Frage zum Listing:
Die Fehlerart symbol Undefined bedeutet, daß ein Symbolname falsch angegeben wurde. Beantworten Sie folgende Frage:
Berichtigen Sie die Fehler. (Benutzen Sie dazu wieder eine Kopie, z.B. "1B.ASM".) Assemblieren Sie die Datei. Falls alle Symbolnamen korrekt sind, werden Sie ein Listing ohne Fehlermeldungen erhalten. Beantworten Sie folgende Fragen:
Laden Sie nun die in Teil b) erzeugte Hex.-Datei (1B.HEX) in den Praktikumsrechner! Lassen Sie das Programm ablaufen, testen Sie auch die Funktion der Taste "+". Beantworten Sie folgende Frage:
Beide Fehler werden vom Assembler nicht erkannt. Der eine ist eher ein logischer Fehler, der andere eher eine Eigenart des Assemblers. Beantworten Sie nach gründlicher Durchsicht des Listings folgende Fragen:
Speichern Sie bitte das korrigierte Programm unter dem Namen 1C_EA.ASM ab und schicken uns es wie gewohnt zu.
Als Programmerweiterung kann eingebaut werden, daß bei Betätigen der Taste "S" das Programm stoppt.
Dazu fügen Sie nach dem Abschnitt
TASTE JSR KEY ;ist eine Taste gedrueckt?
CMPB #$80 ;ist die "+"-Taste gedrueckt?
BEQ ANZEIGE ;ja, sofort weiter mit dem Hochzaehlen
die folgenden Zeilen ein:
CMPB #$86 ;ist die "S"-Taste gedrueckt?
BEQ ENDE ;ja, zum Programmende
Vor der Datendefinition fügen Sie ein:
ENDE SWI ;Programmende
Speichern Sie die geänderte Datei unter dem Namen 1D.ASM oder direkt unter 1D_EA.ASM. Assemblieren Sie das Programm und laden Sie die Hex.-Datei in den Praktikumsrechner. Beantworten Sie folgende Fragen:
Hinweis: In dieser Aufgabe soll der Umgang mit dem Simulator geübt werden. In der Datei 2_VORL.ASM erhalten Sie wieder eine fehlerhafte Lösung zum folgenden Problem. Sie sollen anhand dieses Problems den Simulator ein wenig kennelernen.
Problem: Schreiben Sie ein Programm, welches eine vierstellige Hexadezimalzahl einliest und in S5..S2 anzeigt. Durch Drücken der Tasten "+" bzw. "-" ist dann wahlweise rechts bzw. links von der Zahl die Anzahl der eingeschalteten Segmente dieser Zahl dezimal bzw. hexadezimal anzuzeigen. (Taste "+" zeigt also in S1..S0 die Anzahl dezimal an, Taste "-" in S6..S7 hexadezimal.)
Fehlerhafte Lösungsdatei 2_VORL.ASM:
***************************************************************************
* fehlerhafte Loesung
***************************************************************************
ORG $0400 ;Beginn des Programmbereichs
EINGABE JSR CLRDISP ;Anzeige loeschen
CLR ANZHEX ;Anzahl im Hex.-Format loeschen
CLR ANZDEZ ;Anzahl im Dez.-Format loeschen
LDY #TABELLE ;Y mit Zeiger auf Segmentanzahlen laden
LDX #5 ;X mit Ausgabeposition laden
JSR ZIFFER ;erste Ziffer einlesen
JSR ZIFFER ;zweite Ziffer einlesen
JSR ZIFFER ;dritte Ziffer einlesen
JSR ZIFFER ;vierte Ziffer einlesen
*
* Nun werden die beiden Zaehler direkt in den Siebensegmentcode
* gewandelt, um gleich einfacher ausgegeben werden zu koennen.
*
LDB ANZHEX ;hexadezimale Anzahl laden...
JSR B7SG ;...codieren...
STD ANZHEX ;...und wieder speichern
LDB ANZDEZ ;dezimale Anzahl laden...
JSR B7SG ;...codieren...
STD ANZDEZ ;...und wieder speichern
*
* Nun die Tastaturabfrage und Auswertung der Tasten
*
TASTE JSR HALTKEY ;Auf Tastendruck warten
CMPB #$87 ;Taste "L" gedrueckt?
BEQ EINGABE ;ja, zur Eingabe zurueck
CMPB #$80 ;Taste "+" gedrueckt?
BEQ PLUS ;ja, zur Auswertung
CMPB #$81 ;Taste "-" gedrueckt?
BNE TASTE ;nein, zurueck zur Tasteneingabe
*
* Tasten "+" und "-" auswerten
*
LDD ANZHEX ;D mit codierter Anzahl in hexadezimal laden
LDY #0 ;Y mit "codierter Leere" laden
BRA AUSGABE ;zur Ausgabe
PLUS LDD #0 ;D mit "codierter Leere" laden
LDY ANZDEZ ;Y mit codierter Anzahl in dezimal laden
AUSGABE LDX #6 ;an Stelle S6...
JSR SHOWD ;...wird D ausgegeben (leer oder hex.)
TFR Y,D ;Y wird nach D kopiert...
LDX #0 ;...und an Stelle S0...
JSR SHOWD ;...ausgegeben (leer oder dezimal)
BRA TASTE ;Zurueck zur Tasteneingabe
*
* Unterprogramm ZIFFER
* Eingabe: Ausgabeposition in X; Tabellenzeiger in Y
* Ausgabe: -
* Aendert: X dekrementieren; ANZDEZ, ANZHEX entsprechend hochzaehlen;
* A und B zerstoert
* Die Routine wartet auf eine Hex.-Ziffer und gibt diese an Position X
* aus. Die Anzahl der Segmente dieser Ziffer werden den zwei
* Speicherstellen dazuaddiert.
*
ZIFFER JSR HALTKEY ;Auf Tastendruck warten
BMI ZIFFER ;Bit 7 gesetzt -> Funktionstaste -> ignorieren
JSR SHOWT7SG ;Taste in Siebensegmentcode wandeln und ausgeben
LDA ANZHEX ;Hex.-Zaehler laden...
ADDA B,Y ;...Segmentanzahl addieren...
STA ANZHEX ;...und speichern
LDA ANZDEZ ;Dezimal-Zaehler laden...
ADDA B,Y ;...Segmentzahl addieren...
DAA ;...BCD-Korrektur...
STA ANZDEZ ;...und speichern
TFR X,D ;Ausgabeposition nach D kopieren...
DECB ;...dekrementieren...
TFR D,X ;...und wieder nach X kopieren
RTS ;fertig
*
* Datenbereich
*
ANZHEX RMB 1 ;hexadezimaler Segmentzaehler
ANZDEZ RMB 1 ;dezimaler Segmentzaehler
* 0 1 2 3 4 5 6 7 8 9 A B C D E F
TABELLE FCB 6,2,5,5,4,5,6,3,7,5,6,5,3,5,5,4
U_END ORG * ;Ende des Programmbereichs
Assemblieren Sie das Programm, laden Sie es in den Simulator und starten Sie es. Worin zeigt sich das Fehlverhalten des Programms?
Schalten Sie das Registerfenster zur Beobachtung der Registerwerte ein. Lassen Sie das Programm nochmals ablaufen. Was beobachten Sie im Registerfenster?
Schalten Sie nun ein Speicherfenster zur Anzeige der beiden Zähler ein und lassen Sie dann das Programm laufen. Beantworten Sie folgende Fragen:
Laden Sie das Programm erneut in den Simulator und wiederholen Sie Teil c). Beantworten Sie folgende Fragen:
Nun sollen Sie kurz den integrierten Disassembler kennenlernen. Versuchen Sie, die Monitorroutinen zu disassemblieren. Öffnen Sie dazu ein Disassemblerfenster und lassen Sie sich den Speicherbereich ab $F100 anzeigen. Beantworten Sie folgende Fragen:
Disassemblieren Sie den Bereich ab $F200.
Schreiben Sie ein Programm, welches eine Codewandlung zwischen einigen ASCII-Zeichen und Hexadezimal-Ziffern ermöglicht. Das Programm soll ein Byte einlesen und dieses nach Betätigen der Taste "+" von hexadezimal nach ASCII und nach Betätigen der Taste "-" von ASCII nach hexadezimal wandeln. Danach soll das Programm von vorne beginnen.
Im einzelnen:
Datei 3A_VORL.ASM:
ORG $0400 ;Beginn des Programmbereichs
*
ANFANG JSR CLRDISP ;Anzeige loeschen
EINGABE JSR HALTKEY ;Zeichen von Tastatur lesen
ASLB ;viermal shift links, um das eingegebene Zeichen
ASLB ;in das obere Halbbyte von B zu uebertragen. Falls eine
ASLB ;Funktionstaste gedrueckt wurde, bleibt davon nur der
ASLB ;"Ziffernteil" im unteren Halbbyte ueber.
STB DATA ;Eingabe sichern
JSR HALTKEY ;zweites Zeichen von Tastatur lesen
ANDB #$0F ;oberes Halbbyte loeschen (falls Funktionstaste)
ORB DATA ;mit erstem Zeichen verknuepfen
LDX #0 ;Anzeigeposition
JSR SHOWB7SG ;B im Siebensegmentcode ausgeben
*
* nun beginnt das neue Programm
*
*
* Datenbereich
*
DATA RMB 1 ;Datenbereich zur Zwischenspeicherung der Eingabe
HEX FCB $00 ;hier beginnt die Hex.-Tabelle. Alle Werte werden
FCB $01 ;einfach einzeln als Byte-Datum definiert.
FCB $02 ;
FCB $03 ;
FCB $04 ;
FCB $05 ;
FCB $06 ;
FCB $07 ;
FCB $08 ;
FCB $09 ;
FCB $0A ;
FCB $0B ;
FCB $0C ;
FCB $0D ;
FCB $0E ;
HEXEND FCB $0F ;Ein Hilfs-Label zur Laengenberechnung
ASCII FDB $3031 ;die zweite Tabelle wird aehnlich definiert, jedoch
FDB $3233 ;mit dem Befehl FDB statt FCB.
FDB $3435 ;
FDB $3637 ;
FDB $3839 ;
FDB $4142 ;
FDB $4344 ;
ASCIIE FDB $4546 ;ASCIIEND als Label ist leider zu lang
TABLEN EQU 15 ;15 ist maximaler Offset auf Tabellenanfang
U_END ORG * ;Ende des Programmbereichs
Die Zeile "TABLEN EQU 15" definiert TABLEN als Konstante. Bei jeder Änderung der Tabellenlänge müßten Sie daran denken, diese Konstante entsprechend zu ändern. Um das zu umgehen, kann ein Assembler Konstanten berechnen, z.B. aus vorgegebenen Marken. Geben Sie eine Berechnung für TABLEN aus den Marken an, die in der Vorgabedatei angegeben sind (HEX, HEXEND, ASCII, ASCIIE). Tragen Sie Ihre Lösung bitte statt der Zeile "TABLEN EQU 15" in die Lösungsdatei 3A_EA.ASM zu Teilaufgabe a) ein.
In der Vorlagedatei 3A_VORL.ASM ist die Tabelle der ASCII-Zeichen (ab Marke ASCII) mit dem Pseudobefehl FDB statt FCB definiert. Wieso funktioniert das und was ist dabei zu beachten, wenn Sie mehrere Tabelleneinträge in einem Befehl definieren möchten? Wie könnten Sie die Tabelle auf andere Weise definieren?
Schreiben Sie ein Programm, welches einen Speicherbereich anzeigt. Zuerst soll eine Anfangsadresse eingegeben werden können. Danach soll durch Betätigung den Tasten "+" und "-" durch den Speicher gegangen werden können, wobei in S5..S2 die aktuelle Adresse und in S1..S0 das dort stehende Datum angezeigt werden soll.
Im einzelnen
Anzeige löschen
Kennung "Ad" in Stelle S7..S6 anzeigen und eine Adresse in Stelle S5..S2 einlesen. Ende der Eingabe mit einer beliebigen Funktionstaste, die nicht ausgewertet wird. Kennung "dA" an Stelle S7..S6 anzeigen, aktuelle Adresse an Position Stelle S5..S2 anzeigen, unter dieser Adresse stehendes Datum in Stelle S1..S0 anzeigen. Tastatur zyklisch abfragen:
Taste "+": aktuelle Adresse inkrementieren Taste "-": aktuelle Adresse dekrementieren anderen Tasten: keine Funktion weiter mit 3)
| Einsendeaufgaben zur Kurseinheit 1 | Einsendeaufgaben zur Kurseinheit 3 |