|
PC Inside ermöglicht die Programmierung des Mikroprozessoers durch mnemonische Befehle
und nach der Übersetzung der mnemonischen Befehle durch den eingebauten Assembler
einen Einblick in die Ausführung der Befehle durch den Mikroprozessor (simuliert 8086).
|
Hauptmenü
• Das Menü "Datei"
• Das Menü "Bearbeiten"
• Das Menü "Ansicht"
• Das Menü "Assembler"
• Das Menü "Ausführen"
• Das Menü "Extras"
Informationen und Arbeitsanleitungen zur Programmierung der PC-Inside-Maschine
• Der Mikroprozessor
• Der Arbeitsspeicher und die Segmenteinteilung
• Die verfügbaren Befehle und ihre Operanden
• Die Pseudobefehle des Assemblers
• Konventionen der Assemblerprogrammierung
• Die Fehlermeldungen des Assemblers
• Die Fehlermeldungen bei der Ausführung
• Die Editorbefehle
Sonstiges
• Aufgaben
• Homepage
----------------------------------------------------------------------
Das Menü "Datei"
Wählt man in der Menüleiste den ersten Menüpunkt "Datei" an, so erscheinen im Untermenü
folgende Punkte zum Verarbeiten von Dateien:
neu
Die Datei des aktiven Editorfensters wird gelöscht und bekommt den Namen "unbenannt".
Sind bereits eingegebene Daten noch nicht abgespeichert worden, wird jedoch zunächst angefragt,
ob diese vorher abgespeichert werden sollen.
Nun kann in der linken Karteikarte ein
neues Programm in Assemblersprache und in der rechten Karteikarte ein neues Programm in Maschinensprache
eingegeben werden. Da die Konstruktion von Maschinensprachebefehlen nur mit genauen Kenntnissen der
so genannten Opcodes möglich ist, kann man auch die Erzeugung des Maschinensprache-Programms
aus dem Asselbler-Programm durch den internen Assembler durchführen lassen.
An dieser Stelle muss darauf hingewiesen werden, dass die Erstellung eines solchen Maschinenprogramms
von Hand zwar möglich ist, wenn die Konventionen eingehalten werden
- eine vierstellige Hexadezimalzahl als Adresse, dann
- ein Leerzeichen Abstand und anschließend
- der codierte Befehl einschließlich der Operanden in hexadezimaler Schreibweise,
dass ein solches Verfahren jedoch ausgezeichnete Kenntnisse über das Codieren
der verwendeten Befehle verlangt.
Während ein Assemblerprogramm nicht unmittelbar ausgeführt werden kann,
kann ein solches mit Befehlscode versehenes Maschinenprogramm direkt vom
Befehlszeileninterpreter - Menüpunkt "Ausführen" - ausgeführt werden.
Trotzdem bleibt zu Übungszwecken die Eingabe der Maschinenbefehle "per Hand" möglich.
Durch Anklicken finden Sie weitere Hilfen über
- die zur Verfügung stehenden Editorbefehle und ihre Wirkung,
- die zur Verfügung stehenden Assemblerbefehle, ihre Bedeutung und Kodierung
- die notwendigen Konventionen zum Erstellen von Assemblerprogrammen,
- die Bedeutung der in PC-Inside verwendbaren Assembler-Pseudobefehle
equ (equate)
org (origin)
code [segment]
data [segment]
offset
db (define byte)
dw (define word)
byte ptr [by] (Typüberschreibung))
word ptr [wo] (Typüberschreibung)
sowie die Segmentüberschreibungspräfixe
cs:
ds:
es:
ss:
Datei öffnen
Es erscheint eine Dialogbox mit geöffnetem Ordner, welche die Auswahl
einer bereits abgespeicherten Datei ermöglicht. Nach dem Anklicken einer solchen
Datei wird die ausgewählte Datei geöffnet und im Hauptfenster dargestellt.
Das Hauptfenster bekommt als Zusatz den Namen der Datei. Nun können die Angaben
der geöffneten Datei verändert und der Kontostand berechnet werden.
Sind bereits eingegebene Daten noch nicht abgespeichert worden, wird jedoch
zunächst angefragt, ob diese vorher abgespeichert werden sollen.
Datei speichern
Die aktuelle Datei, die im Hauptfenster sichtbar ist,
wird gespeichert. Ist noch kein Dateiname vergeben, der Zusatz also noch "unbenannt",
so wird in einer Dialogbox die Eingabe des neuen Dateinamens angefordert.
speichern unter
Ein Dialogfenster wird geöffnet, das die Eingabe eines neuen Dateinamens mit oder ohne Pfadangabe ermöglicht.
Dann wird die aktuelle Datei, die im Hauptfenster sichtbar ist, gespeichert.
drucken
Die Konto-Angaben, die sich in der Karteikarte befinden, werden gedruckt. Vorher kann in der
Druck-Dialogbox die Anzahl der Kopien festgelegt werden. Ebenfalls kann dort gewählt werden,
ob nur die selektierten (markierten) Angaben oder alle gedruckt werden.
Druckereinstellung
Wird dieser Untermenüpunkt gewählt, erscheint ein Dialogfenster, in dem der Drucker und das
Format gewählt werden können.
Ende
Anklicken beendet die Anwendung.
----------------------------------------------------------------------
Das Menü "Bearbeiten"
Hier kann ausgewählt werden zwischen:
Zeilen ausschneiden
Die markierten Zeilen im jeweiligen Text werden in die Zwischenablage kopiert und im jeweiligen Text gelöscht.
Zeilen kopieren
Die markierten Zeilen im jeweiligen Text werden in die Zwischenablage kopiert.
Zeilen einfügen
Die Zeilen, die sich in der Zwischenablage befinden, werden an der markierten Stelle im jeweiligen Text eingefügt.
Zeilen löschen
Die markierten Zeilen im jeweiligen Text werden in der Karteikarte gelöscht.
Text suchen
Der gewünschte Text wird im jeweiligen Text gesucht.
suchen und ersetzen
Der gewünschte Text wird im jeweiligen Text gesucht und auf Wunsch durch einen anderen ersetzt.
----------------------------------------------------------------------
Das Menü "Ansicht"
Das Mikroprozessor-Fenster
Nach dem Anwählen erscheint auf der linken Hälfte der Arbeitsfläche das Modell eines Mikroprozessors.
Es handelt sich um den 8086, den Vorgänger der Prozessoren 80286, 80386, 80486 und des Pentium-Prozessors.
Zwar sind seine Nachfolger jeweils schrittweise mit weiteren Fähigkeiten ausgestattet worden,
eine wichtige Abwärtskompatibilität ist jedoch erhalten geblieben.
Die wichtigsten Eigenschaften der Prozessorregister können unter 8086 nachgelesen werden.
Fast alle Registerinhalte können verändert werden. Dadurch besteht die Möglichkeit,
beim späteren Ablauf eines Maschinenprogramms mit anderen Prozessorinhalten zu starten.
Nicht verändert werden können an dieser Stelle die Inhalte
- des Codesegment-Registers CS,
- des Datensegment-Registers DS,
- des Extrasegment-Registers ES und
- des Stapelsegment-Registers SS.
Das Codesegment-Fenster
Die Segmentadresse entspricht dem Inhalt des Codesegment-Registers im Mikroprozessor.
Damit kann also auch nur in diesem maximal 65536 Bytes (10000 hexadezimal) umfassenden
Segment geblättert werden.
Dieses Fenster zeigt auf den Programm-Code des aktuell ablaufenden Maschinenprogramms.
Sind alle Speicherplätze mit CC (hexadezimal) gefüllt, liegt kein Programm vor.
Nätürlich sind die für den Programm-Code reservierten Spiecherplätze vor dem
Überschreiben vom Codesegment-Fenster aus geschützt.
Das Datensegment-Fenster und das Extrasegment-Fenster
Nun wird ein Auschnitt des RAM-Speicherbereichs als Modell des Arbeitsspeichers gezeigt.
Darstellbar sind hierin die Inhalte aller Speicherplätze des Rechners, wobei der
Segmentwert auf einen gültigen Segment-Beschreiber zeigen muss und der Offsetwert
zwischen 0 und dem für das Segment maximalen Offsetwert liegen sollte. Wird dieser maximale
Wert überschritten, befindet man sich nicht mehr im gültigen Segment und die Inhalte werden z.B. mit
0070 xx xx xx xx xx xx xx xx x x x x x x x x
dargestellt. Ebenso wird ein Segment dargestellt, aus dem nicht gelesen werden darf.
Die Inhalte eines Segments, das nicht beschrieben werden darf, werden in roter Farbe dargestellt.
Wichtiges über die Speicherorganisation eines PCs kann während des Ablaufs im
Hilfetext unter Adressierung nachgelesen werden.
In diesem oben angegeben Adressbereich kann nun beliebig geblättert werden, um
die Speicherplatzinhalte in Augenschein zu nehmen. Dies ist einerseits durch die
Aktionsschalter weiter und zurück sowie durch die direkte Anwahl und
Eingabe einer gewünschten Offset-Adresse zu verwirklichen. Alle diese Möglichkeiten
erledigen jedoch nur das Blättern oder Springen innerhalb eines Segments.
Die vollständige Adresse ergibt sich dann aus der Segmentadresse, die
im Protected-Modus zu einem gültigen Segmentbeschreiber zeigen muss und durch die Offsetadresse
Vollständige Adresse = [Segmentadresse] : Offsetadresse.
In einem bestimmten Adressbereich des Daten- und Extrasegments können die
Inhalte der Speicherplätze verändert werden. Dies ist direkt im jeweiligen Fenster möglich.
Diese Eingabe wird durch Anklicken der einzelnen Felder oder durch
Auswahl mit Hilfe der TAB-Taste ermöglicht. Felder, die beim Anklicken nicht grün
erscheinen, erlauben keine Eingabe. Sie repräsentieren somit geschützte Speicherplätze.
Die Freigabe nur eines bestimmten Speicherbereichs hat natürlich das Ziel, wichtige
Bereiche vor dem Überschreiben zu schützen und damit auch das Programm vor seinem
Absturz zu bewahren.
Das Stapelsegment-Fenster
Hier besteht die Möglichkeit die Wirkung der Stapelverarbetungsbefehle zu prüfen. Die Inhalte des Stapelsegments
können nicht durch "ändern" beeinflusst werden.
Lediglich während des Ablaufs eines Maschinenprogramms kann das Stapelsegment durch Stapelbefehle beschrieben werden.
Speicher-Übersicht
Früher wurde hier eine "Segment-Übersicht" erstellt, da der Arbeitsspeicher bei 16-Bit-Computern in segment
aufgeteilt war. Nun jedoch kann auf den gesamten Arbeitsspeicher durch 32-Bit-Pointer zugegriffen werden.
Drücken auf "Start" liefert eine Übersicht über Speicherbereiche.
Nicht jeder Bereich ist jedoch lesbar oder beschreibbar.
Durch Anklicken eines Eintrags
kann man, falls der Bereich lesbar ist, einen Überblick über die Belegung des Bereichs bekommen.
Formulargröße 800x600
Formulargröße 1024x768
Formulargröße 1600x900
Das Anwendungsfenster wird auf die angegebene Größe gebracht. Damit kann sofort den Vorgaben mancher Grafik-Karten entsprochen werden. Selbstverständlich kann auch jede Zwischengröße mit der Maus aufgezogen oder der Maximalzustand gewählt werden.
Schrift ändern
Die Schrift für die gesamte Tabelle kann neu gewählt werden.
----------------------------------------------------------------------
Das Menü "Assembler"
Wählt man in der Menüleiste den vierten Menüpunkt "Assembler" an, so erscheint dort der Unterpunkt
Assemblieren
Beim Anwählen dieses Unterpunktes geschieht folgendes:
Es wird zunächst auf Karteikarte 1 das Editorfenster aufgesucht, das Programmtext
in Assemblersprache enthält. Danach beginnt der eingebaute Assembler in zwei Durchurchläufen
mit seiner Übersetzungsarbeit.
In einem entsprechenden Anzeigefenster wird außer dem Namen der gerade bearbeiteten Datei die
übersetzte Zeile sowie der jeweilige Durchlauf angezeigt. Im ersten Durchlauf findet die
Syntaxüberprüfung statt.
Außerdem wird die Anzahl der Bytes für jeden Befehl berechnet und mit diesem Wert der Inhalt eines
Befehlszeigers aktualisiert. Mit Hilfe dieses Befehlszeigers wiederum können die Marken und
Variablen gesetzt werden.
Im zweiten Durchlauf findet die Kodierung der Befehle statt. Es wird außerdem geprüft, ob die
Sprungadressen erreichbar sind.
Folgende Befehle werden z.Z. übersetzt:
aaa, aad, aam, aas, add, and, call, cbw, clc, cld, cli, cmc, cmp, cwd, daa, das, dec, div,
hlt, idiv, imul, in, inc, int, ,ja, jnbe, jae, jnb, jb, jnae, jbe, jna, jc, jcxz, je, jz,
jg, jnle, jge, jnl, jl, jmp, jnge, jne, jng, jnc, jne, jnz, jno, jns, jnp, jno, jo, jp, jpe,
js, lahf, lds, lea, les, mov, mul, neg, nop, not, or, out, pop, popf, push, pushf, rcl, rcr,
ret, rol, ror, sahf, sal, shl, sar, sbb, scashr, stc, std, sti, sub, test, wait, xchg, xlat, xor.
Folgende Befehle werden z.Z. nicht übersetzt:
cmps, esc, into, iret, lock, lods, loop, movs, rep, scas, stos.
Sie können allerdings mit Hilfe der Define-Byte-Anweisung und der direkten Angabe
des hexadezimalen Befehlscodes ins Programm eingefügt werden. Dies kann z.B durch die Befehlszeile
MovsBef db A5h
im Programmtext erfolgen. Weiterhin ist die Assembler-Anweisung code in der ersten
Zeile des Assemblerprogramms einzugeben, was bewirkt, dass die selbstdefinierten Bytes im
Codesegment abgelegt werden und vom Befehlszeiger des Assemblers als Code mitgezählt werden.
Im Maschinenprogramm findet sich die Zeile dann z.B. wie folgt wieder
0015.A5
Damit dieser Befehl ausgeführt wird, ist nun noch der Punkt zwischen Adresse und Befehlscode
mit einem Leerzeichen zu überschreiben. Der Programmierer ist nun selbst verantwortlich,
dass kein Ausnahmefehler z.B. durch Überschreitung der Segmentgrenze auftritt.
Bei Auftreten eines Fehlers erscheint eine Meldung, die die Zeile und die Art des Fehlers enthält.
Nach dem Bestätigen der Nachricht durch den Benutzer wird das Editorfenster geöffnet, das den
Programmtext enthält und mit dem Cursor an den Anfang der fehlerhaften Zeile gesprungen.
Nun kann mit der Fehlerkorrektur begonnen werden.
Ist trotzdem noch unklar, wodurch die Fehlermeldung hervorgerufen wurde, kann die
Assembler-Fehlerhilfe aufgerufen werden, die eine genauere Beschreibung des Fehlers macht.
Ist kein Fehler in dem zu übersetzenden Assemblerprogramm gefunden worden, erscheint die Nachricht
"Vorgang erfolgreich abgeschlossen". Nach der Bestätigung durch den Benutzer wird ein neues
Editorfenster mit dem Namen des Assemblerprogramms, jedoch der Dateierweiterung MAP geöffnet.
In diesem Fenster erscheint eine Textdatei, die sowohl die Textzeilen des Assemblerprogramms
wie auch - und zwar vorangestellt - die in Maschinensprache kodierten Befehle in hexadezimaler
Darstellung enthält. Diese Textdatei ist in etwa vergleichbar mit den LST-Dateien professioneller Assembler.
Wird nun das Assemblerprogramm verändert und erneut übersetzt, wird die zugehörige alte
Maschinensprachedatei einfach überschrieben.
----------------------------------------------------------------------
Das Menü "Ausführen"
Wählt man in der Menüleiste den vierten Menüpunkt "Ausführen" an, so erscheint dort das folgende Untermenü
starten
fortfahren
Durch Wahl dieser Unterpunkte gibt man zu verstehen, dass ein fertiges Maschinenprogramm
zu Demonstrations- oder Ausbildungszwecken auf dem Bildschirm ablaufen soll.
Nun sucht PC Inside zunächst, ob das zweite Editorfenster Programmtext in
Maschinensprache enthält. Danach erscheint ein großes Dialogfenster, in dem Sie die Parameter für
den Ablauf des Programms wählen können. In diesem Fenster stehen sowohl Einfachauswahl- als auch
Mehrfachauswahl-Schalter zur Verfügung:
Im linken oberen Bereich können Sie zunächst die Geschwindigkeit der Ausführung mit den Einzelauswahl-Schaltern
festlegen.
Ist "auf Tastendruck" gewählt, muss die Ausführung eines jeden Befehls mit der
"Weiter"-Taste angefordert werden. "In Einzelschritt-Automatik" bedeutet eine selbstständige Ausführung,
wobei die Geschwindigkeit als Ziffer dahinter eingegeben werden kann. Bei jedem Schritt werden Mikroprozessor
und Arbeitsspeicher neu auf dem Bildschirm abgebildet. "direkt bis Halt oder Ende" bedeutet
eine Ausführung bis zum nächsten Stoppsignal. Dieses kann durch Drücken der "Halt"- oder "Ende"-Taste,
durch Erreichen des Programmendes oder durch Eintreten einer der unter "Ablauf anhalten"
gesetzten Bedingungen erreicht werden. Erst dann erfolgt eine Ausgabe auf dem Bildschirm.
Je nach Platzbedarf kann ein breites oder schmales Steuerfenster für den Programmablauf gewählt werden.
Im linken unteren Bereich können Sie mit Hilfe der Einzelauswahl-Schalter angeben,
welches Fenster außer dem Mikroprozessorfenster beim Ablauf des Maschinenprogramms geöffnet
sein soll. Auch die Wahl eines Kombinationsfensters ist möglich. In diesem Fall muss am Ende
der darüber befindlichen Zeilen eine Hexadezimal-Ziffer 0,1,...,9,A,...,F eingegeben werden,
die die Anzahl der gewünschten Zeilen angibt, mit der die anderen Fenster im Kombinationsfenster
vertreten sein sollen. Ist keine Ziffer angegeben, wird 0 angenommen.
Rechts oben im Parameter-Dialogfenster können durch Mehrfachauswahl-Schalter Abbruchbedingungen
vorgegeben werden, bei denen das Maschinenprogramm anhält, wenn es sich im Modus 2 oder 3 befindet.
Das Programm setzt fort bis zum nächsten Haltepunkt, falls dann "Weiter" gedrückt wird.
Rechts unten wird durch einen Schalter festgelegt, ob beim Start eines Maschinenprogramms der
Mikroprozessor gelöscht werden soll, also ob alle Register in den Ausgangszustand gebracht
werden sollen. Die gleiche Bedingung kann für den Speicher und seine Inhalte gesetzt werden.
Darunter muss die Wahl getroffen werden, ob beim Ablauf eines Programms die Datenregister als
16-Bit-Register AX, BX, CX und DX oder als 8-Bit-Register AL, AH, BL, BH, CL, CH, DL und DH
angezeigt werden sollen.
Drücken von "Sichern" speichert die aktuelle Parametereinstellung unter dem Namen des auzuführenden
Maschinenprogramms ab, jedoch mit der Namenserweiterung PAM. Somit kann der Benutzer für jedes
Maschinenprogramm eine individuelle Parametereinstellung auf der Festplatte oder Diskette hinterlegen,
welche bei der Ausführung automatisch geladen wird.
Mit der Aktionstaste "OK" akzeptiert man die aktuelle Parameter-Einstellung. Das Dialogfenster schließt
sich, und das Ausführungsfenster wird geöffnet.
Dieser Absatz gilt nur bei vorheriger Wahl von Starten:
Schließt man das genannte Dialogfenster mit "OK" ab, werden Codesegment, Datensegment und
Stapelsegment mit vorgegebenen Inhalten gefüllt, so dass die Segmente in den entsprechenden
Segmentfenstern deutlich erkannt werden können. Die Prozessorregister werden, falls dies vorher
im Dialogfenster angekreuzt war, gelöscht. Andernfalls bleiben die Inhalte bestehen. Der Maschinencode
wird ins Codesegment geladen. Die Variablendaten werden je nach Anweisung des Maschinenprogramms
ins Code- oder ins Datensegment geladen. Hat der Befehlszeiger (IP-Register) im Mikroprozessor
einen Inhalt ungleich Null, wird als erste Befehlszeile diejenige gesucht, die durch den Befehlszeiger
adressiert ist. Ansonsten wird die erste Programmzeile als Befehlszeile gewählt.
Auf dem Bildschirm erscheint das Prozessorfenster sowie das gewählte Segment-, Programmtext- oder
Kombinationsfenster. Als weiteres Fenster wird nun das Ausführungsfenster geöffnet, mit dessen Schaltern
[Weiter], [Halt] und [Ende] die Ausführung des Maschinenprogramms gesteuert werden kann.
Nun beginnt auf Druck des Schalters "Weiter"der eingebaute Interpreter damit, die ausführbaren
Befehlszeilen dem realen Mikroprozessor des Personal-Computers zuzuführen. Die Befehle
aaa, aad, aam, aas, add, and, cbw, clc, cld, cli, cmc, cmp, cwd, daa, das, dec, div, hlt, idiv,
imul, in, inc, int, lahf, lds, lea, les, mov, mul, neg, nop, not, or, out, rcl, rcr, rol, ror, sahf, sal, shl, sar, sbb, scashr, stc, std, sti, sub, test, wait, xchg, xlat, xor
werden dabei wirklich ausgeführt.
Die Befehle für bedingte Sprünge
ja, jnbe, jae, jnb, jb, jnae, jbe, jna, jc, jcxz, je, jz, jg, jnle, jge, jnl, jl, jnge, jne,
jng, jnc, jne, jnz, jno, jns, jnp, jno, jo, jp, jpe, js
werden ebenfalls real ausgeführt. Der Sprung wird jedoch zu einer Abfangadresse geführt und die
restliche Ausführung simuliert. Ist die Befehlszeile mit der gewünschten Sprungadresse nicht auffindbar,
erscheint eine Fehlermeldung im Ausführungsfenster und die dem Sprungbefehl folgende Zeile wird geladen.
Die Ausführung der Befehle call, jmp und ret sowie push, pushf, pop, popf wird vollständig simuliert. Ist die Befehlszeile
mit der gewünschten Sprung-, Rücksprung- oder Aufrufadresse nicht auffindbar, erscheint eine Fehlermeldung
im Ausführungsfenster und die dem jeweiligen Befehl folgende Zeile wird geladen.
Die Befehle, die die Inhalte des Arbeitsspeichers verändern, werden vor der Ausführung überprüft.
Soll ein nicht freigegebener Speicherplatz überschrieben werden, erscheint eine Fehlermeldung im Ausführungsfenster,
der Befehl wird nicht durchgeführt und die dem jeweiligen Befehl folgende Zeile wird geladen.
Wurde wider Erwarten durch einen ausgeführten Befehl das CS- oder SS-Register verändert, erscheint eine
Fehlermeldung im Ausführungsfenster, die Wirkung des Befehls wird rückgängig gemacht und die dem jeweiligen
Befehl folgende Zeile wird geladen.
Alle bei der Ausführung auftretenden Fehlermeldungen führen nicht zu einem Abbruch des Ablaufs. Ist dem
Benutzer unklar, wodurch die Fehlermeldung hervorgerufen wurde, kann die Hilfe unter Ausführungsfehler
aufgerufen werden, die eine genauere Beschreibung des Fehlers macht.
Läuft das Programm in Einzelschrittautomatik ab oder direkt bis Halt oder Ende, kann es durch Drücken des
Schalters [Halt] jederzeit angehalten werden. Die anschließende Betätigung des Schalters "Weiter" führt zum Weiterlauf.
Durch Drücken des Schalters kann der Ausführungsmodus verlassen werden. Es wird dann das
Editorfenster des gerade abgelaufenen Maschinenprogramms in den Bildschirmvordergrung geholt.
----------------------------------------------------------------------
Das Menü "Extras"
Hier gelangt man zum Untermenü
Zähleranimation
Um die Umrechnung von einem Zahlsystem in ein anderes zu erleichtern, öffnet sich nun eine Zähleranimation.
Eine Zahl kann gesetzt und in drei Zahlsystemen betrachtet werden. Das Zählen kann nun durch erhöhen und vermindern
gezeigt werden. Insbesondere ist zu erknenn, dasss eine Umrechnung vom Dualsystem ins Hexadezimalsystem direkt ohne
Umweg über das Dezimalsystem erfolgen kann, da die rechten vier Bits im Dualsystem gerade
die Einerziffer des Hexadezimalsystems und die linken vier Bits im Dualsystem die Sechzehnerziffer
im Hexadezimalsystem ergeben.
Um die Verwendung von Integer-Zahlen (positive und negative ganze Zahlen - im Gegensatz zu nur positiven ganzen Zahlen)
näher zu bringen, ist der Zahlenkreis der 1-Byte-Zahlen angedeutet durch den rechten Zähler "Dezimalsystem mit Vorzeichen".
----------------------------------------------------------------------
Der Mikroprozessor
Das Mikroprozessor-Fenster zeigt ein Modell des im PC verwendeten Mikroprozessors. Dargestellt werden die
Register des Mikroprozessors 8086, also des Vorfahren der Prozessoren 80286, 80386, 80486 und des Pentium-Prozessors.
Da der eingebaute Assembler nur 8086er Befehle erzeugt, kann jeder der Nachfahren diese Befehle bearbeiten.
Beim Ablauf eines Maschinenprogramms kann somit dem Mikroprozessor im Innern des Computers
direkt bei der Arbeit zugeschaut werden. Zu sehen sind:
Die allgemeinen Register oder Datenregister:
ax oder [ah,al] Akkumulator
bx oder [bh,bl] Basis
cx oder [ch,cl] Zähler
dx oder [dh,dl] Daten
Hier steht x für "extended", was bedeuten soll, dass es sich um breite Register handelt.
Diese können 16-Bit-Daten verarbeiten, also Folgen von 16 Dualziffern, wie etwa 0100 1001 0010 1111 oder
ähnliches. Solche 16-Bit-Daten werden im folgenden als Datenwort oder kurz Wort bezeichnet. Es ist jedoch bei
den Datenregistern ax, bx, cx und dx möglich, jeweils die linke oder rechte Hälfte mit einem Befehl anzusprechen.
Hier steht h für high, l für low, was bedeutet, dass sich in ah die 8 höherwertigen Bits von ax und in al die 8
niederwertigen Bits von ax befinden. Solche 8-Bit-Daten werden im folgenden als Datenbyte oder kurz Byte bezeichnet.
Der Akkumulator stellt das wichtigste allgemeneine Register dar. Auf ihn beziehen sich die meisten
Befehle des Befehlssatzes. So bewirkt mul cx, dass der Inhalt des cx-Registers mit dem Inhalt des
ax-Registers multipliziert wird. Eine vergleichbare Multiplikation der Inhalte von bx und cx ist
hingegen nicht möglich. So gilt gegenüber dem Akkumulator für die anderen Datenregister bx,cx und dx
manchmal nur ein eingeschränkter Befehlssatz. Trotzdem haben diese Register über die Funktion von Ablagen
hinaus eine besondere Bedeutung oder Aufgabe.
Das bx-Register kann z. B. bei der indirekten Adressierung eine besondere Bedeutung erlangen. Der Befehl
mov ax,[bx]
bewirkt, dass der Inhalt des durch bx adressierten Wort-Speicherplatzes nach ax kopiert wird.
Ist also in bx gerade die Zahl 7 enthalten, wird das Datenwort an der Adresse 7 des Datensegments nach ax gebracht.
Das cx-Register wird seit jeher von Programmierern als Zähl-Register für Programmschleifen verwendet,
das dx-Register vorwiegend als Ablage.
Die Zeiger- und Indexregister:
sp Stapelzeiger
bp Basiszeiger
si Quellenindex
di Zielindex
Ihnen allen kommt bei der Adressierung eine besondere Bedeutung zu.
Während der Stapelzeiger auf die Spitze des Stapels im Stapelsegment zeigt und seinen Inhalt bei
Unterprogrammaufrufen, Rücksprüngen sowie push- und pop-Befehlen anpasst, muss der Basiszeiger je
nach Bedarf gesetzt werden. Er zeigt häufig auf die im Stapel befindlichen Übergabe-Parameter.
Die si- und di-Register übernehmen häufig Adressierungsaufgaben im Datensegment. Sie erlauben das
Kopieren von Speicherplatzinhalten an andere Stellen. So bewirkt die Befehlsfolge
mov ax,[si]
mov [di],ax ,
dass der Inhalt des durch si adressierten Speicherplatzes (source / Quelle) über ax zu dem durch di adressierten
Speicherplatz (destination / Ziel) gelangt. Ein direkter Transport ist allerdings nicht möglich.
Die Segmentregister:
cs Codesegment
ds Datensegment
ss Stapelsegment
es Extrasegment
Frühere Syteme: MS-DOS und Windows-16-Bit
Ohne die Segmentregister wäre der gesamte durch die Zeigerregister adressierbare Speicherbereich auf
216 = 65536 Plätze begrenzt. Jedes der Segmentregister ermöglicht nun jedoch, bis zu 65536 Plätze in
einem eigenen Segment zu kontrollieren. Diese Segmente sind nicht zwangsläufig getrennt, sie können
sich auch überlappen. Dies ist allerdings unter Windows nicht immer erwünscht, da gerade bei einem
Multitasking-System sehr sorgfältig kontrolliert werden muss, welche Programme auf welche Segmente
zugreifen können, hängt doch das Funktionieren aller anderen Programme davon ab, dass nicht unerwünschte
Veränderungen im Speicher stattfinden.
Daher läuft unter Windows der Prozessor in einem anderen Modus als unter DOS. Dieser neue Modus ist
erst den Prozessoren ab dem 80286 möglich und nennt sich Protected-Modus - im Gegensatz zum Real-Address-Modus
unter DOS. Der Protected-Modus ermöglicht einen störungsfreien Ablauf von mehreren Programmen "gleichzeitig".
Gleichzeitig heißt dabei, dass ein Programm, auch Task genannt, eine Botschaft an Windows sendet, wenn es im
Augenblick nichts zu tun hat außer zu warten. In diesem Augenblick gibt Windows eine Botschaft an die anderen
Programme (Tasks) im Arbeitsspeicher weiter, die nun je nach Bedarf aktiv werden können. Der Prozessor muss in
diesem Fall ständig die Zugriffsrechte der Programme auf die Segmente im Arbeitsspeicher überwachen. Für
jedes der vier oben genannten Segmente existiert im Prozessor abgespeichert ein sogenannter Segmentbeschreiber
mit Informationen über das jeweilige Segment, wie Länge des Segments, Art des Segments, Lese- und
Schreiberlaubnis usw.. So kann z.B generell nicht in ein Codesegment geschrieben werden, ohne eine
Schutzverletzung auszulösen. (Dies ist erst über Umwege möglich, wenn man sich zu diesem Segment einen
Alias-Datensegmentbeschreiber beschafft.)
Aus Segment-Angabe und Offset-Angabe kann die wirkliche Adresse nicht wie unter DOS einfach zusammengesetzt
werden, sie bleibt das Geheimnis des Windows-Betriebssystems. Die Segment-Angabe wird zu einem sogenannten
Selektor, der auf einen Eintrag in einer Beschreibertabelle im Speicher zeigt. Erst hier wird unter
Berücksichtigung der Offset-Angabe die Adresse berechnet.
Jetzige Windwos 32-Bit- und 64-Bit-Systeme:
Es gibt keine Segment-Verwaltung mehr. Alle Adressen werden durch 32-Bit-Zeiger
und 64-Bit-Zeiger komplett dargestellt. Daher ist der gesamte Adressraum viel einfacher zu verwalten.
Trotzdem werden durch solche Zeiger Codebereiche oder Datenbereiche verwaltet.
PC Inside 2.0 simuliert ein 16-Bit-System unter einem 32-Bit-Betriebssystem wie folgt:
Eine Segment-Verwaltung entfällt völlig. Die Segmentregister zeigen auf den Beginn des Code-
oder Datenbereichs. Sind können nicht mehr verändert werden. Nun gibt es nur einen Codesegmentbereich,
einen Datensegmentbereich, einen Extrasegmentbereich und einen Stapelsegmentbereich
– jeweils mit reservierten 4096 Bytes. Jeder Speicherplatz dieser Segmentbereiche kann
über sein Offset ausgelesen oder mit einem Wert belegt werden. Somit ergeben sich nur einfache
Offset-Adressierungen in den vier Segmentbereichen.
Der Befehlszeiger:
ip Befehlszeiger
Der Befehlszeiger (instruction pointer) zeigt auf die Adresse des als nächstes durchzuführenden
Befehls im Codesegment.
Das Statusregister:
Als Kennzeichen oder Flags bezeichnet man die 1-Bit-Zustände des Statusregisters. Beim Zustand 1 sagt man,
das Kennzeichen oder Flag ist gesetzt, beim Zustand 0 sagt man, es ist nicht gesetzt. Nicht alle Kennzeichen
besitzen gleich große Bedeutung.
Von besonderer Bedeutung sind
- das Vorzeichen-Kennzeichen oder auch Sign-Flag s,
- das Null-Kennzeichen oder auch Zero-Flag z und
- das Übertrags-Kennzeichen oder auch Carry-Flag c.
Von geringerer Bedeutung sind
- das Überlauf-Kennzeichen oder auch Overflow-Flag o
- das Paritäts-Kennzeichen oder auch Parity-Flag p und
- das Hilfs-Kennzeichen oder auch Auxilary-Flag a .
Ansonsten existieren noch
- das Richtungs-Kennzeichen oder Direction-Flag d
- das Unterbrechungs-Kennzeichen oder auch Interrupt-Flag i und
- das Einzelschritt-Kennzeichen oder auch Trap-Flag t .
Nicht jeder Befehl beeinflusst die Zustände der Kennzeichen. Der mov-Befehl z.B. ändert keines
der Kennzeichen-Zustände. Hier die Wirkung einiger häufiger Befehle:
Befehl o s z a p c
add    + + + + + + add
and    0 + + u + 0 and
clc    - - - - - 0 clear carry-flag
cmc    - - - - - + complement carry-flag
cmp    + + + + + + compare
dec    + + + + + - decrement
div    u u u u u u divide
inc    + + + + + - increment
mov    - - - - - - move
mul    + u u u u + multiply
neg    + + + + + + negate (Zweierkomplement)
not    - - - - - - Invert (Einerkomlement)
or     0 + + u + 0 or
stc    - - - - - 1 set carry flag
sbb    + + + + + + subtract with borrow
sub    + + + + + + subtract
xor    0 + + u + 0 exclusiv or
Es bedeutet
+: Beeinflussung,
-: keine Beeinflussung,
u: undefinierter Zustand,
0: löschen,
1: setzen.
Das Sign-Flag wird gesetzt, wenn eine entsprechende Operation, die auf einen oder mehrere Operanden des Typs
- Datenbyte wirkt, ein Ergebnis zwischen 128 (80h) und 255 (0FFh),
- Datenwort wirkt, ein Ergebnis zwischen 32768 (8000h) und 65535 (0FFFFh)
liefert.
Es ist somit genau dann gesetzt, wenn das höchstwertige (linke) Bit des Ergebnisses gesetzt ist.
Das Zero-Flag wird gesetzt, wenn eine entsprechende Operation, die auf einen oder mehrere Operanden
des Typs Datenbyte oder Datenwort wirkt, das Ergebnis 0 liefert.
Das Carry-Flag wird gesetzt, wenn eine entsprechende Operation, die auf einen oder mehrere Operanden
des Typs Datenbyte oder Datenwort wirkt, einen Übertrag liefert oder ein Borgen benötigt.
Das Overflow-Flag wird gesetzt, wenn eine entsprechende Operation, die auf einen oder mehrere Operanden
des Typs Datenbyte oder Datenwort wirkt, einen Überlauf liefert.
Das Parity-Flag wird gesetzt, wenn eine entsprechende Operation, die auf einen oder mehrere Operanden
des Typs Datenbyte oder Datenwort wirkt, eine gerade Anzahl von Einsen (in binärer Darstellung) liefert.
Das Auxilary-Flag wird gesetzt, wenn eine entsprechende Operation, die auf einen oder mehrere Operanden
des Typs Datenbyte oder Datenwort wirkt, einen Überlauf bei den 4 niederwertigen Bits bei BCD-Darstellungen liefert.
----------------------------------------------------------------------
Der Arbeitsspeicher und die Segmenteinteilung
Die Adressierung des Arbeitsspeichers hängt vom Modus ab, in dem der Prozessor arbeitet.
Ältere Prozessoren - wie der 8086 - arbeiteten in einem Modus, den man den Real-Address-Modus nennt.
Das Betriebssystem MS-DOS läuft ausschließlich in diesem Modus ab.
Arbeitsspeicher im Real-Address-Modus:
Mit den 20 Adressleitungen des 8086 können 2 20 = 16 5 = Hex FFFFF = 1048576 verschiedene Speicherplätze mit 1 Byte (8 bit) Größe
angesprochen werden. Die vollständige Adresse (adr) erhält man aus einer Segmentangabe (seg) und einer
Offsetangabe (off) durch die Rechnung:
adr = seg·16 + off .
Dies ist die reale Adresse im Arbeitsspeicher. Man spricht von realer Adressierung.
Seit dem 80286 können die Prozessoren in den sogenannten Protected-Modus umschalten, der es dem Anwender erlaubt, mehrere
Programme gleichzeitig in den Arbeitsspeicher zu laden: Multiuse- und Multitask-Konzept. Dieses wird vom Betriebssystem
Windows unterstützt. Dabei müssen sich die geladenen Programme den Arbeitsspeicher so aufteilen, dass der Zugriff auf
gemeinsame Daten zwar möglich ist, ein Zugriff auf kritische Daten jedoch verwehrt wird.
Arbeitsspeicher im Protected-Modus:
Speicherplätze im Arbeitsspeicher werden nach den Grundsätzen der virtuellen Adressierung vergeben.
Dazu wird der Adressraum in Segmente mit beliebiger Größe, höchstens jedoch 64 KByte, unterteilt.
Diese Segmente sind mit besonderen Zugriffsrechten (Privilegstufen) versehen.
Seit Windows 32 bit und Windows 64 bit ist überhaupt keine Einteilung in Segmente mehr nötig,
da genügend Adressraum direkt verwaltet werden kann. Es genügt, eine 32-Bit-Adresse bzw. 64-Bit-Adresse einzugeben.
Es gibt 2 32 = 16 8 = Hex FFFF FFFF = 294.967.296 mögliche 32-Bit-Adressen (über 290 Megabyte) und
es gibt 2 64 = 16 16 = Hex FFFF FFFF FFFF FFFF = 18.446.744.073.709.551.616
mögliche 64-Bit-Adressen (über 18 Millionen Terabyte)
PC Inside 2.0 nutzt folgende Möglichkeit: Wenn man den 32-Bit-Zeiger oder den 64-Bit-Zeiger zum Anfang
des Codebereichs oder des Datenbereichs kennt (wird intern in PC Inside 2.0 verwaltet), kann der Assemblerprogrammierer
über einen Offsetwert von 16 Bit die weiteren Adressen dieses Bereichs ansprechen.
Das reicht zur Programmierung völlig aus.
Datenzugriffe: Man kann nur auf Daten zugreifen, die auf derselben oder einer niedrigeren Privilegstufe
liegen als die aktuelle Privilegstufe. Daher kann man mit einer Anwendung nicht auf Daten des Betriebssystems
zugreifen, ohne dass ein Ausnahmefehler erzeugt wird.
Codezugriffe: Man kann mit Sprung- oder Call-Befehlen nur auf Code gleicher Privilegstufe wie die aktuelle
zugreifen. Mit Call-Gates kann jedoch auch auf Code höherer Privilegstufe (z.B. Betriebssystem) zugegriffen
werden, ohne dass ein Ausnahmefehler erzeugt wird.
Der Offsetwert:
Während die Segmentregister des Prozessors die Segmentangabe verwalten, stellen die Zeigerregister die Offsetangabe zur Verfügung.
Beispiel:
mov ds:[di],15
gibt an, dass für die vollständige Adresse des 1. Operanden die Segmentangabe dem Datensegment-Register (ds)
und die Offsetangabe dem Zielindex-Register entnommen werden soll.
Beim Speichern eines Datenworts wird das niederwertige Byte in dem angegeben Speicherplatz, das höherwertige
Byte in dem um 1 höheren Speicherplatz hinterlegt.
Beispiel:
mov [1256h],3311h
bewirkt, dass im Speicherplatz mit der Adresse 1256h der Wert 11h hinterlegt wird und im Speicherplatz
mit der Adresse 1257h der Wert 33h. Während ein Register den Inhalt 3311 (hexadezimal) anzeigen würde,
zeigt der Wortspeicherplatz den Inhalt wie folgt an:
1256: 1133 (beides hexadezimal).
Der Mikroprozessor gestattet wegen seiner 4 Segment-Register den umittelbaren Zugriff auf 4 Segmente des
Arbeitsspeichers: Das Codesegment, das Datensegment, das Stapelsegment und das Extrasegment. Diese Segmente
können sich natürlich überlappen. Wird z.B. das Codesegment nicht vollständig genutzt, bietet es sich an, an seinem
Ende das Datensegment beginnen zu lassen, um keinen Speicherplatz zu verlieren.
Von besonderer Bedeutung ist natürlich die Bearbeitung der Daten im Datensegment. So wird bei allen Befehlen,
die als Operand eine Datenadresse haben, davon ausgegangen, dass das Datensegment gemeint ist - es sei denn, es
wird bei der indirekten Adressierung das bp-Register verwendet oder es wird ausdrücklich eine
Segmentregister-Überschreibung durchgeführt.
Beispiel:
mov [bx],7 ; speichern von 7 im Datensegment
mov [bp],9 ; speichern von 7 im Stapelsegment
mov ds:[bp],9 ; speichern von 9 im Datensegment
mov es:[bx],9 ; speichern von 9 im Extrasegment
Adressierungsarten
Die Register-Adressierung (hier siehe 1. Operand):
mul bx ;multipliziere die Inhalte von ax und bx
mov cx,6 ;lade cx mit 6
mov dx,ax ;lade dx mit Inhalt von ax
Die umittelbare Adressierung (hier siehe 2. Operand):
mov ax,7 ;lade ax mit 7
add cl,11001100b ;addiere zum Inhalt von cl den Wert 11001100b
sub ah,'A' ;subtrahiere vom Inhalt von ah den Wert 'A'
cmp dx, 0B7h ;vergleiche Inhalt von dx mit 0B7h
Die direkte Adressierung (hier siehe 1. Operand):
mov [7],ax ;lade den Speicherplatz 7 und 8 mit dem Inhalt von ax
add [0FFh],ax ;addiere zum Wort an der Adresse 0FFh den Inhalt von ax
mov es:3,cl ;speichere den Inhalt von cl im Extrasegment an der Adresse 3
mov word ptr[4],5 ;speichere 5 als Datenwort an Adresse 4 und 5
mov wo[4],5 ;(Kurzform) speichere 5 als Datenwort an Adresse 4 und 5
Die eckigen Klammern deuten an, dass es sich nicht um eine Zahl, sondern um eine Speicherplatzadresse handelt.
Dieses erreicht man ebenfalls durch eine Segmentüberschreibung wie z.B. „es:“.
Die indirekte Adressierung (hier siehe 1. Operand):
add [bx],ax ;mit Basisregister
add [si],cx ;mit Indexregister
add [bp][di],al ;mit Basis- und Indexregister
add [bp][di][120],dh ;mit Basisregister, Indexregister und Verschiebeanteil
----------------------------------------------------------------------
Die verfügbaren Befehle und ihre
Operanden
Befehl/ Befehlstyp:
mov Ziel, Quelle (Byte oder Wort übertragen)
Operanden: | Beispiele: |
Speicher, Akkumulator | mov es:1,al |
Akkumulator, Speicher | mov ax,[bx] |
Register, Register | mov cx,bx |
Register, Speicher | mov dl,cs:[4] |
Speicher, Register | mov [di]+10,ax |
Register, unmittelbar | mov cx,7 |
Speicher, unmittelbar | mov byte ptr [200],19 |
Register, Segmentregister | mov ax,cs |
Speicher, Segmentregister | mov [0],ss |
| |
| |
| |
Befehl/ Befehlstyp:
adc Ziel, Quelle (addiere mit Übertrag)
add Ziel, Quelle (addiere)
and Ziel, Quelle (logisches Und)
cmp Ziel, Quelle (vergleiche)
or Ziel, Quelle (logisches Oder)
sbb Ziel, Quelle (subtrahiere mit Carry-Flag)
sub Ziel, Quelle (subrahiere)
test Ziel, Quelle (exclusives Oder)
xor Ziel, Quelle (exclusives Oder)
Operanden: | Beispiele: |
Register, Register | xor cx,bx |
Register, Speicher | cmp dl,cs:[4] |
Speicher, Register | add [di]+10,ax |
Akkumulator, unmittelbar | and ax,00010000b |
Register, unmittelbar | or cx,7 |
Speicher, unmittelbar | sub byte ptr [200],19 |
Befehl/ Befehlstyp:
dec Ziel (vermindere um 1)
inc Ziel (erhöhe um 1)
Operanden: | Beispiele: |
Register | inc cx inc al |
Speicher | inc word ptr [bx][si] |
Befehl / Befehlstyp:
div Quelle (dividiere ohne Vorzeichen)
idiv Quelle (dividiere mit Vorzeichen)
imul Quelle (multipliziere mit Vorzeichen)
mul Quelle (multipliziere ohne Vorzeichen)
neg Quelle (bilde Zweierkomplement)
not Quelle (bilde Einerkomplement)
Operanden: | Beispiele: |
Register | div cx not al |
Speicher | mul word ptr [bx][si] |
| |
Befehl / Befehlstyp:
rcl Ziel, Anzahl (links rotieren durch Carry-Flag)
rcr Ziel, Anzahl (rechts rotieren durch Carry-Flag)
rol Ziel, Anzahl (links rotieren)
ror Ziel, Anzahl (rechts rotieren)
sal Ziel, Anzahl (arithmetisch links verschieben)
sar Ziel, Anzahl (arithmetisch rechts verschieben)
shl Ziel, Anzahl (logisch links verschieben)
shr Ziel, Anzahl (logisch rechts verschieben)
Operanden: | Beispiele: |
Register, n | rcl cx,5 |
Register, cl | rcr dl,cl |
Speicher, n | sar word ptr [di]+10,3 |
Speicher, cl | shr byte ptr [200],cl |
Befehl / Befehlstyp:
xchg Ziel, Quelle (austauschen)
Operanden: | Beispiele: |
Akkumulator, Register | xchg ax,cx |
Register, Register | xchg dl,cl |
Speicher, Register | xchg [di]+10,bl |
Befehl / Befehlstyp:
lds Ziel, Quelle (Zeiger einschließlich ds laden) - in PC Inside32 nicht mehr erlaubt
lea Ziel, Quelle (Offset-Adresse laden)
les Ziel, Quelle (Zeiger einschließlich es laden) - in PC Inside32 nicht mehr erlaubt
Operanden: | Beispiele: |
Register, Speicher | lea ax,[bp] |
Befehl / Befehlstyp:
jmp Ziel (unbedingter Sprung)
Operanden: | Beispiele: |
Marke | jmp Weiter |
Register | jmp ax |
Speicher | jmp [20h] |
Befehl / Befehlstyp:
jmp short Ziel (unbedingter Kurz- Sprung)
ja / jnbe (Sprung bei über / nicht unter oder gleich)
jae / jnb (Sprung bei über oder gleich / nicht unter)
jb / jnae (Sprung bei unter / nicht über oder gleich)
jbe / jna (Sprung bei unter oder gleich / nicht über)
jc (Sprung bei gesetzem Carry-Flag)
jcxz (Sprung, falls Inhalt von cx-Register null)
je / jz (Sprung bei gleich / gestztem Zero-Flag)
jg / jnle (Sprung bei größer / nicht kleiner oder gleich)
jge / jnl (Sprung bei größer oder gleich / nicht kleiner)
jl / jnge (Sprung bei kleiner / nicht größer oder gleich)
jle / jng (Sprung bei kleiner oder gleich / nicht größer)
jnc (Sprung bei nicht gesetztem Carry-Flag)
jne / jnz (Sprung bei nicht gleich / nicht gesetztem Zero-Flag)
jno (Sprung bei nicht gesetztem Overflow-Flag)
jnp / jpo (Sprung bei nicht gesetztem Parity-Flag / ungerader Parität)
jns (Sprung bei nicht gesetztem Sign-Flag)
jo (Sprung bei gesetztem Overflow-Flag)
jp / jpe (Sprung bei gesetztem Parity-Flag / gerader Parität)
js (Sprung bei gesetztem Sign-Flag)
Operanden: | Beispiele: |
Marke | jmp short Weiter |
Marke | jnc Ende |
Marke | jz Begin |
Befehl / Befehlstyp:
call Ziel (Prozedur-Aufruf)
Operanden: | Beispiele: |
Marke | call Prozedur |
Register | call ax |
Speicher | call [20h] |
Befehl / Befehlstyp:
ret [Anzahl] (Prozedur-Rücksprung)
Operanden: | Beispiele: |
[n] | ret |
[n] | ret 4 |
Befehl / Befehlstyp:
push Ziel (lege Wort auf dem Stapel ab)
pop Quelle (hole Wort vom Stapel)
Operanden: | Beispiele: |
Register | push cx |
Speicher | pop [20h] |
Register | push cx |
Befehl / Befehlstyp:
int (Unterbrechungsanforderung)
Operanden: | Beispiele: |
[Konstante (0-255)] | int 3 |
[Konstante (0-255)] | int 15 |
Befehl / Befehlstyp:
aaa (ASCII-Anpassung für Addition)
aad (ASCII-Anpassung für Division)
aam (ASCII-Anpassung für Multiplikation)
aas (ASCII-Anpassung für Subtraktion)
cbw (wandle Byte in Wort um)
clc (lösche Carry-Flag)
cld (lösche D-Flag)
cli (lösche I-Flag)
cmc (komplementiere Carry-Flag)
cwd (wandle Wort in Doppelwort um)
daa (dezimale Anpassung für Addition)
das (dezimale Anpassung für Subtraktion)
hlt (Halt)
iret (Rückkehr von Unterbrechung)
lahf (Register ah mit Flags laden)
popf (hole Flags vom Stapel)
pushf (lege Flags auf Stapel)
sahf (Flags aus Register ah laden)
stc (setze Carry-Flag)
std (setze D-Flag)
sti (setze I-Flag)
wait (warten)
xlat (Übersetzen)
Operanden: | Beispiele: |
keine | cmc |
keine | std |
----------------------------------------------------------------------
Die Pseudobefehle des Assemblers
Der Assembler übersetzt die mnemonischen Befehle eines in Assemblersprache geschriebenen
Programms in ausführbare Maschinensprache-Befehle. Die Länge eines solchen Maschinenbefehls
kann zwischen einem und sieben Bytes variieren. Ein interner Adresszeiger verwaltet dabei die
Adressen des Programmcodes. Er wird nach jedem übersetzten Befehl um die Länge dieses Befehls
weitergestellt und zeigt somit auf die Adresse des nächsten Befehls. Befehlsadressen und
Befehle werden dann durch PC Inside in einer neuen Datei als Hexadezimalzahlen den Mnemoniks
vorangestellt.
Um die Lesbarkeit zu verbessern oder um die Eindeutigkeit bei bestimmten Operanden
zu gewährleisten, können oder müssen dem Assembler zuätzliche Anweisungen gegeben
werden. Man nennt sie Pseudo-Befehle oder Pseudo-Anweisungen. Für PC Inside stehen
folgende Pseudo-Anweisungen zur Verfügung:
Anweisung:
equ (equate - einer Konstanten einen Wert zuweisen)
Operanden: | Beispiele: |
Dezimalzahl | Zahl1 equ 35 |
Hexadezimalzahl | Zahl2 equ 0B3h |
Dualzahl | Zahl3 equ 00100010b |
Zeichen | Zahl4 equ 'K' |
andere bereits definierte Konstante | Zahl5 equ Zahl2 |
Anweisung:
org (origin, Adresszeiger des Assemblers setzen)
Operanden: | Beispiele: |
Konstante | org 100h |
Konstante | org Setup |
Der der org-Anweisung folgende Befehl bekommt beim Assemblieren den Operand
der org-Anweisung als neue Adresse.
Anweisung:
code [segment] (auf den Adresszeiger für Codesegment umschalten)
data [segment] (auf den Adresszeiger für Datensegment umschalten)
Operanden: | Beispiele: |
keine | code |
keine | data |
Beim Assembler-Vorgang bekommen Befehle bestimmte Adressen im Codesegment
und Daten bestimmte Adressen im Code- oder Datesegment zugewiesen.
Daten im Codesegment können nur gelesen werden, Daten im Datensegment
können auch überschrieben werden. Werden mit der db- oder dw-Anweisung
Datenvariable definiert, so muss der Assembler wissen, ob sie ihre Adressen
im Code- oder Datensegment zugewiesen bekommen. Zu Beginn des Vorgangs nimmt
der Assembler das Codesegment an. Durch die data-Anweisung kann jedoch auf das
Datensegment umgeschaltet werden. Auch kann mit der code-Anweisung wieder
zurückgeschaltet werden. Beim Ablauf des Programm befinden sich dann die Daten
im richtigen Segment.
Anweisung:
Der Doppelpunkt hinter einem Namen mit maximal 8 Buchstaben definiert eine
Marke (Label) im Codesegment
Operanden: | Beispiele: |
vorangestellter Name mit | Start: |
maximal 8 Buchstaben | Schleife: |
Eine Marke dient der Kennzeichnung einer Stelle vor einem Befehl im Programmtext.
Zu dieser Marke kann dann gesprungen werden oder ein Unterprogrammaufruf erfolgen.
Anweisung:
db (define byte)
- Steht db hinter einem Namen mit maximal 8 Buchstaben, definiert db eine
Variable im Code- oder Datensegment.
- Steht db vor einer Konstanten, wird dadurch Speicherplatz reserviert und
der Wert der Konstanten dem Speicherplatz vor Programmablauf zugewiesen.
- Steht db vor mehreren Konstanten, wird dadurch Speicherplatz reserviert und
der Wert der Konstanten den Speicherplätzen vor Programmablauf zugewiesen.
- Fehlt nach db die Angabe einer Konstanten, wird ein Byte-Speicherplatz
reserviert. Der Inhalt bleibt jedoch undefiniert.
Operanden: | Beispiele: |
Name mit | Var1 db 25 |
8 Buchstaben | Var2 db 15,8,255 |
Konstante(n) | Var3 db 34h,'W' |
Text | Hallo db 'Hallo Freunde',13 |
Anweisung:
dw (define word)
- Steht dw hinter einem Namen mit maximal 8 Buchstaben, definiert dw eine
Variable im Code- oder Datensegment.
- Steht dw vor einer Konstanten, wird dadurch ein Wort-Speicherplatz reserviert
und der Wert der Konstanten dem Speicherplatz vor Programmablauf zugewiesen.
- Fehlt nach dw die Angabe einer Konstanten, wird ein Wort-Speicherplatz reserviert.
Der Inhalt bleibt jedoch undefiniert.
Operanden: | Beispiele: |
Name mit | Var1 dw 25 |
8 Buchstaben | Var2 dw 8255 |
Konstante(n) | Var3 dw Konst1 |
Anweisung:
offset (liefert die Offset-Adresse einer Marke oder Variablen)
Operanden: | Beispiele: |
Marke | mov ax, offset Schleife |
Marke | mov si, offset Hallo |
Marke | mov [si]offset Hallo,bx |
Wenn nicht der Inhalt sondern die Adresse des Speicherplatzes benötigt wird,
ist die Anweisung offset voranzustellen.
Anweisung:
byte ptr (- oder kurz by - legt das Typattribut fest oder überschreibt es)
Operanden: | Beispiele: |
Konstante | mov al, byte ptr 4000h |
Speicher | mov byte ptr [bp],-5 |
Anweisung:
word ptr (- oder kurz wo - legt das Typattribut fest oder überschreibt es)
Operanden: | Beispiele: |
Konstante | mov [12], word ptr -101 |
Speicher | mov word ptr [bp],-5 |
Anweisung:
short (setzt das Typattribut einer Marke auf short)
Operanden: | Beispiele: |
Marke | jmp short Weiter |
Marke | jmp short Schleife |
Befindet sich die Sprungadresse um weniger als 128 Bytes nach oben oder unten
entfernt, kann ein Zeit- und Byte-sparender Kurzsprung erfolgen. Diese Anweisung
ist dann nötig, wenn die Sprungmarke später im Programmtext folgt und somit
der Assembler beim 1. Durchlauf noch nicht weiß, in welcher entfernung die Marke
kommen wird. Stellt sich dann heraus, dass die Marke trotz short-Anweisung weiter
als 128 Bytes entfernt ist, meldet der Assembler einen Schrittfehler.
Anweisung:
cs: ds: ss: es: (Segmentüberschreibungspräfixe)
Bei der driekten und indirekten Adressierung werden die Speicherplätze vom
Assembler im Datensegment angenommen. Lediglich, wenn eine indirekte Adressierung
mit dem bp-Register erfolgt, wird das Stapelsegment angenommen. Befinden sich
die Speicherplätze jedoch, anders als vom Assembler angenommen, in einem anderen
Segment, also z. B. im Codesegment oder Extrasegment, ist eine Segmentüberschreibung
notwendig.
Operanden: | Beispiele: |
direkte Adresse | mov al, cs: 4000h |
indirekte Adresse | mov ds:byte ptr [bp],-5 |
Variablen können im Code- oder Datensegment stehen. Hier muss in jedem Fall
eine Segmentangabe erfolgen.
Operanden: | Beispiele: |
Adresse | mov ds:Var1,333 |
Adresse | mov ah,cs:Var2 |
Beim Ablauf eines Maschinenprogramms unter PC Inside ist jedoch das Codesegment
vor dem Überschreiben geschützt.
----------------------------------------------------------------------
Konventionen bei der Programmierung in Assemblersprache
An den folgenden Befehlszeilen sollen zunächst die Konventionen der Programmierung in
Assemblersprache verdeutlicht werden:
mov ax, 5 ;lade das Register ax mit der Zahl 5
Summe:   add ax, 4 ;addiere zum Inhalt von ax die Zahl 4
- Die Befehle selbst werden nicht linksbündig in der Befehlszeile eingegeben,
sondern mit einem Abstand von etwa 8 Zeichen zum linken Rand im sogenannten
Befehls- oder Mnemonikfeld. Man erreicht dieses Feld vom linken Rand aus durch
Drücken der Tabulator-Taste im Editor.
- Die Operanden werden unmittelbar hinter den Befehl mit einem Leerzeichen
Abstand geschrieben. Jedoch ist es auch möglich, sie in ein eigenes Operandenfeld
in 7 oder 8 Zeichen Abstand vom Anfang des Befehlsfeldes einzugeben.
Zwei Operanden werden durch ein Komma voneinander getrennt.
- Der Kommentar wird durch ein vorangestelltes Semikolon eingeleitet. Soll ein
Befehl kommentiert werden, steht er hinter den Operanden im Kommentarfeld, soll
ein Programm oder Programmabschnitt kommentiert werden, kann er auch linksbündig
in einer Textzeile stehen.
- Der linke Rand eines Assemblerprogramms ist für die Marken- und Variablennamen
reserviert. Sie stehen im sogenannten Markenfeld links in der Zeile.
----------------------------------------------------------------------
Die Fehlermeldungen des Assemblers
Angabe des Segmentregisters ist notwendig
Bei dem verwendeten Operand handelt es sich um eine Variable. Diese kann aber nun
im Codesegment-Teil des Programmtextes oder im Datensegment-Teil des Programmtextes
deklariert sein. Dies muss dem Assembler durch Angabe des Segmentes mitgeteilt werden.
Der Programmierer muss für die Richtigkeit dieser Angabe selbst Sorge tragen, da sonst
ein Speicherplatz im falschen Segment angesprochen wird.
Beide Operanden haben verschiedene Länge
Bei den beiden verwendeten Operanden ist der eine vom Typ Byte, der andere vom Typ Wort.
Dies ist durch eine geeignete Typüberschreibung richtigzustellen.
Byte- oder Wort-Speicherplatz?
Tritt auf, wenn bei Befehlen als Zieloperand eine direkte oder indirekte Adresse
angegeben wird, ohne jedoch zu vermerken, ob an dem Speicherplatz ein Datenbyte oder
ein Datenwort abgelegt werden soll. Wenn zusätzlich kein Quelloperand existiert oder
über seine Länge (Byte oder Wort) ist nichts bekannt ist, kann auch auf diesem Wege
keine Information vom Assembler geholt werden. Hier wird beim Zieloperand einer der Zusätze
byte ptr oder kurz by
word ptr oder kurz wo
zur Typüberschreibung notwendig.
Befehlsunverträgliche Operanden
Operand und Befehl passen nicht zueinander. Angaben zu den
Befehlen und ihren Operanden sind unter Befehle zu finden.
Falsche Klammersetzung
Bei der registerindirekten Adressierung wurden die eckigen
Klammern falsch gesetzt.
Fehlerhafte Zahl oder Konstante
Die Konstante konnte nicht ermittelt werden, da störende Zeichen
enthalten waren.
Kein Kurzsprung möglich
Tritt bei Verwendung des Sprungbefehls „jmp“ mit dem Zusatz 'short'
oder bei Verwendung von bedingten Sprungbefehlen wie 'jnc' oder 'jz' auf.
Die Sprungadresse der Marke liegt nicht in einer kurzen Entfernung von 128 Bytes.
Ein Kurzsprung ist daher nicht möglich. Daher kann nur der Befehl 'jmp' verwendet werden.
Keine Segmentüberschreibung erlaubt
Bei Sprungbefehlen ist keine Segmentüberschreibung und damit kein
Sprung des Typs "far" erlaubt. Ebenfalls ist keine Segmentüberschreibung bei
Operanden erlaubt, die ein Register oder eine Konstante darstellen.
Kein Speicher-zu-Speicher-Transport möglich
Tritt auf, wenn bei einem Befehl als Ziel und als Quelle ein
Speicherplatz im Arbeitsspeicher angegeben ist. Es gibt bei diesem Prozessor jedoch
keinen Befehl, der einen direkten Speicher-zu-Speicher-Transport erlaubt.
Keine unmittelbare Adressierung möglich
Tritt auf, wenn als Zieloperand eine Zahl oder Konstante angegeben wird.
Eine Zahl oder Konstante ist jedoch kein Speicherplatz. Soll es sich um eine Adresse handeln,
ist die Zahl oder Konstante in eckige Klammern zu setzen oder durch eine Segmentüberschreibung
zu kennzeichenen.
Kein unmittelbar adressierter Sprung
Tritt bei der Verwendung von Sprungbefehlen mit direkter Adressenangabe auf.
Der Sprung kann nur zur einer Marke erfolgen, da hier der Assembler die Existenz prüfen kann.
Konstante nicht erlaubt
Triit auf, wenn nach der Pseudo-Anweisung 'offset' eine Zahl oder
Konstante angegeben wurde. Es muss jedoch eine Marke oder Variable angegeben werden.
Konstantenüberlauf
Es können keine weiteren Konstanten deklariert werden, da bereits
zu viele Konstanten deklariert worden sind.
Kurzsprung nur zu einer Marke
Tritt bei der Verwendung von Sprungbefehlen mit direkter Adressenangabe auf.
Der Sprung kann nur zur einer Marke erfolgen, da hier der Assembler die Existenz prüfen kann.
Länge muss Doppelwort bleiben
Für die Befehle lds und les ist beim Operanden keine Typüberschreibung der
Form byte ptr oder word ptr erlaubt.
Marke oder Befehl ist fehlerhaft
Es handelt sich um keinen Befehl aus dem Befehlssatz des Prozessors.
Es kann sich ebenfalls um keinen Namen für eine Konstante, Variable oder Marke handeln.
Solche Namen müssen mit einem Buchstaben beginnen und dürfen nicht mehr als 8 Zeichen enthalten.
Ein Markenname wird durch einen Doppelpunkt am Ende deklariert.
Markenüberlauf
Es können keine weiteren Marken deklariert werden, da bereits zu
viele Marken deklariert worden sind.
(Name)-Befehl ist nicht verfügbar
Hier handelt es sich zwar um einen Befehl des 8086-Befehlssatztes,
jedoch ist dieser Befehl in der jetzigen Version nicht verfügbar.
(Name) enthält unerlaubte Zeichenfolge
Ein Marken- oder Variablenname darf nur Groß- oder Kleinbuchstaben
oder Ziffern enthalten. Die Ziffern müssen dabei am Ende des Namens stehen.
(Name) ist bereits belegt
Es existiert bereits eine Konstante, Marke oder Variable unter
diesem Namen.
(Name) ist reservierter Befehl / reserviertes Wort
Tritt auf, wenn als Operand eines Befehls erneut ein Befehl oder ein
Pseudobefehl eingegeben wurde. Statt dessen muss ein Register- oder Speicheroperand
angegeben werden.
Name ist zu lang
Der Name einer Konstanten, einer Marke
oder einer Variablen darf nicht mehr als 8 Zeichen haben und muss mit einem Buchstaben
beginnen. Die Marke wird durch einen zusätzlichen Doppelpunkt gekennzeichnet.
Offset-Präfix erforderlich
Statt einer Konstanten wurde ein Marke angegeben. Dies tritt z.B. auf,
wenn bei der indirekten Adressierung ein Register und eine Marke angegeben werden. Hier muss
die Marke mit dem Vorsatz 'offset' versehen werden. Dann ist es dem Assembler möglich, die
Adresse der Marke zu verwenden.
Operand fehlt
Bei der Deklaration der Konstanten fehlt nach der equ-Anweisung der Operand.
Hier muss nun eine Dezimalzahl (5, -3, 44000), eine Hexadezimalzahl (5h, 9AFh, 0ABCDh),
eine Dualzahl(0011b, 111100001111b) oder eine Zeichen ('2','D','+') angegeben werden.
Auch die Angabe einer bereits deklarierten Konstanten ist möglich.
Operand für Konstante fehlerhaft
Bei der Deklaration der Konstanten muss eine Dezimalzahl (5; -3; 44000),
eine Hexadezimalzahl (5h; 9AFh; 0ABCDh), eine Dualzahl(0011b; 111100001111b) oder ein
Zeichen ('2';'D';'+') angegeben werden. Auch die Angabe einer bereits deklarierten
Konstanten ist möglich.
Operand überschreitet Byte-Größe
Bei der Deklaration einer Variablen vom Typ Datenbyte durch 'db'
liegt der Wert des oder der Operanden nicht im Bereich [-128;255].
Programm-Code hat zu hohe Adresse
PC Inside reserviert einen bestimmten überschaubaren Bereich des
Arbeitsspeichers als Codesegment, welcher 4096=1000h Speicherplätz umfasst. Hier werden
bei Programmbeginn die Befehlsbytes des Programmcodes und diejenigen Variablendaten abgelegt,
die durch die code-[segment-]Anweisung für das Codesegment bestimmt wurden. Wird dieser Bereich
überschritten, erfolgt eine Fehlermeldung.
Erfolgte für die Variablen weder die Anweisung code [segment] noch data [segment],
wird das Codesegment gewählt.
Programmtext muss ins Codesegment
Tritt auf, wenn vorher durch das reservierte Wort data [segment]
im Programmtext dem Assembler mitgeteilt wurde, dass der Programmtext zum Datensegment-Teil
gehören soll. In diesem Teil sind jedoch nur Variablendeklarationen erlaubt. Es dürfen
keine Marken mit Doppelpunkt am Ende oder Befehle in den Datensegment-Teil geschrieben werden.
Entweder schreibt man die Befehle vor die data [segment] Anweisung oder man macht mit einer
code [segment] Anweisung deutlich, dass die folgenden Befehle und Variablen für das Codesegment
vorgesehen sind.
Variablen im Codesegment werden vor dem Überschreiben durch PC Inside geschützt. Nur Variablen
im Datensegment können verändert werden.
Sprung-Befehl erforderlich
Tritt auf, wenn nach der Pseudoanweisung 'short' kein Sprungbefehl steht.
Es muss hier jedoch ein Sprungbefehl angegeben werden.
Störender Zusatz bei einem Namen
Hinter einem Konstanten-, Marken- oder Variablennamen steht noch ein
störender Zusatz.
Störender Zusatz bei einem Registeroperand
Tritt auf, wenn vor einen Registeroperand eine Typüberschreibung
gesetzt wurde. Ein Registeroperand, z.B. ax, kann jedoch durch eine solche Typüberschreibung,
hier z.B. byte ptr, nicht beeinflusst werden. Die Überschreibung ist daher sinnlos.
Störendes Komma
Vor oder hinter dem Komma fehlt ein Operand.
Ungültiger DB-Operand
Bei der Deklaration einer Variablen vom Typ Datenbyte durch 'db' besitzt
die angegebene Konstante eine falsche Darstellung. Gültig ist eine Dezimalzahl,
eine Hexadezimalzahl (0B3h), eine Dualzahl (1100011B), eine bereits definierte Konstante,
ein Zeichen ('G') oder eine Zeichenkette. Mehrere Operanden können duch Kommas
voneinander getrennt werden.
Ungültiger DW-Operand
Bei der Deklaration einer Variablen vom Typ Datenwort durch 'dw' besitzt
die angegebene Konstante eine falsche Darstellung. Gültig ist eine Dezimalzahl,
eine Hexadezimalzahl (0BC3Fh), eine Dualzahl (1111000111B) oder eine bereits definierte Konstante.
Ungültiger Operand
Es wurde ein Befehl verwendet, bei dem der angegebene Operand nicht
erlaubt ist. Die erlaubten Operanden sind in der Hilfe-Datei ASSBEF.HLF wiedergegeben.
Variablen-Daten haben zu hohe Adressen
PC Inside reserviert einen bestimmten überschaubaren Bereich des
Arbeitsspeichers als Datensegment, welcher 4096=1000h Speicherplätz umfasst. Hier werden
bei Programmbeginn diejenigen Variablendaten abgelegt, die durch die data-[segment-] Anweisung
für das Datensegment bestimmt wurden. Wird dieser Bereich überschritten, erfolgt eine
Fehlermeldung.
Variablenüberlauf
Es können keine weiteren Variablen deklariert werden, da bereits
zu viele Variablen deklariert worden sind.
Wert von (Name) unbekannt
Unter diesem Namen ist keine Konstante, keine Marke und keine
Variable deklariert worden. Wahrscheinlich handelt es sich um einen Schreibfehler.
Diese Meldung erscheint erst beim 2. Durchlauf des Assemblers.
Wort-Operand wird verlangt
Tritt auf, wenn bei den Befehlen 'push' und 'pop' ein Operand der Länge
Byte vom Assembler erkannt wurde. Dies kann auf die Angabe eines 8-Bit-Registers oder auf die
Typüberschreibung 'byte ptr' zurückzuführen sein. Es muss daher das 8-Bit-Register durch ein
16-Bit-Register ersetzt werden oder die Typüberschreibung rückgängig gemacht werden.
Zeichenkette überschreitet Zeilenende
Bei der Deklaration einer Variablen vom Typ Datenbyte durch 'db' besitzt
die angegebene Zeichenkette keine Begrenzung am Ende. Der Text kann entweder in Anführungsstrichen
oder in Hochkommas eingefasst werden.
Zu viele Operanden
Für den verwendeten Befehl sind zu viele Operanden angegeben.
Die Anzahl und die Art der der Operanden kann in der Hilfe-Datei ASSBEF.HLF nachgelesen werden.
Zu wenige Operanden
Für den verwendeten Befehl sind zu wenige Operanden angegeben. Die Anzahl
und die Art der der Operanden kann in der Hilfe-Datei ASSBEF.HLF nachgelesen werden.
Zwei Basisregister
Bei der indirekten Adressierung wurden bei einundderselben Adresse
zwei Basisregister verwendet, z.B. bx und bp oder auch zweimal bx. Dies ist jedoch nicht
erlaubt. Es darf höchstens ein Basisregister und höchstens ein Indexregister verwendet werden.
Zwei Indexregister
Bei der indirekten Adressierung wurden bei einundderselben Adresse
zwei Indexregister verwendet, z.B. si und di oder auch zweimal si. Dies ist jedoch
nicht erlaubt. Es darf höchstens ein Indexregister und höchstens ein Basisregister
verwendet werden.
8-Bit-Wert verlangt
Bei der Verwendung der Befehle "in" und "out" musst der Wert des
Operanden im Bereich [0;255] liegen.
----------------------------------------------------------------------
Die Fehlermeldungen bei der Ausführung
Fehlerhafte Befehlszeilen werden nicht ausgeführt. Statt dessen wird eine Fehlermeldung
ausgegeben.
Treten beim Ausführen des Programms solche Fehlermeldungen auf, wird der Ablauf wird
nicht abgebrochen. Es wird diejenige Zeile geladen, welche der fehlerhaften Befehlszeile
nachfolgt.
CS-Register kann nicht geändert werden
Tritt auf, wenn durch einen Befehl das Codesegment-Register
verändert werden soll. Dies ist z.Z. nicht möglich.
Ende der Programmdatei
Hier handelt es sich nicht um eine Fehlermeldung, sondern lediglich die Mitteilung,
dass die letzte Maschinenprogrammzeile abgearbeitet wurde und keine weitere Zeile vorhanden ist.
Der Ausführungsmodus kann nun nur durch die Taste wieder verlassen werden.
Gewünschte IP-Adresse nicht gefunden
Die Meldung bedeutet, dass keine Maschinenprogramm-Zeile gefunden
werden konnte, die als Befehlsadresse die gewünschte IP-Adresse enthält. IP steht hier
für instruction pointer oder Befehlszeiger. Die Meldung tritt auf, wenn vor der
Ausführung eines Maschinenprogramms der Befehlszeiger (IP) bereits mit Hilfe des
Mikroprozessorfensters gesetzt wurde und die Register vor dem Programmbeginn nicht
gelöscht werden sollen. Hier muss in das IP-Register vor Programmbegin eine gültige
Befehlsadresse gegeben werden.
Keine Intersegment-Aufrufe erlaubt
Tritt auf, wenn durch einen Befehl ein Intersegmentaufruf ausgelöst
werden soll. Dies ist z.Z. nicht möglich.
Letzter Befehl war nicht durchführbar
Tritt auf, wenn Befehlsadresse oder Befehlsbytes nicht in Ordnung
waren. Insbesondere werden keine Zeilen ausgeführt, in denen sich Variablen und ihre
Adressen befinden, da es sich um keine sinnvollen Befehle handelt.
Programm-Code hat zu hohe Adresse
PC Inside rreserviert einen bestimmten überschaubaren Bereich des
Arbeitsspeichers als Codesegment, welcher 4096=1000h Speicherplätze umfasst. Hier werden
bei Programmbeginn die Befehlsbytes des Programmcodes und diejenigen Variablendaten abgelegt,
die durch die code-[segment-]Anweisung für das Codesegment bestimmt wurden. Wird dieser
Bereich überschritten, erfolgt eine Fehlermeldung.
Existiert für die Variablen weder die Anweisung code [segment] noch data [segment],
wird das Codesegment gewählt.
Sprungadresse wurde nicht gefunden
Tritt bei Sprungbefehlen oder Unterprogrammaufrufen auf.
Es kann keine Zeile des Maschinenprogramms gefunden werden, an deren Anfang die geforderte
Sprung-adresse steht. Dieser Fehler wird besonders häufig beim indirekten Sprung auftreten,
da in einem solchen Fall die Sprungadresse einem Register oder Speicherplatz entnommen
werden muss und vorher verändert werden konnte.
SS-Register kann nicht geändert werden
Tritt auf, wenn durch einen Befehl das Stapelsegment-Register
verändert werden soll. Dies ist z.Z. nicht möglich.
Stapelgrenze erreicht
PC Inside reserviert einen bestimmten überschaubaren Bereich des
Arbeitsspeichers als Stapelsegment, welcher 4096=1000h Speicherplätz umfasst. Bei Programmbeginn
wird der Stapelzeiger auf 256=100h gestzt. Wird durch einen Stapelbefehl dieser Bereich
überschritten, erfolgt eine Fehlermeldung. Der Befehl wird nicht ausgeführt.
Unerlaubter Adressbereich
PC Inside reserviert einen bestimmten überschaubaren Bereich des
Arbeitsspeichers als Datensegment, welcher 4096=1000h Speicherplätze umfasst. Sollen durch
einen Befehl Speicherplätze außerhalb dieses Bereichs verändert werden, erfolgt eine Fehlermeldung.
Variablen-Daten haben zu hohe Adressen
PC Inside reserviert einen bestimmten überschaubaren Bereich des
Arbeitsspeichers als Datensegment, welcher 4096=1000h Speicherplätze umfasst. Hier werden
bei Programmbeginn diejenigen Variablendaten abgelegt, die durch die data-[segment-]
Anweisung für das Datensegment bestimmt wurden. Wird dieser Bereich überschritten,
erfolgt eine Fehlermeldung.
----------------------------------------------------------------------
Editorbefehle
Cursorbefehle
Zeichen nach links | Cursor links |
Zeichen nach rechts | Cursor rechts |
Wort nach links | Strg Cursor links |
Wort nach rechts | Strg Cursor rechts |
Zeile nach oben | Cursor hoch |
Zeile nach unten | Cursor tief |
Seite nach oben | Bild hoch |
Seite nach unten | Bild tief |
Zeilenanfang | Pos1 |
Zeilenende | Ende |
Textanfang | Strg Pos1 |
Textende | Strg Ende |
Einfüge- und Löschbefehle
Zeichen löschen | Entf |
Zeichen links löschen | Rückwärtstaste |
Einfügemodus ein/aus | Einfg |
Blockbefehle
Block markieren | Strg A |
Block ausschneiden | Strg X |
Block kopieren | Strg C |
Block einfügen | Strg V |
----------------------------------------------------------------------
Aufgaben
Aufgaben 1: Maschinenorientierte Programmierung, allgemein
Aufgaben 2: Adressierung von Daten
Aufgaben 3: Stapel und Unterprogamme