6. Funktionseinheiten eines Computers / Mikrocomputers
6. Funktionseinheiten eines Computers / Mikrocomputers
6. Funktionseinheiten eines Computers / Mikrocomputers
Erfolgreiche ePaper selbst erstellen
Machen Sie aus Ihren PDF Publikationen ein blätterbares Flipbook mit unserer einzigartigen Google optimierten e-Paper Software.
Rechnergrundlagen Teil 2 - 1 - Prof. Dipl.-Ing. Komar<br />
<strong>6.</strong> <strong>Funktionseinheiten</strong> <strong>eines</strong> <strong>Computers</strong> / <strong>Mikrocomputers</strong><br />
CPU Zentraleinheit Prozessor<br />
Rechenwerk und Steuerwerk<br />
Adreß-Bus Daten-Bus Steuer-Bus<br />
Speicher Arbeitsspeicher<br />
Hauptspeicher<br />
für Programme u. Daten<br />
Schnittstelle<br />
Ein- / Ausgabe Peripherie<br />
1. Prozessor, ( CPU , Zentraleinheit, Mikroprozessor )<br />
wichtigste Komponente , seine Eigenschaften bestimmen wesentlich die Leistungsfähigkeit des gesamten<br />
<strong>Computers</strong>, ( CPU auf einem Chip -> Mikroprozessor -> Mikrocomputer; CPU = central processing unit )<br />
2. Speicher , bestehend aus Festwertspeicher ( Nur-Lese-Speicher ROM ) und flüchtigem Schreib/Lese-<br />
Speicher ( RAM ) enthält die Programm-Befehle und die zu verarbeitenden Daten.<br />
3. Periphere Bausteine ( Interface, Schnittstellen) verbinden den Mikrocomputer mit der Außenwelt, z.B. mit<br />
Drucker, Tastatur, Bildschirm, Floppylaufwerk, Festplatte oder einem Meßgerät.<br />
Tastatur, Maus und Bildschirm bilden die Schnittstelle für die Mensch-Maschine-Kommunikation<br />
Aufgaben der Interfacebausteine sind<br />
- zeitliche Abstimmung, da Peripherie deutlich langsamer<br />
- Pegelanpassung (unterschiedliche Spannungen)<br />
- Daten puffern ( zwischenspeichern )<br />
4. Bus-System - Verbindungsleitungen (Adreß-, Daten- und Steuerbus) dienen der bidirektionalen Übertragung<br />
von Informationen zwischen Prozessor / Speicher und Prozessor / periphere Bausteine.<br />
5. Software (Programme) beinhaltet die Anweisungen ( Befehle ) an den Prozessor und legt damit die Aufgabe<br />
des <strong>Computers</strong> fest.<br />
Die Anpassung des Mikrocomputer an die jeweilige Aufgabe erfolgt durch<br />
- unterschiedliche Speicherkonfiguration (ROM / RAM )<br />
- verschiedene Schnittstellenbausteine<br />
- anwendungsspezielle Software.
Rechnergrundlagen Teil 2 - 2 - Prof. Dipl.-Ing. Komar<br />
<strong>6.</strong>1 Aufbau <strong>eines</strong> Mikroprozessors<br />
Der Mikroprozessor enthält die logischen Funktionen <strong>eines</strong> Prozessors auf einem einzigen hochintegrierten<br />
Halbleiterbaustein ( integrated circuit IC in MOS-Technologie).<br />
Der Prozessor ist ein Automat ( synchrones Schaltwerk ) der eine festgelegte Anzahl von Tätigkeiten ( Menge<br />
der Maschinenbefehle, Befehlssatz ) ausführen kann und damit den gesamten Computer steuert und arithme -<br />
tische und logische Aufgaben löst. Er ist also für die Abarbeitung der Maschinenbefehle zuständig, die in<br />
binärcodierter Form im Arbeitsspeicher vorliegen und in ihrer Gesamtheit ein ablauffähiges Programm bilden.<br />
Ein von einem Quarzgenerator extern erzeugter Takt sorgt innerhalb der CPU für den synchronen Ablauf der<br />
Arbeitsvorgänge.<br />
Ein Resetimpuls (auch beim Einschalten) versetzt den Prozessor in einen definierten Grundzustand, aus dem<br />
heraus er sofort mit der Befehlsabarbeitung an einer konstanten, festgelegten Adresse im Arbeitsspeicher<br />
beginnt.<br />
Steuerbus Adreßbus (16, 20, 24, 32 Bit ) Datenbus ( 8, 16, 32, 64 Bit )<br />
Steuersignale Adressen Befehle Daten<br />
interne<br />
Steuerwerk Steuersignale Rechenwerk<br />
Das Rechenwerk besteht aus Registern ( CPU interner schneller Speicher) und der Arithmetisch-Logischen-<br />
Einheit (ALU), einer Rechenschaltung für die Verarbeitung von Daten.<br />
Das Steuerwerk (Leitwerk) besteht aus einer Ablaufsteuerung, die den binären Code der Programmbefehle in<br />
Steuersignale umsetzt. Es holt sich das Programm Befehl für Befehl aus dem Arbeitsspeicher und führt die<br />
Befehle aus, indem es die Operanden aus dem Arbeitsspeicher in das Rechenwerk lädt, dort die erforderlichen<br />
Operationen anstößt und eventuell anschließend das Ergebnis in den Arbeitsspeicher schreibt.<br />
Die Register des Steuerwerks enthalten Adressen und das zentrale Register des Steuerwerks ist der Befehlszähler<br />
( Program Counter PC oder auch Instruction Pointer IP ) mit der Adresse des nächsten Befehls.<br />
Die Breite der Register (8, 16 oder 32 Bit ) von Rechen- und Steuerwerk entspricht meist der externen Datenbus-<br />
breite und ist zusammen mit der Taktfrequenz ein überschlägiges Kriterium für die Leistungsfähigkeit des<br />
Mikroprozessors.<br />
Bus -System <strong>eines</strong> <strong>Mikrocomputers</strong><br />
Register Register<br />
Ablaufsteuerung A L U<br />
Leitungssystem für die parallele, gleichzeitige Übertragung von Signalen zwischen den Komponenten <strong>eines</strong><br />
<strong>Mikrocomputers</strong> (auch innerhalb des Mikroprozessors)<br />
Datenbus - Transport von Befehlen und Daten zwischen Prozessor und Bausteinen, bidirektional<br />
Mikroprozessoren werden nach der Breite des Datenbusses eingeteilt ( 8, 16, 32 oder 64 Bit )<br />
Adreßbus - Mikroprozessor legt die Adresse <strong>eines</strong> Speicherwortes (Byte ) oder die Adresse des Registers<br />
<strong>eines</strong> Peripheriebaust<strong>eines</strong> auf den unidirektionalen Adreßbus (16, 20, 24 oder 32 Bit )<br />
Steuerbus - Sammelschiene für unterschiedlichste Steuersignale zur zeitlichen und logischen Koordination<br />
der Abläufe ( z.B. Schreiben / Lesen im Speicher ) durch den Mikroprozessor.
Rechnergrundlagen Teil 2 - 3 - Prof. Dipl.-Ing. Komar<br />
<strong>6.</strong>2 Speicherbausteine<br />
hoch<br />
Kosten/Bit<br />
niedrig<br />
Worte Register ( parallele Flipflops )<br />
k-Byte Cache ( SRAM)<br />
M -Byte Haupt - bzw Arbeitsspeicher (EPROM u. DRAM)<br />
Geschwindig - M -Byte Diskette / Floppy<br />
keit<br />
G-Byte Festplatte u. Magnetband<br />
G-Byte Optische Speicher ( CD, DVD )<br />
Speicherhierachie in <strong>Computers</strong>ystemen<br />
Die in <strong>Computers</strong>ystemen verwendeten Halbleiterspeicher sind intern als Matrixspeicher organisiert.<br />
Durch das Anlegen einer Adresse kann in einem wahlfreien Zugriff ( random access ) auf das<br />
Speicherelement (meist 1 Bit oder 1 Byte ) zugegriffen werden, d.h. entweder der Inhalt ausgelesen oder ein<br />
neuer eingeschrieben werden.<br />
Die Zugriffszeit (access time ) kennzeichnet die Zeitspanne, die zwischen dem Anlegen der Adresse und der<br />
Verfügbarkeit der gültigen Daten an den Ausgängen vergeht.<br />
Die Zykluszeit ist die Zeitspanne vom Beginn <strong>eines</strong> Speichervorganges bis zu dem Zeitpunkt, an dem ein neuer<br />
Speichervorgang beginnen kann und setzt sich zusammen aus der Zugriffszeit und möglicherweise einer<br />
Regenerationszeit für das Wiederherstellen der beim Lesen zerstörten Information (DRAM).<br />
Nach der Beständigkeit der Information bei Spannungsausfall unterscheidet man flüchtige Schreib/Lese-<br />
Speicher ( RAM ) und nichtflüchtige Festwertspeicher ( Nur-Lese-Speicher read only memory ROM )<br />
ROM - Festwertspeicher (Read only memory), nichtflüchtig für Programme und konstante Daten<br />
ROM - vom Hersteller maskenprogrammiert, nur wirtschaftlich bei großen Stückzahlen<br />
PROM - vom Anwender mit Programmiergerät einmal programmierbar<br />
EPROM - (erasable PROM) mit UV-Licht löschbar und vom Anwender neu programmierbar<br />
EEPROM / EAROM - electrically alterable ROM, kann in Schaltung umprogrammiert werden<br />
Flash-PROM - technisch u. preislich zwischen EPROM und EEPROM angesiedelt,<br />
ganzer Chip bzw Teile (Page, Block) lassen sich in Sekundenbruchteilen löschen und neu program –<br />
mieren, wobei die dafür nötige Spannung von 12V auf dem Chip erzeugt wird und dieser dabei in der<br />
Schaltung verbleiben kann. Kapazität byteorganisiert bis 20 Mbit, Lesespannung 5V und Lesezugriffs -<br />
zeit < 100 nsec, Siliziumdisk, PCMCIA-Memory-Card, BIOS-Festwertspeicher<br />
RAM - Schreib-Lesespeicher für variable Information, flüchtig, ohne Spannung Datenverlust<br />
SRAM - statisches RAM, Speicherelement sind Flipflops und deswegen Datenhaltung solange Spannung<br />
anliegt, wortorganisiert (meist 1 Byte), störsicher und zuverlässig , problemloser Anschluß, kurze<br />
Zugriffszeit von wenigen nsec ( Zykluszeit ), um Faktor 4 niedrigere Speicherdichte als DRAM, teuer<br />
DRAM - dynamisches RAM, da Speicherelement ein Kondensator ,benötigt es alle 2 - 100 ms einen Refresh,<br />
viermal höhere Integrationsdichte und dadurch kostengünstiger als SRAM, überwiegend bitorganisiert,<br />
meistens Multiplexen der beiden Adresshälften, Zugriffszeiten < 100 nsec, störanfällig, billig<br />
dynamische Speicherbausteine mit integrierter Refreshlogik erhältlich ( pseudostatische DRAM )<br />
Mit den Begriffen FPM (Fast Page Modus), EDO (extended data out ) oder SDRAM (synchrones<br />
dynamisches RAM ) sind DRAM-Bausteine gemeint, bei denen durch besondere Betriebsmodi die<br />
Zugriffszeiten abgekürzt werden.
Rechnergrundlagen Teil 2 - 4 - Prof. Dipl.-Ing. Komar<br />
<strong>6.</strong>3 Software<br />
Ein Programm für einen Prozessor besteht aus einer sequentiellen Folge von binären Bitmustern,<br />
den Maschinenbefehlen ( Makrobefehle ). Ein Maschinenbefehl kann z.B. im PC 1 bis 9 Byte lang sein.<br />
Bei der Abarbeitung des Programms werden diese Befehle sukzessive im Maschinencode aus dem Arbeits-<br />
speicher über den Datenbus in den Prozessor geladen.<br />
Der Operationscode (opcode) des Befehls, der die gewünschte Operation und die dazu benötigten Prozessor-<br />
Komponenten spezifiziert, wird in die Befehlsregister des Steuerwerks geladen.<br />
Ein Programm in Maschinensprache ist also eine Folge von binär codierten Befehlen (Objectcode).<br />
Diese Maschinenbefehle sind als eine Folge von Nullen und Einsen (Bitmuster) sehr unübersichtlich und<br />
werden deswegen grundsätzlich in hexadezimaler Schreibweise abgekürzt und übersichtlicher dargestellt.<br />
Für das Programmieren sind diese hexadezimalen Abkürzungen immer noch zu unhandlich und von daher<br />
erfolgt der Schritt zur Verwendung einer Assemblersprache mit mnemonischen Abkürzungen für die Befehle.<br />
Beispiel: MOV A,#13 Assemblerbefehl ( 2 Byte ) Lade Akkumulator mit Konstante 1310<br />
74 0D Maschinenbefehl hexadezimal ( Opcode ->74h, Operand-> 13 )<br />
01110100 00001101 Maschinenbefehl binär<br />
Der Begriff Assembler wird zum einen für die Sprache (Vereinbarung der mnemonischen Abkürzungen) als<br />
auch für das Übersetzungsprogramm (das aus den mnemonischen Abkürzungen die Maschinenbefehle erzeugt)<br />
verwendet. Programmierung in Assembler ist bei Mikrocomputern noch recht häufig, da der aus Assembler-<br />
programmen erzeugte Maschinencode gegenüber demjenigen aus Hochsprachen erzeugten schneller und<br />
speicher- effizienter ist.<br />
Andererseits ist für Assemblerprogrammierung ein hoher Einarbeitungsaufwand nötig und der Assemblercode<br />
ist prozessorabhängig (nicht kompatibel).<br />
Die Compiler ( Übersetzerprogramme ) für höhere Programmiersprachen erzeugen zum einen direkt den<br />
Maschinencode für den jeweiligen Prozessor oder generieren in der jeweiligen Assemblersprache einen sogn.<br />
Zwischencode, der anschließend vom Assembler übersetzt wird.<br />
Im Mittel werden für die Realisierung <strong>eines</strong> Hochsprachen-Befehls ungefähr 10 – 20 Maschinenbefehle benötigt.<br />
Bei Generierung <strong>eines</strong> Assembler-Zwischencodes, kann falls gewünscht, dieser von Hand optimiert werden.<br />
Ein Betriebssystem ordnet sich zwischen Hardware und Anwendersoftware ein und man versteht darunter<br />
nach DIN: " diejenigen Programme <strong>eines</strong> digitalen Rechensystems, die zusammen mit den Eigenschaften der<br />
Rechenanlage die Basis der möglichen Betriebsarten des digitalen Rechensystems bilden und insbesondere die<br />
Abwicklung von Programmen steuern und überwachen."<br />
Infolgedessen umfasst das Betriebssystem nur die Basissoftware, die einem Benutzer der Anlage erst ermöglicht<br />
seine eigene (Anwendungs-)Software mehr oder weniger komfortabel ablaufen zu lassen.<br />
Betriebssysteme bestehen im wesentlichen aus Hilfsprogrammen für Dateiverwaltung, Editieren, Übersetzen,<br />
Linken/Laden und Testen (Debuggen). Einfachste Betriebssysteme (ohne Massenspeicher) werden als Monitor<br />
bezeichnet (im MVUS 80535 -> MONITOR-51, auch DEBUG im PC kann als solches betrachtet werden )<br />
Bekannteste Betriebssysteme für Personalcomputer und Arbeitsplatzrechner sind<br />
CP/M (8 Bit)<br />
DOS (16 Bit)<br />
OS-2 (32 Bit)<br />
UNIX (32 Bit)<br />
WINDOWS (32 Bit)<br />
LINUX (32 Bit)<br />
Betriebssysteme lassen sich grob in Singletasking- und Multitasking-Systeme unterteilen, wobei letztere die<br />
(quasi-) "gleichzeitige" Ausführung mehrerer Programme (Tasks, Prozesse) unterstützen.<br />
Beim kooperativen Multitasking unterbricht sich eine Anwendung selbst, um einer anderen vorübergehend<br />
den Vortritt zu lassen ( WINDOWS 3.x ) und beim preemtiven Multitasking wird jedem Programm ( Task )<br />
vom Scheduler eine Zeitscheibe zugeteilt (WINDOWS 98, UNIX, LINUX ).<br />
Bei Echtzeitbetriebssystemen wird für den Taskwechsel eine bestimmte Zeitdauer garantiert, damit zeit -<br />
kritische Aufgaben ausreichen schnell bearbeitet werden können.<br />
Verbreitete Echtzeitbetriebssysteme (Multitasking): RMX 86 und OS-9
Rechnergrundlagen Teil 2 - 5 - Prof. Dipl.-Ing. Komar<br />
<strong>6.</strong>4 Bauformen und Einsatz von Mikrocomputern<br />
Mikrocontroller<br />
Der Single-Chip-Mikrocomputer besteht aus einem einzigen Baustein, d.h. er ist ein vollständiger Rechner auf<br />
einem Chip. Neben dem Prozessorkern (meist aus einer erfolgreichen Mikroprozessorfamilie ) enthalten diese<br />
Bausteine eine aufgaben- bzw kundenspezifische Speicher- und Peripheriebestückung. Nur die Anschlüsse der<br />
Peripherie-Komponenten werden an den Stiften ( Pins ) herausgeführt.<br />
Sie werden für einfache Steuerungen ( controller ) im Masseneinsatz verwendet und diese Embedded Systems -<br />
Anwendungen sind sicherlich die am weitesten verbreitete Mikrocomputerform, allerdings meist unsichtbar für<br />
den Geräteanwender.<br />
Beispiel : Intel 8051-Familie mit 80515 / 80535 im MVUS-System der FH-Dieburg<br />
Ein-Platinen-Computer<br />
Der Single-Board-Mikrocomputer besteht aus einer Karte mit einer gedruckten Schaltung.<br />
Prozessor, Speicherbausteine und Peripheriebausteine werden durch Leitungen miteinander verbunden. Mit<br />
Erweiterungssteckern können Zusatzkarten (z.B. Speichererweiterung, Grafik) angeschlossen werden.<br />
Beispiel : Motherboard des PC<br />
Einsatzgebiete: Personalcomputer, Hobbycomputer, Arbeitsp1atzrechner<br />
Programmierung in Assembler und höheren Programmiersprachen<br />
Baugruppen-System<br />
Das Bauplattensystem besteht aus einzelnen Karten im Europa oder Doppeleuropaformat für ein Einschub-<br />
Gehäuse (Rack) mit einer standardisierten Bus-Rückwand.<br />
Es gibt Prozessorkarten, Speicherkarten und Peripheriekarten. Der Rechner wird nach den Erfordernissen der<br />
Anwendung zusammengesteckt und läßt sich daher leicht ändern und erweitern.<br />
Die verschiedensten Hersteller können Karten für das jeweilige genormte Bus- System anbieten.<br />
Systeme : ECB ( 8 Bit Z80 / 8080 ), VME-Bus ( Motorola 68 000 ), Multibus ( Intel 80x86 )<br />
Einsatzgebiete: Steuerung von Maschinen und Anlagen (Prozeßrechner), insbesondere in der industriellen<br />
Automatisierungs- und Robotertechnik.<br />
Digitale Signalprozessoren DSP<br />
sind speziell für die schnelle digitale Verarbeitung von analogen Signalen (z.B. Audio, Video ) ausgelegt.<br />
Die Synthese und Analyse von analogen Signalen ist sehr rechenintensiv und benötigt spezielle Reihen-<br />
entwicklungen. Hierzu ist die Multiplikation und eine anschließende Addition zu einem bereits vorhandenen<br />
Wert nötig ( DFT bzw FFT )<br />
DSPs haben ein Rechenwerk, das auf solche Berechnungen spezialisiert ist. Auf den Bausteinen befinden sich<br />
mehrere Analog/Digital- ( ADC ) und Digital/Analog-Wandler DAC.<br />
Außerdem besitzen sie meist getrennte Programm- und Datenspeicher mit jeweils eigenen Bussystemen und<br />
vermeiden mit dieser Harvard-Architektur den von-Neumannschen Flaschenhals.<br />
Anwendung: Sprach- und Bildverarbeitung, Regelungstechnik, Telekommunikation.<br />
Co-Prozessoren<br />
erfüllen im Computer spezielle Aufgaben und entlasten dadurch die CPU.<br />
Arithmetik-Co-Prozessoren übernehmen die Gleitkommaberechnungen, Graphik-Co-Prozessoren führen<br />
komplexe graphische Berechnungen durch.<br />
Daneben übernehmen Spezial -Mikrocontroller die Kommunikation und Verwaltung von Externspeicher (Hard<br />
Disk Controller, Floppy Disk Controller ) , Bildschirm , serielle Schnittstelle (USART) und Netzwerken.<br />
Multimediaprozessoren beschleunigen die Bildverarbeitung.<br />
Mit zunehmendem Integrationsgrad werden viele dieser Hilfsfunktionen in den Mikroprozessor integriert.
Rechnergrundlagen Teil 2 - 6 - Prof. Dipl.-Ing. Komar<br />
<strong>6.</strong>5 Elektronische und digitale Grundlagen<br />
Digitale Schaltungen werden mittels logischer Funktionen aufgebaut.<br />
Die drei logischen Grundfunktionen sind die UND-, ODER- und NICHT-Verknüpfung.<br />
Jede digitale Logikschaltung (z.B. Pentium III ) kann nun entweder nur mit UND- und NICHT-, oder ODER-<br />
und NICHT-Verknüpfungen beschrieben werden.<br />
Diese logischen Funktionen werden durch elektronische Schalter ( Transistoren ) realisiert, die mit einer<br />
Versorgungsspannung von 5 V ( 3,3 V ) betrieben werden.<br />
Die Hersteller von derartigen integrierten Logikfunktionen garantieren bei Einhaltung der Grenzwerte<br />
für Temperatur, Versorgungsspannung und Ausgangsbelastung (fan out) für ihre Bausteine die Einhaltung der<br />
sogn. Logikpegel ( TTL-Pegel, TTL = Transistor-Transistor-Logik ) von 0 – 0.8 V für Low und 2 – 5 V<br />
für High.<br />
Die Ausgangsschaltungen derartiger Logikfunktionen werden im folgenden mit Schaltern symbolisiert.<br />
+ 5V + 5V + 5V<br />
H = 1 L = 0 potentialfrei (hochohmig)<br />
0 V 0 V 0 V<br />
Ausgang High Ausgang Low Ausgang abgeschaltet ( tristate )<br />
Gegentakt-Ausgang Tristate -Ausgang für Bildung von Bussystemen benötigt<br />
Schaltnetze sind logische Funktionen, die binäre Eingangsworte in binäre Ausgangsworte umwandeln.<br />
Und zwar hängt bei diesen kombinatorischen Schaltungen, die Ausgabe nur von der momentan anliegenden<br />
Eingabe ab.<br />
Schaltwerke entstehen aus Schaltnetzen durch Rückkopplungen und weisen Speicherverhalten auf.<br />
Durch dieses Speicherverhalten ist der Ausgang auch von früheren Eingaben abhängig, das Schaltwerk hat<br />
also ein “Gedächtnis“, das in den sogn. Zuständen des Schaltwerkes realisiert ist (sequentielle Logik, finit<br />
state machine ).<br />
Um in den Rückkopplungszweigen der einzelnen Zustände gleiche Laufzeiten (Verzögerungszeiten ) zu<br />
erzielen, fügt man in diese Rückkopplungszweige taktgesteuerte Schalt/Speicherelemente ( Flipflops ) ein,<br />
die nur zu den definierten Taktzeitpunkten die anliegenden Signale übernehmen, bzw weiterleiten.<br />
Da durch den Takt in allen Rückkopplungszweigen synchrones Verhalten erzwungen wird, bezeichnet man<br />
getaktete Schaltwerke als synchrone Schaltwerke.<br />
Komplexe digitale Schaltungen wie z.B. Mikroprozessoren sind Automaten und lassen sich nur als getaktete<br />
synchrone Schaltwerke realisieren.<br />
Schaltwerk<br />
Eingänge Ausgänge<br />
Schaltnetz<br />
Verzögerung<br />
Speicher<br />
Automat<br />
Zustände<br />
Die ersten Mikroprozessoren in den 70iger und 80iger Jahren wurden alle als mikroprogrammiertes Steuer-<br />
werk entworfen und erhielten später die Bezeichnung CISC (Complex Instruction Set Computer ).
Rechnergrundlagen Teil 2 - 7 - Prof. Dipl.-Ing. Komar<br />
Man zielte darauf ab, immer mehr und komplexere Befehle auf der Maschinenbefehlsebene zur Verfügung<br />
zu stellen. Dabei wird das interne Schaltnetz dieser CISC-Prozessoren in Form <strong>eines</strong> Festwertspeichers<br />
(mikroprogrammiertes Steuerwerk ) realisiert.<br />
Jeder der Befehle ( Makrobefehl ) aus dem externen Arbeitsspeicher wird im Steuerwerk des CISC-Prozessor<br />
durch ein Mikroprogramm abgearbeitet. Dieses Mikroprogramm befindet sich im internen Festwertspeicher<br />
und steuert die Abarbeitung des Makrobefehles aus dem externen Programmspeicher.<br />
Das Mikroprogramm im internen Festwertspeicher wird als Firmware bezeichnet und in den 80iger<br />
Jahren gab es mikroprogrammierbare Mikroprozessoren, bei denen der Anwender durch Implementierung<br />
<strong>eines</strong> eigenen Mikroprogramms seinen eigenen Befehlssatz erzeugen konnte.<br />
Seit Beginn der 90iger Jahre hat sich die Architektur des RISC-Prozessors ( Reduced Instruction Set<br />
Computer ) durchgesetzt. Ansatz dabei war die Beschränkung auf wenige, einfache Befehle ( ungefähr 100 )<br />
und die optimale Implementierung dieser wenigen Befehle auf dem Prozessor.<br />
RISCs benötigen wegen ihrer einfachen Befehle keinen Mikrocode und deswegen wird bei ihnen das interne<br />
Schaltnetz in festverdrahteter Logik (Gatterverküpfungen ) realisiert.<br />
Diese einfachere Hardware läßt höhere Taktraten zu und da die Befehlsverarbeitung nach dem Pipeline-Prinzip<br />
erfolgt, wird meist pro Maschinentakt ein Befehl beendet.<br />
Da die heutigen Mikroprozessoren (Intel 80x86, Motorola 680x0 usw ) kompatibel zu den ersten CISC-<br />
Bausteinen der jeweiligen Mikroprozessorfamilie bleiben müssen, sind auf den heutigen Bausteinen meist CISC-<br />
und RISC-Komponenten gemischt untergebracht.<br />
Als grobe Kriterien für die Leistungskategorie des Prozessors bzw Rechners gelten die externe Datenbus -<br />
breite die meistens identisch ist mit der internen Registerbreite und der Takt.<br />
Je größer die Taktrate und die Datenbusbreite, um so mehr Daten können pro Zeiteinheit aus dem Arbeits -<br />
speicher in den Prozessor übertragen werden.<br />
<strong>6.</strong>6 Personal-Computer PC und Intel 80x86-Prozessoren.<br />
Der 16-Bit-Prozessor 8086 begründete die 80x86-Familie von Intel und wurde in der “Light-Version“ des<br />
8088 (nur 8-Bit-Datenbus) der Stammprozessor des IBM-Personal -<strong>Computers</strong>.<br />
Der 8086 wurde so weit wie nur möglich kompatibel zur 8-Bit-Vorgängergeneration 8080/8085 entwickelt<br />
und hatte neben einem 16-Bit-Datenbus einen 20-Bit-Adressbus mit einem realen Adressraum von 1 Mbyte .<br />
Dieser Adressierungsmodus wird als Real-Mode bezeichnet und das Betriebssystem DOS (Disk Operating<br />
System ) ist in seinen Funktionen im wesentlichen auf diesen Real-Mode beschränkt.<br />
PC-Kategorie Prozessor Register [Bit] Datenbus [Bit] Adreßbus [Bit] Takt [MHz]<br />
Ur-Pc 8088 16 8 20 4,77<br />
XT 8086 16 16 20 4,77 – 10<br />
AT 80286 16 16 24 6 – 20<br />
-386 80386 32 32 32 25 – 40<br />
-486 80486 32 32 32 25 – 100<br />
Pentium 80586 32 64 32 100 – 500<br />
Pentium IV Pentium IV 32 64 36 > 1500<br />
Um ein Programm, das für den ersten Ur-PC entwickelt wurde, auch noch auf einem heutigen Pentium-PC<br />
ablaufen lassen zu können, sind alle Intel 80x86-Prozessoren aufwärtskompatibel, d.h. sie enthalten alle<br />
Befehle und Funktionen der vorhergehenden Prozessorgeneration.<br />
In jedem 80x86-Prozessor ist somit der Real-Mode ( 8086-Prozessor ) vorhanden und da unter dem Betriebs-<br />
system WINDOWS auch das Betriebssystem DOS zur Verfügung gestellt wird, ist Kompatibilität zurück bis<br />
zum Ur-Pc gewährleistet.<br />
Bei den Nachfolgeprozessoren des 8086 hat INTEL zur Unterstützung <strong>eines</strong> Multitasking durch ein vierstufiges<br />
Speicherschutzkonzept den sogn. Protected Virtual-Adress-Mode ( PVA ) eingeführt.<br />
Da sich alle 80x86-Prozessoren nach dem Einschalten im Real Mode befinden, erfolgt die Umschaltung in den<br />
Protected-Mode durch Setzen <strong>eines</strong> Bits im Maschinenstatuswort .<br />
Der Speicher über der 1Mbyte-Grenze ( Extended Memory bis 4 Gbyte ) kann von den 80x86-Prozessoren<br />
nur im Protected-Mode angesprochen werden.<br />
Der ab dem 80386 zur Verfügung stehende Virtual 8086 Mode ermöglicht die Betreibung von Real-Mode-<br />
Programmen in der geschützten Umgebung des Protected-Mode. ( z.B. MS-DOS-Eingabeaufforderung unter<br />
WINDOWS )<br />
Ab dem 80386 ist die interne Registerbreite von 16 auf 32 Bit verdoppelt worden und diese stehen auch im<br />
Real-Mode zur Verfügung, können aber aus Gründen der Kompatibilität für DOS-Programme nicht effizient<br />
verwendet werden.
Rechnergrundlagen Teil 2 - 8 - Prof. Dipl.-Ing. Komar<br />
<strong>6.</strong>7 Der Personal-Computer als Mikrocomputer-Versuchs und Übungssystem ( PC– MVUS )<br />
Mit den DOS-Hilfsprogrammen DEBUG und EDIT kann man ohne symbolische Assembler wie TASM<br />
( Borland ) oder MASM ( Microsoft ) den PC als Mikrocomputer Versuchs- und Übungssystem benutzen.<br />
Das DOS-Kommando DEBUG dient der Fehlersuche ( debugging ) auf Maschinenbefehlsebene. Man kann es<br />
aber auch als ein Einfachst-Betriebssystem (sogn. Monitor ) verwenden, mit dessen Hilfe kleine Assembler-<br />
Programme entwickelt und getestet werden und auch ablaufen können.<br />
Denn DEBUG enthält einen einfachen Zeilenassembler mit dessen Hilfe unter DOS im Real-Mode kurze<br />
COM-Programme ( Begrenzung auf 64 Kbyte ) entwickelt werden können.<br />
Die Ein/Ausgabe über Tastatur und Bildschirm wird mit Hilfe der entsprechenden Betriebssystemfunktionen<br />
(DOS und BIOS-Interrupts ) für Tastatur und Bildschirm bewerkstelligt.<br />
Das Monitorprogramm DEBUG erlaubt es, Assemblerbefehle Zeile um Zeile in Maschinencode<br />
umzuwandeln und ab einer bestimmten Adresse im Speicher abzulegen ( line by line Assembler ). Bei dieser<br />
einfachsten Art der Programmierung können jedoch Operanden wie z.B. Adressen und Konstanten nicht<br />
symbolisch, d.h. in Form von definierten Bezeichnern angegeben werden, sondern müssen stets als<br />
Hexadezimalzahlen in der Assemblerzeile auftreten. Insbesondere bei Sprungbefehlen muß dazu das Sprungziel<br />
als absolute Adresse angegeben und vom Programmierer vorher berechnet werden.<br />
Müssen später weitere Assemblerbefehle eingefügt werden, so verschieben sich die Adressen für die folgenden<br />
Befehle entsprechend und der Vorteil <strong>eines</strong> komfortablen Assemblers zur professionellen Programmentwick-<br />
lung wird schnell deutlich.<br />
Mit dem zu DOS gehörendem Texteditor EDIT kann man für größere Programme eine Quelldatei aus<br />
Assemblerbefehlen und DEBUG-Anweisungen erzeugen, die dann in einem Durchlauf vom Debugger<br />
übersetzt werden kann. Damit lassen sich mit dem Debugger auch größere Assemblerprogramme handhaben.<br />
<strong>6.</strong>8 DEBUG<br />
Der englische Begriff bug bedeutet soviel wie Wanze oder Käfer. Tatsächlich wird ein Fehler in einem<br />
Computerprogramm im Fachjargon ebenfalls als bug bezeichnet. Entsprechend wird die Fehlersuche oder<br />
Fehlerbeseitigung in Programmen Debugging genannt.<br />
Man unterscheidet im wesentlichen drei verschiedene Arten von Fehlern, die bei der Erstellung von Computerprogrammen<br />
auftreten können:<br />
- Syntaxfehler<br />
- Laufzeitfehler<br />
- Logikfehler<br />
Ein Syntaxfehler ist ein Verstoß gegen die Regeln der jeweiligen Programmiersprache, also beispielsweise ein<br />
Tippfehler oder ein gänzlich unbekannter Befehl. Der Compiler (=Programm, das die geschriebenen Befehle in<br />
die für den Computer verständliche Binärcodierung umsetzt) meldet solche Fehler und fordert den<br />
Programmierer zur Korrektur auf.<br />
Syntaxfehler sind die einfachste und "angenehmste" Fehlerart und entsprechend leicht zu beheben.<br />
Bei einem Laufzeitfehler konnte das Programm vom Compiler zwar korrekt in Maschinencode übersetzt<br />
(=compiliert) werden, doch weist das Programm bei seiner Ausführung einen Fehler auf, der zum Beispiel durch<br />
eine Division durch Null (hierauf reagieren Computer sehr empfindlich) oder durch andere unerlaubte Dinge<br />
ausgelöst wurde, die zum Zeitpunkt der Compilierung noch nicht abzusehen waren (Drucker nicht bereit,<br />
falscher Bildschirmtyp, Festplatte voll etc.).<br />
Die unangenehmste Fehlerart sind die Logikfehler: das Programm wurde ebenfalls fehlerfrei compiliert und<br />
arbeitet sogar - nur leider tut es nicht das, was es eigentlich tun sollte. Logikfehler sind in der Entwicklungsphase<br />
größerer Programme unvermeidbar, da kein Programmierer ein Programm derart vor seinem geistigen Auge<br />
ablaufen lassen kann, wie es der Computer später real ausführt.
Rechnergrundlagen Teil 2 - 9 - Prof. Dipl.-Ing. Komar<br />
7. 1 Programmiermodell des INTEL 8086-Prozessors ( Real Mode )<br />
enthält die Register mit ihren symbolischen Namen, die für den Programmierer erreichbar sind.<br />
Bit-Nummer 15 8 7 0<br />
AX AH AL AL Arbeitsregister allg. Arbeitsregister 16 Bit breit<br />
auch als zwei 8-Bit-Register verwendbar<br />
BX BH BL BL<br />
H -> High höherwertiges<br />
L-> Low niederwertiges Byte<br />
CX CH<br />
CH<br />
CL<br />
CL<br />
DH DL<br />
DX DH DL<br />
Offsetregister<br />
SI Indexregister SI -> Source Index ( Quellindex )<br />
DI DI -> Destination Index (Zielindex )<br />
SP Stapelzeigerregister SP-> Stackpointer zeigt auf den aktuellen<br />
Eintrag im Stack ( Stapel )<br />
BP BP -> Basepointer<br />
CS Segmentregister CS-> Codesegment, zeigt auf Speicher-<br />
segment mit aktuellem Programmcode<br />
DS DS->Datensegment, zeigt auf Daten<br />
ES ES->Extrasegment ( 2.Datensegment )<br />
SS SS->Stacksegment, zeigt auf Stapelsegment<br />
für Zwischenspeicherung<br />
IP Befehlszeiger IP-> Instruction Pointer zeigt auf die Speicher-<br />
adresse mit dem nächsten auszuführenden<br />
Befehl<br />
F Prozessorstatusregister F -> Flagregister , die einzelnen Flags<br />
(Bits) weisen auf wichtige interne<br />
Prozessorzustände hin.<br />
Flagregister (Status register) F :<br />
15 14 13 12 11 10 9 8 7 6 5 4 3 2 1 0<br />
0 NT IO PL O D I T S Z 0 A 0 P 1 C<br />
Kurzbez. Bezeichnung Debug-Bez. Bedeutung<br />
1 0<br />
C Carry CY / NC C zeigt einen Übertrag aus der höchstwertigen Stelle an<br />
wird benötigt bei arithmetischen und logischen Operationen<br />
P Parity PE / PO Im niederwertigen Byte des Ergebnisses ist die Anzahl der auf<br />
even / odd 1 stehenden Bits gerade (even) (keine Ergänzung !! nur Anzeige )<br />
A Auxiliary AC / NA zeigt einen Übertrag von Bit 3 nach Bit 4 an<br />
Carry benötigt für Dezimalkorrektur beim Rechnen mit BCD-Zahlen
Rechnergrundlagen Teil 2 - 10 - Prof. Dipl.-Ing. Komar<br />
Z Zero ZR / NZ zeigt an, ob das Ergebnis einer Operation 0 ist<br />
S Sign NG / PL zeigt das Vorzeichen <strong>eines</strong> Ergebnisses an ( höchstwertiges Bit )<br />
O Overflow OV / NV Überlauf, d.h. Vorzeichenumkehr, Überschreiten des Zahlenbereiches<br />
vorzeichenbehafteter Dualzahlen<br />
Steuerflags<br />
D Direction DN / UP gibt bei Stringoperationen die Indexrichtung (inkrementieren oder<br />
dekrementieren) an<br />
I Interrupt Enable EI / DI maskierbare externe Interrupts werden zugelassen (INTR-Eingang)<br />
/ gesperrt<br />
T Trap nach Ausführung <strong>eines</strong> Maschinenbefehls wird ein Interrupt<br />
ausgelöst, um Programme zu testen ( Einzelschrittmodus )<br />
7.1.1 Adressierung<br />
Im Real -Mode arbeiten die 80x86-Prozessoren mit einer 20-Bit-Adresse und können damit einen Speicher -<br />
bereich von 1 Mbyte adressieren.<br />
Da aber nur 16 Bit breite Register zur Verfügung stehen, wird die physikalische 20-Bit-Adresse aus einer<br />
effektiven 16-Bit-Adresse ( Offsetadresse ) und einem Segmentregisterinhalte (16 Bit) automatisch im<br />
Prozessor gebildet ( Segment : Offset )<br />
Dazu wird der Segmentregisterinhalt um 4 Stellen nach links geshiftet (entspricht Multiplikation mit 1610 )<br />
und die Offsetadresse addiert.<br />
Physikalische Adresse ( 20 Bit ) = Segmentadresse ( 16 Bit ) * 1610 + Offsetadresse (16 Bit )<br />
Bei der Programmcodeadressierung bilden das Codesegmentregister und der Instruction-Pointer ein Paar<br />
und man schreibt<br />
CS : IP z.B. 4F7E : 2100<br />
Offsetadresse 2 1 0 0 h<br />
Segmentadresse * 16 + 4 F 7 E h<br />
_____________________<br />
absolute Adresse = 5 1 8 E 0 h<br />
Die Summe von Segment- und Offsetadresse führt immer zu einem eindeutigen Ergebnis, umgekehrt kann von<br />
einer absoluten Adresse nicht eindeutig auf eine Offset- und Segmentadresse geschlossen werden, da es eine<br />
Vielzahl möglicher Kombinationen gibt.<br />
Eine Änderung der Segmentadresse um 1 bewirkt eine Änderung der absoluten ( physikalischen ) Adresse<br />
um nur 16 ( = 1 Paragraph )<br />
Jedem Programm das unter DOS läuft, werden im Speicher das Codesegment CS, das Datensegment DS, das<br />
Stacksegment SS und das Extrasegment ES zugewiesen.<br />
Ein einzelnes Segment, dessen Beginn durch den Inhalt des Segmentregisters festgelegt wird, kann 64 kByte<br />
groß sein. Die einzelnen Segmente können völlig getrennt sein oder sich mehr oder weniger überlappen.<br />
Durch diese vier Segmentregister ist es möglich, vier verschiedene Speicherbereiche gleichzeitig in einem<br />
Programm anzusprechen.<br />
Beim Laden von .COM-Programmen werden von DOS alle vier Segmentregister auf die gleiche freie<br />
Adresse im Arbeitsspeicher gesetzt.<br />
Damit stehen in COM-Programmen nur 64 kByte Speicher zur Verfügung und man arbeitet im Grunde wie<br />
bei einer 16-Bit-Adressmaschine nur mit den Offsetadressen.<br />
Folgende Registerpaare sind zur Adreßbildung einander fest zugeordnet: Befehlsadresse CS : IP<br />
Stapeladresse SS : SP<br />
Zieladresse ES : DI
Rechnergrundlagen Teil 2 - 11 - Prof. Dipl.-Ing. Komar<br />
7.1.2 Speicherbelegung im PC unter DOS<br />
1MByte FFFFF<br />
F0000<br />
C0000<br />
640Kbyte A0000<br />
057FF<br />
05000<br />
00500<br />
00400<br />
003FF<br />
BIOS – ROM<br />
System- BIOS<br />
Andere ROM – Bereiche<br />
Zusatz- BIOS<br />
Bildschirm RAM<br />
COMMAND.COM ladbarer Teil<br />
freier RAM für Anwendungen<br />
COMMAND.COM residenter Teil<br />
DOS - Variablen, Puffer<br />
Gerätetreiber<br />
MSDOS.SYS<br />
IO.SYS<br />
BIOS Variablen<br />
Interruptvektoren<br />
00000<br />
Adressen<br />
Unter DOS sind die ersten 640 kByte für das Betriebssystem und die Anwendungsprogramme reserviert.<br />
Über 640 Kbyte liegt zunächst der Video-RAM, an den sich ab 768 kByte die verschiedenen BIOS anschließen.<br />
Über 1Mbyte beginnt der Extended Memory, der sich bis 4 Gbyte ( 32-Bit-Adressbus ) erstrecken kann.<br />
Der sogn. Higher Memory Area HMA ist der Speicherbereich oberhalb von 1 Mbyte 100000 – 10FFEF h<br />
der im Real-Mode bei den 8086-Nachfolgeprozessoren erreichbar ist. Dies wird durch den größeren<br />
Adressbereich dieser Prozessoren ( 24 – 32 Bit ) ermöglicht und zwar über deren Adressbit A 20 .<br />
Wird die physikalische Adresse aus den maximalen Werten FFFF h in Segment und Offset gebildet, so ergibt<br />
sich ein maximaler Wert für die physikalische Adresse oberhalb der Real-Mode-Grenze von 1 Mbyte.<br />
Segment * 2 4 FFFF0 h<br />
+ Offset FFFF h<br />
phys. Adresse 10FFEF h (max. erreichbare Adresse, 65 520 Byte oberhalb 1 Mbyte )<br />
Bei diesen Werten werden beim 8086 (A20 fehlt ) die Adressen 00000 – 0FFEFh angesprochen (sogn. wrap<br />
around ). Bei den Nachfolgeprozessoren wird im PC dieses wrap around -Verhalten durch die Steuerung des<br />
Adressbits A20 über den Tastaturcontroller erreicht. (zwecks Kompatibilität !! )
Rechnergrundlagen Teil 2 - 12 - Prof. Dipl.-Ing. Komar<br />
7.1.3 Interrupt-Vektor-Tabelle<br />
Wichtige Einträge in der Interrupt-Vektor-Tabelle (werden von DOS beim Hochfahren ( boot ) gesetzt)<br />
INT-NR. Adressbereich Standardbelegung Portadressen<br />
der wichtigsten Bausteine<br />
00 0000 – 0003 CPU: Division durch Null<br />
01 0004 – 0007 CPU: Single Step<br />
02 0008 – 000B RAM-Fehler (NMI)<br />
03 000C– 000F CPU: Breakpoint erreicht<br />
04 0010 – 0013 CPU: numerischer Überlauf INTO<br />
05 0014 – 0017 Print Screen (Bildschirm Hardcopy )<br />
06 0018 –001B CPU: unbekannter Befehl<br />
08 0020 – 0023 IRQ0: Timer-Baustein 0040 – 005F<br />
09 0024 – 0027 IRQ1: Tastatur 0060 – 006F<br />
0A 0028 – 002B IRQ2: 2.Interruptcontroller 00A0 - 00BF<br />
0B 002C – 002F IRQ3: 2.serielle Schnittstelle COM2 02F8 – 02FF<br />
0C 0030 – 0033 IRQ4: 1.serielle Schnittstelle COM1 03F8 – 03FF<br />
0D 0034 – 0037 IRQ5: 2 Drucker 0278 – 027F<br />
0E 0038 – 003B IRQ6: Diskettenlaufwerk 03F0 – 03F7<br />
0F 003C – 003F IRQ7: 1.Drucker 0378 – 037F<br />
10 0040 – 0043 BIOS: Video-Funktionen<br />
16 0058 – 005B BIOS : Tastaturabfragen<br />
19 0064 – 0067 BIOS: Warmstart <br />
1A 0068 – 006B BIOS: Zeit / Datum abfragen<br />
20 0080 – 0083 DOS: Programm beenden<br />
21 0084 – 0087 DOS: Diverse DOS-Funktionen<br />
70 01C0 – 01C3 IRQ8 : Echtzeituhr 0070 – 007F<br />
75 01D4 – 01D7 IRQ13: Co-Prozessor 00F0 – 00FF<br />
76 01D8 – 01DB IRQ14: Festplatte<br />
F1 03C4 – 03FF nicht benutzt: können vom Anwender frei belegt werden<br />
FF<br />
CPU: interne Hardwareinterrupts , werden vom Prozessor durch Ausnahmesituationen ( Exceptions ) bzw.<br />
Fehlersituationen selbst ausgelöst ( Faults, Traps und Aborts )<br />
IRQ: externe Hardwareinterrupts werden von peripheren Komponenten des PCs über die beiden<br />
Interruptcontroller ausgelöst.<br />
DOS / BIOS: Software-Interrupts erfolgen programmgesteuert wie Unterprogramm-Calls mit INT-Befehlen<br />
und sind somit nichts anderes als verkürzte Unterprogrammaufrufe mit variabler Sprung-<br />
adresse in der Interrupt –Vektor – Tabelle.<br />
Externe Hardware -Interrupts am INTR-Eingang können entweder alle gemeinsam durch das Sperren des<br />
INTR-Eingangs generell unterdrückt werden (Löschen des Interrupt-Flags durch CLI ) oder einzeln selektiv<br />
durch Programmierung der Masken der beiden Interrupt-Controller.<br />
Der Interrupt-Eingang NMI ( nicht maskierbarer Interrupt ) ist nicht sperrbar und ist im PC als<br />
Katastropheneingang für schwere Systemfehlern ( Speicher-Fehler ) verschaltet und damit für den Anwender<br />
nicht nutzbar.
Rechnergrundlagen Teil 2 - 13 - Prof. Dipl.-Ing. Komar<br />
7.1.4 Das Speichermodell COM<br />
DOS kennt zwei verschiedene Typen von ausführbaren Maschinenprogrammen: EXE und COM.<br />
Ein COM -Modul ist dadurch gekennzeichnet, daß alle 4 Segmente deckungsgleich "übereinander " liegen,<br />
d.h. beim Laden <strong>eines</strong> COM -Programmes durch DOS werden alle Segmentregister mit dem gleichen Adress-<br />
wert initialisiert.<br />
Damit existiert nur ein einziges gemeinsames Segment von 64 Kbyte für Programmcode, Daten und Stapel, was<br />
einer 16-Bit -Adressmaschine entspricht.<br />
Beim Aufruf wird jedes COM-Programm von DOS mit einem Kopf, dem Program Segment Prefix (PSP )<br />
versehen. In diesen Vorspannblock speichert DOS bestimmte Informationen, die man bei der systemnahen<br />
Programmierung manchmal benötigt.<br />
Der PSP ist 256 Byte groß, beginnt immer bei der Offset-Adresse 0000 und reicht bis 00FF h. Aus diesem<br />
Grund beginnt ein COM-Programm immer bei Adresse 100 h.<br />
Die Register werden bei einem COM-File wie folgt initialisiert:<br />
CS = DS = ES = SS wird durch DOS anhand des freien Speicherplatzes festgelegt.<br />
IP = 100 h Programmstart bei CS : 100 h<br />
SP = FFFE h Stapelzeiger SP wird mit FFFF h auf das Ende des Segmentes gesetzt und der Stapel<br />
mit der 16-Bit Rücksprungadresse 0000 belegt.<br />
Der Stapel wächst zu kleineren Adressen hin.<br />
In Adresse 0 und 1 enthält der PSP den Befehl INT 20 h . Ein Sprung an die Adresse 0 führt zur Beendigung<br />
des Programms aber auch ein RET am Ende des Programms führt über die Rücksprungadresse 0000 auf den<br />
INT 20 h Befehl und damit zur Beendigung des Programmes und zur Rückkehr nach DOS.<br />
Ab Adresse 80 h beginnt der Parameterbereich, der alle Parameter enthält, die in der Kommandozeile nach dem<br />
Programmaufruf eingegeben wurden. Befehle für die E/A-Umleitung ( ) sind nicht enthalten.<br />
In Adresse 80h ist die Anzahl der Zeichen in der Kommandozeile ( exklusiv des abschließenden CR ) enthalten<br />
und ab 81h folgen die Character der Kommandozeile ( nach dem Programmaufruf ).<br />
Aufbau des Program-Segment-Prefix PSP :<br />
Offset<br />
00 – 01 INT 20h –Befehl<br />
02 – 03 der vom Programm belegte Speicher in Paragraphen ( 16-Byte-Blöcke )<br />
05 – 09 FAR-Call zum Interrupt 21 h<br />
0A – 0D Kopie von Interrupt-Vektor 22h , Beendigungsadresse<br />
0E – 11 Kopie von Interrupt-Vektor 23h , Ausstiegsadresse für Ctrl-Break<br />
12 – 15 Kopie von Interrupt-Vektor 24h , Ausstiegsadresse für fatale Fehler<br />
2C – 2D Programmumgebungsadresse ( Segment )<br />
50 – 52 enthält INT 21 h, RET durch FAR CALL können Funktionsaufrufe erfolgen<br />
5C – 6B File Control Block FCB des ersten Parameters der Kommandozeile<br />
6C – 7B FCB des zweiten Parameters<br />
80 – FF Parameterbereich, enthält alle Zeichen (Characters), die nach dem Kommandonamen<br />
eingegeben wurden. In 80h Anzahl der Zeichen<br />
SS : SP<br />
CS: IP CS : 0100 h<br />
SS=ES=DS=CS : 0000<br />
Stapel vergrößert sich von der höchsten Segmentadresse nach<br />
unten<br />
Programmcode und Daten<br />
Programmsegmentpräfix PSP<br />
Speicherabbild <strong>eines</strong> COM-Programmes nach dem Laden
Rechnergrundlagen Teil 2 - 14 - Prof. Dipl.-Ing. Komar<br />
7.1.5 Maschinensprache des 8086<br />
Je nach Befehl und Adressierungsart kann ein Maschinenbefehl des 8086 1 bis 6 Byte lang sein.<br />
Byte 1 Byte 2 Byte 3 Byte 4 Byte 5 Byte 6<br />
Opcode Adressie- Operandenteil<br />
rungsart<br />
Der Opcode legt fest, was getan werden soll, der Operandenteil womit .<br />
MOV DX,4037 wird vom Assembler in den Maschinencode ( Objectcode ) BA3740 h übersetzt.<br />
Das 1.Byte BA h ist der Opcode und die beiden nächsten Byte 3740 h bilden den Operandenteil<br />
Das Vertauschen von High und Low Byte des Operanden hängt zusammen mit der<br />
INTEL-Konvention zur Datenspeicherung :<br />
High Byte (Word) auf High- Adresse, Low Byte (Word) auf Low-Adresse<br />
INTEL-Konvention für die Reihenfolge der Operanden <strong>eines</strong> Befehls:<br />
1.Operand ist Ziel , 2. Operand ist Quelle 1. Operand ist Quelle u. Ziel, 2. Operand ist Quelle<br />
MOV BX, DX ADD DX, CX<br />
Quelle Quelle<br />
Ziel Quelle und Ziel<br />
Zwei (Integer) - Datentypen werden auch in DEBUG wie folgt definiert:<br />
DB Define Byte Reserviert ein Byte DB 10 DB 'A'<br />
DW Define Word Reserviert zwei Byte DW 1FA4 DW '23'<br />
Beispiel zur Intel-Konvention für Datenspeicherung in DEBUG-Assembler-Syntax (alle Werte hexadezimal)<br />
Speicherbelegung<br />
Offset-Adresse Inhalt<br />
ORG 100<br />
DB 12, 34, 56, 78 0 1 0 0 1 2<br />
1 3 4<br />
2 5 6<br />
3 7 8<br />
4 –<br />
ORG 200<br />
DW 1234, 5678 0 2 0 0 3 4<br />
1 1 2<br />
2 7 8<br />
3 5 6<br />
4 –<br />
Inhalt von AX = AH | AL nach Ausführung des Befehls<br />
MOV AX, [ 0100 ] -> 34 12<br />
MOV AX, [ 0200 ] - > 12 34<br />
MOV AX, [ 0201 ] - > 78 12
Rechnergrundlagen Teil 2 - 15 - Prof. Dipl.-Ing. Komar<br />
7.1.6 Übersicht der 8086-Assemblerbefehle ( Maschinenbefehle )<br />
Befehl Funktion<br />
AAA ASCII adjust AL for addition<br />
AAD ASCII adjust for division<br />
AAM ASCII adjust for multiply<br />
AAS ASCII adjust for subtraction<br />
ADC Xl ,X2 Add with carry<br />
ADD X1,X2 Addition<br />
AND Xl ,X2 Logical-AND<br />
CALL NAER CALL im Segment<br />
CALL FAR CALL über Segmentgrenzen<br />
CBW Convert byte in word<br />
CLC Clear caw flag<br />
CLD Clear direction flag<br />
CLI Clear interrupt enable flag<br />
CMC Complement carrv flag<br />
CMP Xl ,X2 Compare<br />
CMPS Xl ,X2 Compare Strings<br />
CWD Convert word to doubleword<br />
DAA Decimal adjust AL after addition<br />
DAS Decimal adjust AL after subtraction<br />
DEC Xl Decrement<br />
DIV Xl Unsigned divide<br />
HLT Halt<br />
IDIV Xl Signed divide<br />
IMUL Xl Signed multiply<br />
IN Xl ,X2 Input byte/word from port<br />
INC Xl Increment Xl um 1<br />
INT 3 Interrupt 3<br />
INT xx Interrupt xx<br />
INTO Interrupt on overflow<br />
IRET Interrupt return<br />
JA cb Jump short if above (CF=0 and ZF=0)<br />
JAE cb Jump short if above or equal (CF=0)<br />
JB cb Jump short if below (CF=l)<br />
JBE cb Jump short if below or equal (CF=1 or ZF=l)<br />
JC cb Jump short if carry (CF=1)<br />
JCXZ cb Jump short if CX register is zero<br />
JE cb Jump short if equal (ZF=l)<br />
JG cb Jump short if greater (ZF=0 and SF=OF)<br />
JGE cb Jump short if greater or equal (SF=OF)<br />
JL cb Jump short if less (SF/=OF)<br />
JLE cb Jump short if less or equal (ZF=l or SF/=OF)<br />
JMP cb Jump short<br />
JMP FAR Jump far (4-byte address)<br />
JMP NEAR Jump near<br />
JNA cb Jump short if not above (CF=l or ZF=l)<br />
JNAE cb Jump short if not above or equal (CF=l)<br />
JNB cb Jump short if not below (CF=0)<br />
JNBE cb Jump short if not below or equal (CF=0 and ZF=0)<br />
JNC cb Jump short if not carry (CF=0)<br />
JNE cb Jump short if not equal (ZF=0)<br />
JNG cb Jump short if not greater (ZF=l or SF/=OF)<br />
JNGE cb Jump short if not greater or equal (SF/=OF)<br />
JNL cb Jump short if not less (SF=OF)<br />
JNLE cb Jump short if not less or equal (ZF=0 and SF=OF)<br />
JNO cb Jump short if not overflow (OF=0)<br />
JNP cb Jump short if not parity (PF=0)<br />
JNS cb Jump short if not sign (SF=0)<br />
JNZ cb Jump short if not zero (ZF=0)<br />
JO cb Jump short if overflow (OF=l)<br />
JP cb Jump short if parity (PF=l)<br />
JPE cb Jump short if parity even (PF=l)<br />
JPO cb Jump short if parity odd (PF=0)<br />
JS cb Jump short if sign (SF=l)<br />
JZ cb Jump short if zero (ZF=l)
Rechnergrundlagen Teil 2 - 16 - Prof. Dipl.-Ing. Komar<br />
LAHF Load: AH= flags<br />
LDS Xl ,X2 Load pointer using DS<br />
LEA Xl ,X2 Load effectiv adress<br />
LES Xl ,X2 Load pointer using ES<br />
LODS Load stringbyte<br />
LODSW Load stringword<br />
LOOP XX Loop DEC CX; jump short if CX/=0<br />
LOOPE XX Loop Equal DEC CX; jump short if CX/=0 and equal (ZF=l)<br />
LOOPNE XX Loop Not Equal DEC CX; jump short if CX/=0 and not equal<br />
LOOPNZ XX Loop Not Zero DEC CX; jump short if CX/=0 and ZF=0<br />
LOOPZ XX Loop Zero DEC CX; jump short if CX/=0 and zero (ZF=l)<br />
MOV Xl ,X2 Move<br />
MOVSB Move Stringbyte<br />
MOVSW Move Stringword<br />
MUL Multipy unsigned<br />
NEG Negate<br />
NOP No Operation<br />
NOT NOT-Vergleich<br />
OR Xl ,X2 Logical-OR<br />
OUT Xl ,X2 Output to port<br />
POP Xl POP Register from stack<br />
POPF Pop Flags<br />
PUSH Xl PUSH Register to stack<br />
PUSHF PUSH Flags<br />
RCL xx,l Rotate left carry<br />
RCR xx,l Rotate right carry<br />
REP (prefix) Repeat<br />
REPE (prefix) Repeat equal<br />
REPNE (prefix) Repeat not equal<br />
REPNZ (prefix) Repeat not zero<br />
REPZ (prefix) Repeat zero<br />
RETF Return far<br />
RET Return near<br />
ROL xx,1 Rotate left<br />
ROR xx,l Rotate right<br />
SAHF Store AH into flags<br />
SAL xx,l Shift arithmetik left<br />
SAR xx,l Shift arithmetik right<br />
SBB Xl ,X2 Subtract with borrow<br />
SCAS Compare Strings<br />
SHL xx,l Shift left<br />
SHR xx,l Shift right<br />
STC Set carry flag<br />
STD Set direction flag<br />
STI Set interrupt enable flag<br />
STOS xx Store String<br />
SUB Xl ,X2 Subtract<br />
TEST Xl ,X2 Test<br />
XCHG Xl ,X2 Exchange<br />
XLAT xx Translate<br />
XOR Xl ,X2 Exclusive-OR
Rechnergrundlagen Teil 2 - 17 - Prof. Dipl.-Ing. Komar<br />
7.1.7 Befehlssatz des 8086<br />
Adressierungsarten<br />
Die INTEL 80x86-Familie weist sechs Adressierungsarten auf. Bei Zwei-Operand-Befehlen ist ein Operand<br />
in der Regel ein Register. Der zweite bestimmt die Adressierungsart. Bei Ein-Operand-Befehlen bestimmt der<br />
Operand die Adressierungsart.<br />
Registeradressierung<br />
Alle Operanden stehen in Registern. Der Maschinencode ist kompakt und besonders schnell ausführbar.<br />
ADD CX,DX INC CX<br />
SUB AL,CH MUL BX<br />
Unmittelbare Adressierung<br />
Der Quelloperand ist eine Konstante. Es sind damit nur Zwei-Operand-Befehle möglich, wobei der erste<br />
Zieloperand ein Register oder eine Speicheradresse sein kann.<br />
ADD BL, A4 MOV AH,34 MOV AX,DDDD SUB WORD PTR [1000], 12AD<br />
Direkte Adressierung<br />
Ein Operand ist eine Speicheradresse. Diese wird in eckige Klammern [ ] gesetzt ( Syntax DEBUG-Assembler )<br />
MOV AX, [1000] ADD [AF00], DX SUB [2000], BL AND BYTE PTR [1000], FF<br />
Unzulässig ist folgender Befehl : MOV [1000] , [2000] weil Speicher zu Speicher - Zuweisung<br />
Indirekte Adressierung<br />
Der Operand ist ein Speicherplatz, der indirekt über bestimmte Register angesprochen wird.<br />
Form: Opcode Register, [Indexregister] oder Opcode [Indexregister], Register<br />
Als Indexregister dürfen nur SI, DI, BP und BX verwendet werden.<br />
MOV AX, [ SI ] ADD DX, [ BX ] AND [ DI ],CL<br />
Auch registerindirekte Sprünge sind möglich. Hier sind alle Register zulässig<br />
JMP AX springe zur Speicheradresse die gebildet wird aus CS : AX-Inhalt<br />
CALL DI Unterprogrammverzweigung zu der Adresse aus CS und Offset im DI-Register<br />
Basisregister plus Displacement<br />
Das Indexregister plus einer konstanten Verschiebung (displacement ) zeigt auf die Adresse im Speicher.<br />
MOV CX,[ BX + 4 ] Der Inhalt der beiden Byte mit den Adressen ( DS : BX-Inhalt + 4 ) und<br />
( DS : BX-Inhalt + 5 ) wird nach CX kopiert<br />
ADD AX, [ SI + 100 ] Der Inhalt des Wortes, dessen Adresse aus DS : [SI] + 100 h gebildet wird,<br />
wird zu AX hinzuaddiert<br />
MOV [ 6 + DI ] , BL Der Inhalt von BL wird in die Speicher-Adresse ES : [ DI ] + 6 kopiert<br />
Basisregister plus Indexregister plus Displacement<br />
Angesprochen wird die Speicheradresse, auf die das erste Indexregister plus dem Inhalt des zweiten Index-<br />
registers plus einer konstanten Verschiebung (displacement ) zeigt<br />
MOV CL, [ BP+DI+100 ] Speicheradresse SS : [ BP ] + [ DI ] + 100<br />
MOV [ BX ] [ DI ], AX Speicheradresse DS : [ BX ] + [ DI ] (z.B. Matrizenop. BX-> Zeile, DI->Spalte )
Rechnergrundlagen Teil 2 - 18 - Prof. Dipl.-Ing. Komar<br />
Transportbefehle MOV – IN / OUT – PUSH / POP<br />
Weil die INTEL-Prozessorfamilie maximal Speicher-zu-Register-Befehle zulässt, ist der MOV-Befehl<br />
der häufigste in einem 80x86-Programm. Beispielsweise bedeuten:<br />
MOV AX, DX transportiere den Inhalt von Register DX nach AX<br />
MOV CL,AH transportiere den Inhalt von Halbregister AH nach CL<br />
MOV BX,1000 lade die Zahl 1000 (hex) ins BX-Register<br />
MOV BL,C4 lade die Zahl C4 (hex) ins BL-Halbregister<br />
MOV [1000],CH transportiere den Inhalt von Halbregister CH zum Speicher l000 h<br />
MOV [1000],CX transportiere den Inhalt von Register CX zum Speicher 1000 und 1001<br />
Diese Adressierungsart nennt man ,,Register zu Speicher" oder ,,direkt".<br />
Als Operanden kommen prinzipiell Registerinhalte, Speicherinhalte und Konstanten in Frage. MOV kann als<br />
Prototyp der Zwei - Operand - Befehle gelten, ein Operand ist in der Regel ein Register. Dieses bestimmt die<br />
Wortbreite der Operation (16 Bit bei Vollregister, 8 Bit bei Halbregister ). Gemischte Operationen sind<br />
unzulässig!<br />
MOV AX, BL unzulässig, da unterschiedliche Registerbreite<br />
MOV [1000], [2000] unzulässig, da Speicher-zu-Speicher-Zuweisung<br />
Mit IN- und OUT-Befehlen lassen sich Daten zwischen Prozessor und I/O-Ports austauschen.<br />
Die Register aller Peripherie -Bausteine ( Controller ) können über Ports angesprochen werden. Die 80x86<br />
Familie verfügt über einen I/O-Adressraum von 64 Kbyte, der nicht mit dem Speicheradressraum<br />
zusammenfällt.<br />
Die I/O-Adressen sind 16 Bit lang und die meisten Peripheriebausteine weisen eine Register / Datenbusbreite<br />
von 8 Bit auf.<br />
IN AL , port Lade AL mit Byte aus port-Register port = niederwertiges Byte der I/O-Adresse<br />
IN AX , port Lade AX mit Wort aus port-Register höherwertiges Byte dabei Null<br />
IN AL,DX Lade AL mit Byte aus dem Portregister, dessen Adresse (16 Bit) in DX steht<br />
IN AX,DX Lade AX mit Wort aus dem Portregister, dessen Adresse in DX steht<br />
OUT port,AL Lade 8-Bit-port-Register mit dem Inhalt von AL, port = niederwertiges Adressbyte<br />
OUT port,AX Lade 16-Bit-port-Register mit dem Inhalt von AX<br />
OUT DX,AL Lade 8-Bit-Portregister, dessen Adresse in DX steht, mit dem Inhalt von AL<br />
OUT DX,AX Lade 16-Bit -Portregister, dessen Adresse in DX steht, mit dem Inhalt von AX<br />
Im PC sind die Portadressen auf 10 Adressbit beschränkt und für das System und die Erweiterungskarten<br />
stehen daher nur die Portadressen von 0000 bis 03FF h zur Verfügung.<br />
Mit den Befehlen PUSH und POP lassen sich die Inhalte der 16-Bit -Register und von Speicherworten auf<br />
dem Stapel zwischenspeichern bzw. zurückholen.<br />
Der Stapel (Stack) ist ein besonderer Bereich des Arbeitsspeichers, der durch den Stapelzeiger SP und das<br />
Stapelsegmentregister SS adressiert wird (SS : SP ) und nach dem Prinzip Last In – First Out (LIFO)<br />
organisiert ist. Legt man mit PUSH Wörter auf den Stapel, so wird der Stapelzeiger SP automatisch um 2<br />
vermindert, der Stapel wächst also zu niedrigen Adressen hin. Beim Herunterholen mit dem POP-Befehl ist es<br />
genau umgekehrt.<br />
Der Zugriff auf den Stapel erfolgt immer wortweise (16 Bit ), wobei das High-Byte auf der höheren und das<br />
Low-Byte auf der niedrigeren Adresse gespeichert wird.<br />
Der Stapelzeiger SP zeigt immer auf das zuletzt auf den Stapel gelegte Low-Byte.<br />
Bei jedem Unterprogramm-Aufruf mit dem Call-Befehl, wird die Rücksprungadresse auf den Stapel gelegt<br />
und bei dem Rücksprung mit RET wieder in den Instruction-Pointer IP zurückgeladen.<br />
Bei jedem Interrupt ( Hard- und Software ) werden das Statusregister F, das Codesegmentregister CS und der<br />
Befehlszähler IP auf den Stapel gerettet und mit dem Befehl IRET wieder zurückgeholt.<br />
PUSH AX / POP DS legt / holt ein 16-Bit-Register auf / vom Stapel<br />
PUSH [1000] / POP [200] " Speicherwort "<br />
PUSHF / POPF legt / holt Statusregister F auf / vom Stapel
Rechnergrundlagen Teil 2 - 19 - Prof. Dipl.-Ing. Komar<br />
Arithmetische Befehle ADD – SUB – MUL – DIV–CMP–INC–DEC<br />
Alle arithmetischen Befehle arbeiten mit Ganzzahl-Operanden ( 8 Bit, 16 Bit oder 32 Bit)<br />
Bei Additions- und Subtraktionsbefehlen braucht hinsichtlich vorzeichenloser oder vorzeichenbehafteter<br />
Dualzahlen ( Zweierkomplementdarstellung negativer Zahlen ) nicht unterschieden werden.<br />
Ein Überschreiten des jeweiligen Zahlenbereiches wird für vorzeichenlose Dualzahlen im C-Flag (Carry )<br />
und für vorzeichenbehaftete im O-Flag (Overflow ) des Flagregisters F ( Statusregister ) angezeigt.<br />
ADD op1 , op2 op1 = op1 + op2 ADD AX, DX<br />
ADC op1 , op2 op1 = op1 + op2 + Carry-Bit ADC CH, BYTE PTR [BX+2]<br />
SUB op1 , op2 op1 = op1 – op2 SUB [1000], BX<br />
SBB op1 , op2 op1 = op1 – op2 – Carry-Bit SBB DH, 4F<br />
CMP op1 , op2 Testsubtraktion op1 – op2 ohne verändern von Operanden zum Setzen der Statusflags<br />
INC op1 op1 = op1 + 1 das Carryflag wird nicht verändert INC BYTE PTR [BX+2]<br />
DEC op1 op1 = op1 – 1 das Carryflag wird nicht verändert DEC WORD PTR [1000]<br />
bei op1 und op2 sind alle Byte und Wortoperanden zulässig.<br />
Die Multiplikations- und Divisionsbefehle gelten nur für den Akkumulator AX und das DX-Register als Hilfs-<br />
register. Es sind keine Konstanten als Operanden möglich.<br />
MUL byte AX = AL * Byteregister oder Speicherbyte MUL BYTE PTR [1000]<br />
MUL wort (DX+AX) = AX * Wortregister oder Speicherwort MUL WORD PTR [BX+1]<br />
DIV byte AL = AX / Byteregister oder Speicherbyte AH = Rest DIV CL<br />
DIV word AX = (DX + AX ) / Wortregister o. Speicherwort DX = Rest DIV CX<br />
MUL und DIV funktionieren richtig nur bei vorzeichenlosen Dualzahlen. Nach DIV sind die Arithmetikflags<br />
undefiniert und nach MUL zeigen C = O =1 an, daß AH oder DX signifikante Ergebnisstellen beeinhalten.<br />
Unmittelbare Adressierung mit Konstanten im Befehl ist bei MUL / IMUL und DIV / IDIV nicht möglich<br />
Für das Rechnen in vorzeichenbehafteten Zahlensystemen mit vorzeichenbehafteten Operanden sind die<br />
folgenden Befehle vorgesehen:<br />
IMUL byte AX = AL * Byteregister oder Speicherbyte IMUL AL<br />
IMUL word (DX+AX) = AX * Wortregister oder Speicherwort IMUL WORD PTR [101]<br />
IDIV byte AL = AX / Bytergister o. Speicherbyte AH = Rest IDIV BYTE PTR [BX+1]<br />
IDIV word AX = (DX + AX) / Wortreg. o. Speicherwort DX = Rest IDIV CX<br />
NEG operand Negiere den Operanden ( Zweierkomplement ) NEG AX<br />
CBW Lade AH mit dem Vorzeichenbit von AL 8 -> 16 Bit Bereichserweiterung von<br />
CWD Lade DX mit dem Vorzeichenbit von AX 16 -> 32 Bit vb. Dualzahlen<br />
DIV und IDIV liefern ein ganzzahliges Ergebnis mit Teilerrest, wobei dieser Teilerrest ganzzahlig und mit<br />
dem Vorzeichen des Dividenden (1.Operand) dargestellt wird. Überschreitet der Quotient die Kapazität des<br />
Zielregisters ( AL oder AX ) oder erfolgt eine Division durch Null, so wird der Interrupt INT 0 ausgelöst<br />
(Fehlermeldung)<br />
Dezimale arithmetische Operationen (BCD-Arithmetik)<br />
Diese Befehle führen Anpassungen und Korrekturen für die BCD-Arithmetik durch. Diese sollten vor oder nach<br />
den binären arithmetischen Operationen durchgeführt werden, wobei das Zielregister immer der Akku AL / AX<br />
sein muß, denn die nachfolgenden Korrekturoperationen beziehen sich immer auf AL / AX.<br />
DAA Dezimalkorrektur zweier gepackter Dezimalziffern in AL nach Addition<br />
DAS Dezimalkorrektur zweier gepackter Dezimalziffern in AL nach Subtraktion<br />
AAA Dezimalkorrektur in AL nach der Addition ungepackter Dezimalziffern, höherwertiges Nibble = 0<br />
Bei einem Übertrag (größer 9 ) wird AH inkrementiert.<br />
AAS Dezimalkorrektur in AL nach der Subtraktion ungepackter Dezimalziffern, höherwertiges Nibble = 0<br />
Bei einer negativen Differenz wird das AH-Register dekrementiert<br />
AAM Korrigiert das AX-Register nach einer dualen Byte-Multiplikation, so daß eine zweistellige<br />
ungepackte Dezimalzahl in AX entsteht. ( AH = AL / 10 d AL = Rest )<br />
AAD Vorbereitung einer dezimalen Byte-Division mit dem Befehl DIV. Umwandlung einer ungepackten<br />
BCD-Zahl in AX in eine Dualzahl in AL. Multipliziert AH mit 10 d und addiert dies zu AL. Setzt<br />
danach AH auf 0.
Rechnergrundlagen Teil 2 - 20 - Prof. Dipl.-Ing. Komar<br />
Logische Befehle NOT – AND – OR – XOR – TEST<br />
Die folgenden logischen Befehle führen bitweise die boolschen Verknüpfungen zwischen den beiden Operanden<br />
durch<br />
NOT operand Invertiere Operanden ( Einerkomplement ) NOT WORD PTR [BX+3]<br />
AND op1, op2 Lade op1 mit op1 UND op2 AND CX, [3000]<br />
OR op1, op2 Lade op1 mit op1 ODER op2 OR AX, 3FFF<br />
XOR op1, op2 Lade op1 mit op1 EODER op2 XOR BYTE PTR [BX+10],0F<br />
TEST op1, op2 Testverundung op1 UND op2 , verändert keine Operanden, verändert Statusflags<br />
bit1 bit2 AND OR XOR<br />
0 0 0 0 0<br />
0 1 0 1 1<br />
1 0 0 1 1<br />
1 1 1 1 0<br />
Schiebebefehle RCL – RCR – ROL – ROR – SAL – SAR – SHL – SHR<br />
Mit den Schiebebefehlen lassen sich aus Bytes oder Wörtern bestehende Bitmuster um eine oder mehrere<br />
Bitpositionen nach rechts oder links verschieben. Man unterscheidet das Schieben hinsichtlich<br />
zyklisch (rotieren ) -> 1.Buchstabe R -> über das Carry-Flag RC -> links RCL rechts RCR<br />
ohne das Carry-Flag RO -> links ROL rechts ROR<br />
arithmetisch ->ersten beiden Buchstaben SA -> links SAL rechts SAR<br />
logisch ->ersten beiden Buchstaben SH -> links SHL rechts SHR<br />
Alle Byte- oder Wortoperanden ( Register, Speicher ) sind möglich, wobei in CL die Anzahl der Schiebe-<br />
positionen angegeben werden muß, RCL operand,CL<br />
Wird nur um eine Bitposition nach links oder rechts geschoben, so genügt folgende Syntax ROR operand,1<br />
logisches Schieben -> in frei werdende Stelle eine 0 nachziehen, das herausfallende Bit geht ins Carry-Flag<br />
CY<br />
0 CY 0<br />
vorzeichenlose Dualzahl * 2 n vorzeichenlose Dualzahl / 2 n , Rest im Carry<br />
SHL AX , 1 n = geschobene Bitpositionen SHR BYTE PTR [DI+1] , CL<br />
arithmetisches Schieben -> die Operanden werden als vorzeichenbehaftete Dualzahlen behandelt, das Links-<br />
Schieben entspricht völlig dem logischem Links-Schieben SAL = SHL und auch der Opcode ist völlig<br />
identisch, beim arithmetischen Rechts-Schieben bleibt das höchstwertige Bit MSB erhalten (Vorzeichen )<br />
vorzeichenbehaftete Dualzahl * 2 n vorzeichenbehaftete Dualzahl / 2 n<br />
SAL AL, CL SAR WORD PTR [1000], 1<br />
zyklisches Schieben -> frei werdende Stellen werden durch herausgeschobene Bit ersetzt. Es geht kein Bit<br />
verloren. CY<br />
CY<br />
ROL / ROR schieben Operanden im Ring RCL / RCR schieben Operanden mitsamt Carry über<br />
herausgeschobenes Bit ins Carry das Carry -Flag im Ring<br />
ROR BYTE PTR [BX],CL RCL CX,CL<br />
CY
Rechnergrundlagen Teil 2 - 21 - Prof. Dipl.-Ing. Komar<br />
Programmverzweigungsbefehle JMP – Jcc – LOOP – CALL – INT<br />
Die kontinuierliche Bearbeitung eine sequentiellen Programms kann auf unterschiedliche Arten unterbrochen<br />
und an einer anderen Stelle fortgesetzt werden:<br />
- mit /ohne Speicherung der Rückkehradresse zur erneuten Aufnahme der Abarbeitung an der zuvor<br />
verlassenen Stelle (CALL, INT / JMP )<br />
- unabhängig oder abhängig vom aktuellen Zustand der CPU ( JMP / JBedingung )<br />
- programmiert oder asynchron durch externe Ereignisse (CALL, INT / Hardwareinterrupt )<br />
Wird die Rückkehradresse (Adresse des nächsten auszuführenden Befehls ) vor dem Sprung auf dem Stapel<br />
abgelegt, so handelt es sich um Unterprogramme oder Interrupt-Service-Routinen ISR .<br />
Ansonsten um bedingte und unbedingte Sprungbefehle.<br />
Während alle unbedingten Sprungbefehle stets zu einer Programmverzweigung führen, erfolgt bei den bedingten<br />
Sprüngen das Verzweigen in Abhängigkeit vom aktuellen Zustand <strong>eines</strong> Bits im Flagregister des Prozessors und<br />
damit in Abhängigkeit vom Ausgang einer zuvor ausgeführten Operation.<br />
Für den Übersetzungsvorgang ist es dabei wichtig zu wissen, ob sich das Sprungziel einer Programmverzwei -<br />
gung innerhalb des aktuellen Segments befindet oder nicht. Man unterscheidet darum:<br />
- Intra-Segment-Sprünge<br />
Das Sprungziel liegt im aktuellen Segment und es wird nur ein neuer 16 Bit Offset für IP benötigt.<br />
- Inter-Segment-Sprünge<br />
Das Sprungziel liegt in einem anderen als dem momentan aktiven Codesegment und es wird ein neuer<br />
Segmentselektor für CS und ein Offset für IP benötigt<br />
Das Sprungziel kann dabei wie folgt adressiert werden:<br />
- Sprungziel relativ zum momentanen Stand von IP im selben Segment (Intra-Segment) gespeichert als<br />
1 Byte Displacement (-128.. +127) z.B. bedingte Sprungbefehle sind relative Sprünge mit kurzer Distanz<br />
- Sprungziel relativ zum momentanen Stand von IP im selben Segment (Intra-Segment) gespeichert als<br />
2 Byte Displacement (-32768.. +32767)<br />
- Sprungziel als absolute Adresse im selben Segment (Intra -Segment), gespeichert in einem Register oder in<br />
einer Speicheradresse ( je 2 Byte ) sog. Indirekt-Sprung<br />
- Sprungziel als absolute Adresse in einem anderen Segment (Inter-Segment) mit Angabe von<br />
Segmentselektor und Offset, gespeichert im Befehl als Immediate Operand mit 4 Byte, Direkt-Sprung<br />
- Sprungziel als absolute Adresse in anderem Segment (Inter-Segment) mit Angabe von Segmentselektor und<br />
Offset, gespeichert als Doppeiwort (IP, CS ) in einer Speicheradresse, Indirekt-Sprung<br />
Unbedingter Sprung JMP (nur Intrasegment-Sprünge )<br />
JMP ziel Springe immer zur Zieladresse JMP 1000<br />
JMP register Springe immer zur Adresse im Register JMP AX<br />
JMP speicherwort Springe immer zur Adresse im Speicherwort JMP [1200]<br />
JMP [reg] Springe zu Adresse im Speicherwort, dessen Adresse im Register steht JMP [BX]<br />
Bedingte Sprünge<br />
Vor einem bedingten Sprung muß zunächst die Sprungbedingung untersucht werden. Dies geschieht in der<br />
Regel durch einen Test-, Vergleichs- oder Zählbefehl, der mit seinem Ergebnis die Bedingungsbit des Status-<br />
registers verändert. Diese werden dann durch die bedingten Sprungbefehle ausgewertet.<br />
Ist die Sprungbedingung erfüllt, so wird der Sprung ausgeführt, anderenfalls wird mit dem nächsten Befehl<br />
fortgesetzt<br />
Alle bedingten Sprungbefehle springen mit einer relativen 8-Bit -Adresse im Segment (intrasegment).<br />
Durch diesen 8-Bit-Abstand (displacement) sind nur Sprungziele erreichbar, die sich im Bereich von 128 Bytes<br />
vor oder 127 Bytes hinter dem Sprungbefehl befinden.<br />
Jcc ziel cc = mnemonische Abkürzung der Bedingungen<br />
Viele dieser Sprungbefehle lassen sich mit verschiedenen mnemotechnischen Abkürzungen formulieren, die<br />
aber durch den Assembler in einen gemeinsamen Opcode umgesetzt werden. Bei der Disassemblierung mit
Rechnergrundlagen Teil 2 - 22 - Prof. Dipl.-Ing. Komar<br />
DEBUG wird aber nur eine mnemonische Abkürzung ausgegeben und deswegen kann sich das dissassemblierte<br />
Programm bezüglich seiner Mnemonik vom ursprünglichen Quellprogramm unterscheiden.<br />
Jump if Flags für Sprung<br />
JA / JNBE Above / Not Below or Equal (vl.D) C = 0 AND Z = 0<br />
JAE / JNB /JNC Above or Equal / Not Below / Not Carry (vl.D) C = 0<br />
JB / JNAE / JC Below / Not Above or Equal / Carry (vl.D) C = 1<br />
JBE / JNA Below or Equal / Not Above (vl.D) C OR Z = 1<br />
JG / JNLE Greater / Not Less nor Equal (vb.D) ( S XOR O ) OR Z = 0<br />
JGE / JNL Greater or Equal / Not Less (vb.D) S XOR O = 0<br />
JL / JNGE Less / Not Greater nor Equal (vb.D) S XOR O = 1<br />
JLE / JNG Less or Equal / Not Greater (vb.D) ( S XOR O ) OR Z = 1<br />
JE / JZ Equal / Zero Z = 1<br />
JNE / JNZ Not Equal / Not Zero Z = 0<br />
JO Overflow O = 1<br />
JNO Not Overflow O = 0<br />
JS Sign S = 1<br />
JNS No Sign (positiv ) S = 0<br />
JNP / JPO No Parity / Parity Odd P = 0<br />
JP / JPE Parity / Parity Even P = 1<br />
JCXZ CX is Zero Register CX = 0<br />
vl.D = vorzeichenlose Dualzahl vb.D = vorzeichenbehaftete Dualzahl<br />
Wiederholungsschleifen<br />
Schleifen mit festem Schleifenzähler CX. CX wird nach jedem Schleifendurchlauf dekrementiert und abgefragt.<br />
LOOP ziel CX = CX – 1 und springe wenn CX ≠ 0<br />
LOOPE / LOOPZ ziel CX= CX – 1, springe wenn CX ≠ 0 und Z = 1 (Ergebnis = 0 )<br />
LOOPNE / LOOPNZ ziel CX= CX –1, springe wenn CX ≠ 0 und Z = 0 (Ergebnis ≠ 0 )<br />
ziel is t eine relative 8-Bit-Adresse<br />
Unterprogrammaufruf CALL – RET<br />
Unterprogramme sind Programmteile, die von verschiedenen Programmstellen aufgerufen werden können und<br />
die nach Beendigung an die Stelle ihres Aufrufs zurückkehren. Unterprogramme werden mit dem CALL –<br />
Befehl aufgerufen und müssen mit dem Rücksprung-Befehl RET (Return) abgeschlossen werden.<br />
Beim Aufruf <strong>eines</strong> innerhalb des Segments liegendem Unterprogramms (Intrasegment) bleibt das Codesegment-<br />
register CS unverändert und es wird nur der Befehlszähler IP auf den Stapel gerettet und anschließend wird IP<br />
mit der CALL-Adresse ( Offset ) überschrieben und damit wird zum ersten Befehl des Unterprogramms<br />
verzweigt.<br />
Mit dem RET-Befehl wird die Rücksprungadresse ( Offset ) vom Stapel in den Befehlszähler IP<br />
zurückgeschrieben und damit wird hinter dem CALL-Befehl mit der Programmabarbeitung fortgefahren.<br />
CALL adresse direkte 16-Bit-Wortadresse<br />
CALL word-register Unterprogrammadresse befindet sich im 16-Bit-Register<br />
CALL WORD PTR wort Unterprogrammadresse befindet sich im Speicher-wort<br />
CALL WORD PTR [wreg] Adresse der Unterprogrammadresse befindet sich im Wortregister<br />
RET Rücksprung aus Unterprogramm ( Rückspr.-Adresse vom Stapel )<br />
RET zahl Rücksprung und Stapelzeiger SP um zahl erhöhen
Rechnergrundlagen Teil 2 - 23 - Prof. Dipl.-Ing. Komar<br />
Interrupt-Aufruf INT – IRET<br />
Mit dem INT-Befehl erfolgt der Aufruf <strong>eines</strong> speziellen Unterprogramms, wobei zuerst das Flagregister und<br />
danach die Rücksprungadresse auf den Stapel gesichert wird ( Softwareinterrupt )<br />
Danach wird die Einsprung-Adresse des Unterprogramms (4 Byte für Segment : Offset) aus der Interrupt-<br />
Vektortabelle gelesen, der INTR-Eingang und der Einzelschrittmodus gesperrt ( I =0 und T=0 im Flagregister )<br />
und zum Unterprogramm (Interrupt-Service-Routine ) verzweigt.<br />
Diese Interrupt-Vektor-Tabelle liegt im unteren Adressbereich von 0000:0000 bis 0000:03FF h und kann mit<br />
einer Länge von 1Kbyte insgesamt 256 verschiedene Interrupt-Einsprungadressen zu jeweils 4 Byte aufnehmen.<br />
Die Lage der Einsprung-Adresse in der Interrupt-Vektor-Tabelle wird mit der Nummer 0-255 im zweiten Byte<br />
des INT-Befehls angegeben.<br />
Mit dem IRET-Befehl wird aus der Interrupt-Routine zurückgesprungen, indem vom Stapel die Rücksprung -<br />
adresse nach IP und CS , sowie der Flagregisterinhalt nach F zurückgeholt werden.<br />
INT zahl Interrupt-Vektor befindet sich in Adresse 4 * zahl<br />
INTO Falls O-Flag gesetzt ist, erfolgt Aufruf von INT 4 (Vektor in 10 h )<br />
INT3 Durch ein Opcodebyte codiert. Für die Programmierung von Haltepunkten. (Vektor in 0C h )<br />
IRET Rücksprung vom Interrupt ( POP IP, POP CS, POPF )<br />
Flagregisterbefehle<br />
CLC Carry löschen C = 0 STC Carry setzen C = 1 CMC Carry invertieren<br />
CLI Interrupt-Enable-Flag I löschen und damit Interrupteingang INTR sperren<br />
STI " I setzen und damit Interrupteingang INTR freigeben<br />
CLD Direction Flag D löschen , bedeutet SI / DI inkrementieren<br />
STD " D setzen, " SI / DI dekrementieren<br />
LAHF Lade AH mit Low-Byte des Flagregisters<br />
SAHF Schreibe AH in das Low-Byte des Flagregisters<br />
Spezielle Datenübertragung XCHG, LES, LDS<br />
XCHG operand,operand Vertausche die beiden Operanden ( register / speicher und word / byte )<br />
LES wortreg. , doppelwort Lade ES- und Wort- Register aus Speicherdoppelwort<br />
LDS wortreg. , doppelwort Lade DS- und Wort- Register aus Speicherdoppelwort<br />
Prozessor-Steuerungsbefehle<br />
HLT Prozessor anhalten, Wiederanlauf nur durch Interrupt oder RESET möglich.<br />
NOP No Operation keine effektive Funktion, verbraucht nur Rechenzeit, Platzhalter<br />
String-Befehle und REP-Vorsätze ( Wiederholungsvorsätze )<br />
String-Befehle verwenden implizit die Register DS,ES sowie SI und DI um fortlaufend auf hintereinander-<br />
liegende Quell- und Zieloperanden zugreifen zu können. Dabei dienen DS: SI als Quell- und ES:DI als<br />
Zieladressregister.<br />
In Abhängigkeit vom D-Flag werden die Indexregister SI und DI nach jedem Befehl inkrementiert (D = 0) oder<br />
dekrementiert (D = 1 ). Bei Bytebefehlen (MOVSB) um 1 und bei Wortbefehlen (MOVSW ) um 2.<br />
Die Befehle werden oft innerhalb von Schleifen verwendet, da in der Regel nur dann das gleichzeitige, implizite<br />
Inkrementieren bzw Dekrementieren der Indexregister sinnvoll ist.<br />
LODSB / LODSW Lade AL / AX mit dem durch DS : SI adressierten Byte / Wort. SI auf nächste Adresse<br />
STOSB / STOSW Speichere AL / AX in das durch ES : DI adressierte Byte / Wort. DI auf nächste Adresse<br />
MOVSB / MOVSW Kopiert den Quellstring DS : SI auf den Zielstring ES : DI. SI und DI auf nächste Adresse<br />
CMPSB / CMPSW Vergleicht durch Subtraktion ( DS:SI ) – ( ES:DI ). Operanden werden nicht verändert<br />
SI und DI werden auf die nächste Adresse gesetzt<br />
SCASB / SCASW Testsubtraktion AL/AX – ( ES : DI ), nur Statusflags verändert, DI auf nächste Adresse<br />
Um String-Befehle innerhalb einer Schleife zu bearbeiten, ist ein Befehlspräfix (Repeat-Vorsatz) vorgesehen.<br />
REP ( STOS oder MOVS ) CX = CX – 1 wiederhole solange CX ≠ 0<br />
REPE / REPZ ( SCAS oder CMPS ) CX = CX – 1 wiederhole solange CX ≠ 0 und Z=1 ( Differenz = 0 )<br />
REPNE / REPNZ ( SCAS oder CMPS ) CX = CX – 1 wiederhole solange CX ≠ 0 und Z=0 (Differenz ≠ 0 )
Rechnergrundlagen Teil 2 - 24 - Prof. Dipl.-Ing. Komar<br />
7.2 Der M S-DOS Standardmonitor und Debugger DEBUG<br />
Kurzreferenz der wichtigsten DEBUG-Befehle<br />
Nach Aufruf meldet sich DEBUG mit einem " – " als Prompt und wartet auf die Eingabe von Ein -Buchstaben-<br />
Befehlen, evtl. gefolgt von Parametern. Der Befehl " q " beendet DEBUG und führt auf die Shellebene zurück.<br />
Aufruf: >DEBUG<br />
>DEBUG A:ASYP1 .COM (Einlesen der Datei ASYP1 .COM von Laufwerk A )<br />
Hex-Arithmetik: -H 3 2 (zeigt Summe und Differenz der jeweiligen Hexadezimalzahlen)<br />
-H 3D5C 2A10<br />
-H 5 FFFF<br />
Register anzeigen und ändern: -R (zeigt alle Register)<br />
-R AX (zeigt nur AX)<br />
-R IP (usw.)<br />
Speicherplätze ansehen und ändern: -E 100<br />
(nächste Speicherstelle: jeweils drücken; die Ausgabe des E-Kommandos sieht etwa so aus:<br />
25A6:100 00. Hinter dem " . " kann ein neuer Inhalt eingeben werden z.B. 25A6:0100 00.01 00.d8<br />
Single Step Modus (Trace): -T (Ausführung <strong>eines</strong> Befehls mit Anzeige aller<br />
Register)<br />
Programm ausführen (Go): -G (Programmausführung ab CS : IP )<br />
-G 1FE (Programmausführung bis incl. Adresse CS: 01FE)<br />
Programm ausführen (Proceed): -P (wie T, jedoch werden Unterprogramme wie ein Schritt behandelt)<br />
Programme eingeben (Assemble): -A 100 (nächster Assernblerbefehl: jeweils drücken, Ende: )<br />
Programm ausgeben (Unassemble): -U (16 Befehle ab IP)<br />
-U 200 (16 ab Adresse 200)<br />
-U 100 200 (Adr. 100 bis 200)<br />
Speicherinhalte ausgeben (Dump): -D (8 Zeilen ab IP)<br />
-D 200 (8 ab Adresse 200)<br />
-D 100 200 (Adr. 100 bis 200)<br />
Programme benennen (Name): -N WRITESTR.COM<br />
Programm auf Platte schreiben (Write): -W<br />
(unter Namen WRITESTR.COM, vorher Länge des Programms in Byte in das Registerpaar BX: CX schreiben)<br />
Programm laden ( Load ): -L<br />
(lädt das Programm, dessen Name mit dem Befehl N in den PSP-Kopf geschrieben wurde )<br />
DEBUG verlassen: - Q<br />
Groß- oder Kleinschreibung spielt keine Rolle! Alle Zahlenwerte sind hexadezimal !!!<br />
Beim Start stellt DEBUG ein volles 64 KByte-Segment zur Verfügung. Alle Segmentregister zeigen auf die<br />
gleiche Adresse. Das entspricht dem DOS-Speichermodell COM . Diese Einstellung nicht verändern.!!!<br />
Regel: Jedes DEBUG-Maschinenprogramm ( .COM-Modell ) muß bei der Offset-Adresse l00 h beginnen.<br />
DEBUG bietet die Startadresse 100 h standardmäßig an, indem es den Befehlszähler (IP) zu Beginn automatisch<br />
auf 100 setzt.
Rechnergrundlagen Teil 2 - 25 - Prof. Dipl.-Ing. Komar<br />
7.2.1 DEBUG-Beschreibung<br />
DEBUG wird, wie andere DOS-Kommandos auch, durch Eingabe des Namens aufgerufen:<br />
DEBUG <br />
oder<br />
DEBUG name.ext <br />
Im zweiten Fall wird der Name (ggf mit Pfadangabe und Erweiterung) des Programms eingegeben, das getestet<br />
werden soll. DEBUG meldet sich daraufhin mit einem Bindestrich ,,-,,. Dieser Strich bedeutet, daß DEBUG auf<br />
die Eingabe von Befehlen wartet. Alle DEBUG-Befehle bestehen aus einem Schlüsselbuchstaben und ggf<br />
Optionen. Die häufigsten und wichtigsten DEBUG-Befehle sind A(ssemble), D(ump) , E (nter), G(o), I (n),<br />
L (oad ), N (ame), O (ut), P(roceed) , Q(uit), R(egister), S(earch), T(race), U(nassemble) und W (rite) in<br />
alphabetischer Reihenfolge.<br />
Es ist zu beachten ist, daß alle Zahlen ausschließlich hexadezimal eingegeben werden müssen.<br />
Eine Eingabeoption, die nicht zwingend notwendig ist, wird in eckigen Klammern [ ] dargestellt, unbedingt<br />
notwendige Optionen werden in spitze Klammem < > gesetzt.<br />
Bei einem Eingabefehler erzeugt DEBUG eine Fehlermeldung mit einem Pfeil, der auf die Stelle des Fehlers<br />
zeigt. Für den Einsatz von DEBUG ist die Kenntnis der Adressierungsarten des 8086-Prozessors notwendig.<br />
A (ssemble) Befehl Dient zur Eingabe von Assemblerbefehlen<br />
Syntax: A [Adresse]<br />
Wird A ohne Option eingegeben, wird der folgende Assemblercode an der aktuellen Adresse CS:IP abgelegt. Als<br />
Option kann eine einzelne Offsetadresse eingegeben werden (dann wird als Segment CS vorausgesetzt) oder eine<br />
komplette Adresse bestehend aus Segment : Offset, wobei Segment ein Registername sein darf (CS, DS, ES oder<br />
SS) und Offset eine Hex-Zahl oder beides Hex-Zahlen. DEBUG zeigt anschließend die aktuelle Adresse für den<br />
nun einzugebenden Assemblerbefehl an und wartet auf die Eingabe.<br />
Beispiele für Aufruf:<br />
A<br />
A 100<br />
A DS:100<br />
A 1ffa:1234 allen Beispielen folgt dann die Eingabe von Maschinenbefehlen .<br />
Ausstieg aus A: durch statt einem weiterem Maschinenbefehl.<br />
Beispiel:<br />
–a l00<br />
10BB:0100 mov ax,ff00<br />
10BB:0103 mov [bx+12],cx<br />
10BB:0106<br />
–<br />
U (nassemble) Befehl Disassembliert einen Speicherbereich<br />
Syntax: U [Adresse] [Bereich]<br />
Ab der angegebenen Adresse versucht das Programm DEBUG den Code in Assembleranweisungen zurück zu<br />
übersetzen. Als Bereich kann z. B. u 100 200 angegeben werden.<br />
Beispiel:<br />
–u l00<br />
10BB:0100 B800FF MOV AX,FF00<br />
10BB:0103 894F12 MOV [BX+12],CX<br />
. . . .<br />
10BB:0106<br />
D (ump) Befehl Zeigt Speicherinhalte an<br />
Syntax: D [Adresse] [L Länge ]<br />
Gibt man D ohne Option ein, wird ein Speicherbereich beginnend mit der Offsetadresse 100h und der Segmentadresse,<br />
die bei Start von DEBUG vorlag, ausgegeben. Wird als Option nur eine Hex-Zahl übergeben, gibt<br />
DEBUG eine kleinen Speicherblock ab Adresse DS:Hex-Zahl aus. Weiterhin kann als Option eine komplette
Rechnergrundlagen Teil 2 - 26 - Prof. Dipl.-Ing. Komar<br />
Adresse bestehend aus Segment : Offset übergeben werden, wobei Segment ein Registername sein darf (CS, DS,<br />
ES oder SS) und Offset eine Hex-Zahl oder beides Hex-Zahlen. Die zweite Option ist eine Längenangabe, die<br />
festlegt, wieviele Bytes ausgegeben werden sollen. Die Angabe erfolgt durch ein ,,L“ gefolgt von einer Hex-<br />
Zahl. Diese Zahl darf nicht größer sein als ffff h abzüglich der aktuellen Offsetadresse. Nach Ausgabe einer<br />
kompletten Bildschirm- seite erfolgt keine Pause.<br />
Beispiele:<br />
D<br />
D 00ff<br />
D DS:100<br />
D 1cc2 :1234<br />
G (o) Befehl Führt ein Programm teilweise oder ganz aus und setzt Breakpoints<br />
Syntax: G [=Adresse] [Adr1] ... [Adr10 ]<br />
Das Kommando Go führt zur Ausführung des Programms ab der angegebenen Adresse. Werden keine<br />
optionalen Haltepunkte ( Adri ) angegeben, so läuft das Programm bis zum "Ende" (falls es terminiert).<br />
Das Debug-Programm streut dazu an den angegebenen Haltepunkten Unterbrechungsbefehle ein, welche beim<br />
Erreichen <strong>eines</strong> Haltepunktes oder beim Terminieren des Kommandos wieder entfernt werden. Beim Erreichen<br />
<strong>eines</strong> Haltepunktes wird jeweils die aktuelle Registerbelegung ausgegeben.<br />
Beispiel:<br />
–g = 100 106<br />
AX=0000 BX=0000 CX=0000 DX=0000 SP=FFEE BP=0000 SI=0000 DI=0000<br />
DS=1092 ES=1092 SS=1092 CS=1092 IP=0100 NV UP EI PL NZ NA PO NC<br />
1092:0106 52 PUSH DX<br />
–<br />
R (egister ) Befehl Zeigt Registerinhalte an und erlaubt deren Änderung<br />
Syntax: R [Registername]<br />
Wird kein Registername eingegeben, werden alle Prozessorregister angezeigt. Außerdem wird der Maschinen-<br />
befehl angezeigt, der an der Adresse CS:IP steht. Wird ein Registername übergeben, wird der aktuelle Inhalt,<br />
gefolgt von einem Doppelpunkt (in der nächsten Zeile ) angezeigt. Jetzt kann Return gedrückt werden – dann<br />
wird der aktuelle Wert beibehalten - oder ein 16-Bit -Hex-Wert ( 0-ffff h) eingegeben werden. Das Register wird<br />
dann auf diesen Wert gesetzt. Eine Sonderstellung nimmt hier das Flagregister ein. Es wird nicht, wie alle<br />
anderen Register, hexadezimal angezeigt. Allen Bits wird entsprechend ihres Inhaltes ( 0 oder 1) eine<br />
Kurzbezeichnung zugeordnet (siehe Tabelle). Der dem Zustand entsprechende Kurzname muß auch bei einer<br />
manuellen Änderung eingegeben werden (mehrere Namen werden durch Leerzeichen voneinander getrennt).<br />
Beispiele:<br />
R<br />
R CS<br />
R F<br />
Name in Abhängigkeit des Zustandes des Flagregisters F :<br />
Flagname gesetzt gelöscht<br />
-Overflow (yes / no) OV NV<br />
-Direction (decrement/increment) DN UP<br />
-Interrupt (enable/disable) EI DI<br />
-Sign (negative/positive) NG PL<br />
-Zero (yes / no) ZR NZ<br />
-Auxiliary carry (yes / no) AC NA<br />
-Parity (yes / no) PE PO<br />
-Carry (yes / no) CY NC
Rechnergrundlagen Teil 2 - 27 - Prof. Dipl.-Ing. Komar<br />
Beispiel:<br />
–r<br />
AX=0000 BX=0000 CX=0000 DX=0000 SP=FFEE BP=0000 SI=0000 DI=0000<br />
DS=1092 ES=1092 SS=1092 CS=1092 IP=0100 NV UP EI PL NZ NA PO NC<br />
1092:0100 B800FF MOV AX,FF00<br />
–<br />
Soll ein Registerinhalt auf einen bestimmten Wert gesetzt werden, so geschieht dies z.B. für den Stacksegment<br />
( Register SS ) auf 200 h wie folgt:<br />
–r ss<br />
SS 1092<br />
:0200<br />
–<br />
S (earch) Befehl Sucht nach einer Kombination bestimmter Bytes im Speicher<br />
Syntax: 1.S <br />
2.S <br />
In beiden Fällen kann Adresse eine einzelne Hex-ZahI sein, dann wird DS als Segmentanteil vorausgesetzt und<br />
die Zahl dient als Offsetadresse, außerdem kann eine komplette Adresse bestehend aus Segment : Offset<br />
eingegeben werden, wobei Segment ein Registername sein darf (CS, DS, ES oder SS) und Offset eine Hex-Zahl<br />
oder beides Hex-Zahlen. Bei der Liste handelt es sich um eine Ansammlung von 8-Bit -Hex-Zahlen (0-ff h),<br />
getrennt durch ein Leerzeichen, oder um ASCII-Zeichen, die dann in Hochkommata " " gesetzt werden<br />
müssen.<br />
zu Syntax 1:<br />
Die Länge des zu durchsuchenden Speicherbereiches wird durch ein ,,L“ gefolgt von einer 16-Bit-Hex-Zabl<br />
( 0-ffff h ) angegeben, wobei die Zahl nicht größer als ffff h minus der angegebenen Offsetadresse sein darf.<br />
Beispiele:<br />
S 100 L200 01 02<br />
S 100 L200 0a 12 "A" "B" "ABCD"<br />
S DS:200 L280 0f ff<br />
S 0lff:80 L700 0c 07<br />
zu Syntax 2:<br />
Der Bereich ist ein 16-Bit-Hex-Wert (0 – ffff h ), der die Offsetadresse kennzeichnet, bis zu der gesucht werden<br />
soll. Beispiele:<br />
S 100 180 01 02<br />
S 100 200 0a 12 "A" "B" "ABCD"<br />
S DS:200 280 0f ff<br />
S 01ff:80 700 0c 07<br />
T (race) Befehl Führt einen oder mehrere Maschinenbefehle im Einzelschrittmodus aus<br />
Syntax: T [=Adresse] [Anz]<br />
Das Trace-Kommando führt das Programm ab der angegebenen Adresse schrittweise aus und listet nach jedem<br />
Kommando den aktuellen Inhalt aller CPU-Register (analog dem R-Kommando). Weiterhin wird der nächste<br />
auszuführende Befehl disassembliert und analog dem U-Kommando angezeigt.<br />
Es werden so "Anz" Befehle ( Anz ist hexadezimal anzugeben!) nacheinander ausgeführt. Fehlt die Angabe<br />
"Anz", so wird genau ein Befehl ausgeführt. Fehlt die Adresse, so wird der nächste Befehl (auf den CS:IP zeigt)<br />
ausgeführt.<br />
Beispiel:<br />
–t=100 2<br />
AX=FF00 BX=0000 CX=0000 DX=0000 SP=FFEE BP=0000 SI=0000 DI=0000<br />
DS=1092 ES=1092 SS=1092 CS=1092 IP=0100 NV UP EI PL NZ NA PO NC<br />
1092:0103 894F12 MOV [BX+12],CX<br />
AX=0000 BX=0000 CX=0000 DX=0000 SP=FFEE BP=0000 SI=0000 DI=0000<br />
DS=1092 ES=1092 SS=1092 CS=1092 IP=0100 NV UP EI PL NZ NA PO NC<br />
1092:0106 52 PUSH DX
Rechnergrundlagen Teil 2 - 28 - Prof. Dipl.-Ing. Komar<br />
P (roceed) Befehl Bestimmte Programmsequenzen werden nicht im Einzelschrittmodus ausgeführt.<br />
Syntax: P [=Adresse] [Wert]<br />
Das Proceed-Kommando ist ähnlich wie das Trace-Kommando, jedoch wird ein Unterprogramm, eine Schleife,<br />
eine Interruptserviceroutine oder eine Stringoperation in einem Zug abgearbeitet und erst bei dem direkt darauf-<br />
folgenden Befehl wird angehalten.<br />
N (ame ) Befehl Setzt einen Dateinamen und bereitet Dateikontrollblöcke vor<br />
Syntax: N <br />
Dateiname muß ein nach den DOS-Regeln gültiger Name sein, der auch Laufwerk und Pfadnamen beinhalten<br />
darf.<br />
Der Name wird als ASCII-String an die Adresse CS : 80 h geschrieben, die Dateikontrollblöcke an den Adressen<br />
CS:5C und CS:6C werden vorbereitet. Alle Datei Ein- und Ausgaben beziehen sich jetzt auf den angegebenen<br />
Dateinamen ( z.B. beim W - Befehl )<br />
Beispiel:<br />
N hallo.com<br />
N c:\dos\utils \more\test.txt<br />
W (rite ) Befehl Schreiben in eine Datei<br />
Beschreibt eine Datei mit dem Namen, der an der aktuellen Code-Segmentadresse : 80h (CS:80h) als ASCII-<br />
Zeichenkette steht. Der Name kann z.B. durch den N(ame) Befehl eingegeben worden sein. Wird keine Adresse<br />
übergeben, wird die Datei beginnend mit dem Inhalt der Adresse CS: l00h beschrieben. Wird als Adresse nur<br />
eine Hex-Zahl übergeben, wird als Segmentadresse der Inhalt des DS-Registers vorausgesetxt. Weiterhin kann<br />
eine komplette Adresse bestehend aus Segment: Offset eingegeben werden, wobei Segment ein Registername<br />
sein darf (CS, DS, ES oder SS) und Offset eine Hex-Zahl oder beides Hex-Zahlen. Die Datei wird dann<br />
beginnend mit der angegeben Adresse beschrieben. Die Anzahl der geschriebenen Bytes muß in den Registern<br />
CX (niederwertiger Anteil) und BX (höherwertiger Anteil) hinterlegt sein.<br />
Beispiele:<br />
W<br />
W 100<br />
W ES:4500<br />
W abcd:1234<br />
Zusammenfassung der DEBUG-Befehle<br />
Befehl Semantik Format<br />
Assemble Assembleranweisungen umwandeln a [Adresse]<br />
Compare Speicherbereiche miteinander vergleichen c Bereich Adr<br />
Du mp Speicherinhalt anzeigen d [Adr] oder d [Bereich]<br />
Enter Speicherinhalt ändern / eingeben e Adr Liste<br />
Fill Speicherbereich mit Muster füllen f Bereich Muster<br />
Go Pgrammausführung mit evtl. Breakpoints g [=Adr][Adrl][Adr2]...<br />
Hexarithm. hexadez. Addition und Subtraktion h Wert Wert<br />
Input Byte von I/O-Adresse lesen i Portadresse<br />
Load Dateien oder abs. Diskettensektoren laden l [Adr [Laufw Sek. Sek.]]<br />
Move Speicherbereich übertragen m Bereich Adr<br />
Name Dateien und Parameter definieren n [d:] [Pfad]Name[.erw]<br />
Output Byte an I/O-Adresse senden o Portadresse Byte<br />
Proceed Stopp bei nächster Instruktion p [=Adr] [Wert]<br />
Quit DEBUG-Prog. verlassen, zurück zu DOS q<br />
Register Register abfragen / Wert zuweisen r [Reg]<br />
Search Suche nach Zeichen s Bereich Liste<br />
Trace Ausführung und Protokoll der Register t [=Adr] [Wert]<br />
Unassemble Code rückübersetzen in Assemb leranw. u [Adr] oder u [Bereich]<br />
Write Dateien oder abs. Diskettensek. schreiben w [Adr [Laufw Sek. Sek.]]<br />
Eine umfassendere Beschreibung der DEBUG-Befehle kann dem DOS-Manual entnommen werden
Rechnergrundlagen Teil 2 - 29 - Prof. Dipl.-Ing. Komar<br />
7.2.2 Arbeiten mit DOS-DEBUG<br />
Nach dem Aufruf des Programms meldet sich der Kommandointerpreter mit dem typischen Prompt-Zeichen “–“<br />
Das Debug-Programm kann mit dem Kommando q verlassen werden.<br />
Um direkt mit einem bereits vorhandenen File vom Typ name.com arbeiten zu können, welches anschließend<br />
auch durch den einfachen Aufruf unter DOS ausgeführt und getestet werden kann, ist es zweckmäßig, sich ein<br />
bereits verfügbares (funktionierendes) Programm bzw. File zunächst zu kopieren, um es dann mit dem<br />
Programm DEBUG nach eigenen Wünschen zu verändern.<br />
Das File more.com, welches ebenfalls als Standardprogramm zum Umfang von DOS dazugehört, eignet sich<br />
z.B. dazu wegen s<strong>eines</strong> geringen Umfangs besonders.<br />
Es wird z.B. per<br />
> copy c:\dos\more.com c:\test.com (oder copy c:\windows \command\more.com c:\test.com)<br />
kopiert und kann per<br />
> debug test.com bearbeitet werden.<br />
Hierzu ist es wichtig zu wissen, daß in COM-Files stets ab der Adresse CS:0100h der ausführbare<br />
Maschinencode abgelegt ist und das Programm beim Aufruf unter DOS stets beginnend mit dieser Adresse<br />
gestartet wird.<br />
Der Wert von CS (Codesegment-Zeiger) ist jeweils abhängig von der nächsten freien Adresse im Speicher des<br />
Rechners. Der Wert selbst ist unerheblich, da COM -Files stets kleiner als 64 KB sein müssen und sich darin<br />
Code-, Daten - und Stackbereich befinden müssen.<br />
Bevor man z.B. mit dem Befehl a 100 ab der Startadresse ein neues Programm (an der Stelle des alten)<br />
assembliert und im Speicher ablegt, kann man sich das ursprüngliche Programm (more) zunächst mit Hilfe des<br />
Befehls u 100 in disassemblierter Form ausgeben lassen.<br />
Hat man ein eigenes Programm in dieser Weise erstellt, so kann man es einfach per Kommando w innerhalb<br />
von DEBUG auf die Festplatte bzw. Floppy, von der es gelesen wurde, zurückschreiben, das Programm DEBUG<br />
mit dem Kommando q verlassen und das Programm test per Aufruf ausführen.<br />
Ein letzter Punkt, welcher hierbei beachtet werden muß, ist der, daß als letzte Befehle stets<br />
mov ah,4c und<br />
int 21 ausgeführt werden müssen.<br />
Dieser DOS-Systemaufruf stellt sicher, daß nach der Ausführung des "neuen" COM-Files korrekt zum<br />
Betriebssystem DOS zurückgekehrt wird.<br />
Programmerstellung per DOS-DEBUG<br />
Zur Beschaffung <strong>eines</strong> DOS-Files im COM -Format wird das File more.com, welches in seiner ursprünglichen<br />
Funktion die bildschirmweise Ausgabe <strong>eines</strong> Textfiles leistet, einfach kopiert. Das kopierte Programm mit dem<br />
Namen test.com wird anschließend derart verändert, daß es lediglich das Zeichen “ 0 “ auf dem Bildschirm<br />
ausgibt und anschließend zu DOS zurückkehrt.<br />
>copy more.com test.com Kopieren des Programmes more.com nach test.com<br />
>debug test.com Aufruf des Programmes debug.com mit dem<br />
Parameter test.com<br />
-u 100<br />
44B0:0100 E8B002 CALL 03B3 Hier steht der erste Maschinenbefehl, welcher<br />
44B0:0103 7307 JNB 010C beim Aufruf von more bzw. test ausgeführt<br />
44B0:0105 E8A603 CALL 04AE wird.<br />
. . .<br />
-a 100<br />
44B0: 0100 mov dl,30 Ab dieser Stelle werden einfach neue Befehle<br />
44B0: 0102 mov ah,2 abgelegt und später per write-Kommando in<br />
44B0: 0104 int 21 das File test zurückgeschrieben.<br />
44B0 :0106 mov ah,4c<br />
44B0 :0108 int 21<br />
44B0: 010a
Rechnergrundlagen Teil 2 - 30 - Prof. Dipl.-Ing. Komar<br />
-w<br />
00A58 Byte werden geschrieben<br />
-q<br />
>test Aufruf des Programmes test.com unter DOS<br />
0 Ausgabe einer 0 von test.com<br />
> DOS wartet auf die nächste Eingabe<br />
Beispiel für typische DEBUG-Sitzungen<br />
Nachfolgend wird ein weiteres Beispiel vorgeführt, das den Umgang mit DEBUG verdeutlichen soll.<br />
Es wird ein kurzes Maschinensprache - Programm erzeugt und schrittweise ausgeführt und verändert.<br />
Start von DEBUG aus der DOS-Kommandoebene mit<br />
DEBUG <br />
Nachfolgende Befehle sind, jeweils gefolgt von der Enter-Taste, einzugeben:<br />
A 100<br />
MOV AH,09<br />
MOV DX,010b<br />
INT 21<br />
MOV AH, 4C<br />
INT 21<br />
<br />
E 0l0B 0D 0A “ Hallo Assembler !“ 0D 0A “$“<br />
N hallo.com<br />
R CX<br />
21<br />
W CS: l00<br />
Q<br />
Diese Anweisungen erzeugen ein lauffähiges Programm direkt in Maschinensprache. Anschließend wird es unter<br />
dem Namen ,,HALLO . COM“ in das Arbeitsverzeichnis des aktuellen Datenträgers geschrieben. Führen Sie es<br />
durch Eingabe von HALLO einmal aus! Die Aufgabe soll nun darin bestehen, das Wort „Assembler“ durch<br />
Ihren Namen zu ersetzen. Nehmen Sie dazu das Programm in DEBUG auf:<br />
DEBUG HALLO.COM<br />
Hinweis: Eine COM-Datei wird immer an die Adresse CS: 100 geladen. Lassen Sie sich nun 2lh Speicherplätze<br />
ab CS:100 anzeigen:<br />
Eingabe:<br />
D CS:100 L21<br />
Ausgabe:<br />
135B: 0100 B4 09 BA 0B 01 CD 21 B4 – 4C CD 21 0D 0A 48 61 6C . . . . . . ! . L .! . . Hal<br />
135B: 0110 6C 6F 20 41 73 73 65 6D – 62 6C 65 72 20 21 0D 0A lo Assembler ! . .<br />
135B:0120 24 $<br />
–<br />
Sie erkennen ganz rechts am Bildschirm den Satz ,,Hallo Assembler !,, wieder, zusammen mit einigen ,,wilden"<br />
Zusatzzeichen. In der Mitte werden die Inhalte der 21 h Speicherstellen hexadezimal dargestellt. Ganz links stehen<br />
die Speicheradressen. Zunächst geht es darum, die Adresse des Buchstaben ,,A“ aus dem Wort „Assembler“<br />
ausfindig zu machen. Dazu müssen Sie abzählen, um wieviele Bytes das „ A“ hinter der angegebenen Adresse in<br />
der zweiten Zeile (= 135B:0110 ) steht. Die Zählung muß bei Null beginnen! Addieren Sie dann diese Zahl zum<br />
Offsetanteil (der nach dem Doppelpunkt) der angegebenen Adresse und merken Sie sich diese. Wenn Sie richtig<br />
gezählt haben, müßten Sie zu der Zahl 3 gekommen sein:<br />
110 (hex)+ 3 (hex)= 113 (hex)
Rechnergrundlagen Teil 2 - 31 - Prof. Dipl.-Ing. Komar<br />
Disassemblieren Sie das Programm<br />
Eingabe:<br />
U CS:100 121<br />
Ausgabe:<br />
135B: 0100 B409 MOV AH, 09<br />
135B: 0102 BA0B01 MOV DX, 010B<br />
135B: 0105 CD21 INT 21<br />
135B: 0107 B44C MOV AH, 4C<br />
135B: 0109 CD21 INT 21<br />
135B: 010B 0D0A48 OR AX, 480A<br />
135B: 010E 61 DB 61<br />
135B: 010F 6C DB 6C<br />
135B: 0110 6C DB 6C<br />
135B: 0111 6F DB 6F<br />
135B: 0112 204173 AND [BX+DI+73] ,AL<br />
135B: 0115 7365 JNB 017C<br />
135B: 0117 6D DB 6D<br />
135B: 0118 62 DB 62<br />
135B: 0119 6C DB 6C<br />
135B: 011A 65 DB 65<br />
135B: 011B 7220 JB 013D<br />
135B: 011D 210D AND [DI] ,CX<br />
135B: 011F 0A24 OR AH, [SIl<br />
135B: 0121 6F DB 6F<br />
–<br />
Sicher erkennen Sie die zuvor eingegebenen Befehle wieder. Vor jedem Befehl steht die jeweilige<br />
Speicheradresse. Da nach dem zweiten ,,int 21“ keine weiteren Befehle sondern der Text ,,Hallo Assembler !,,<br />
abgelegt ist, werden wirre Maschinenbefehle angezeigt. DEBUG versucht hier, die Bytes des Textes als<br />
Maschinencode zu interpretieren.<br />
Nun geben Sie Ihren Namen, gefolgt von den Bytes 0d 0a und ,,$“ (Zeilenvorschub und Textendezeichen) an<br />
der ermittelten Adresse ein:<br />
E CS:113 "MeinName !" 0d 0a "$"<br />
Da Ihr Name vermutlich nicht genau der Länge des Wortes „ Assembler“ entspricht, mu ß jetzt die Länge für die<br />
Datei abgeändert werden. Lassen Sie sich den Speicherinhalt noch einmal anzeigen:<br />
Eingabe:<br />
D CS:100<br />
Ausgabe:<br />
135B:0100 B4 09 BA 0B 01 CD 21 B4 - 4C CD 21 0D 0A 48 61 6C . . . . . . . ! .L.!..Hal<br />
135B:0110 6C 6F 20 4D 65 69 6E 4E – 61 6D 65 20 21 0D 0A 24 10 MeinName . . $<br />
135B:0120 24 6F 72 2C 20 77 65 6E - 6E 20 64 69 65 0D 0A 20 $or, wenn die . .<br />
135B:0130 20 20 20 20 20 20 20 20 – 20 20 20 20 20 20 20 20<br />
135B:0140 20 20 20 20 20 20 20 20 - 20 20 20 20 20 20 20 20<br />
1358:0150 20 61 6E 67 65 67 65 62 - 65 6E 65 20 44 61 74 65 angegebene Date<br />
1358:0160 69 20 76 6F 72 68 61 6E – 64 65 6E 20 69 73 74 2E i vorhanden ist.<br />
135B:0170 0D 0A 00 44 65 6E 20 42 - 65 66 65 68 6C 20 46 4F . . . Den Befehl FO<br />
–<br />
Jetzt wird, da keine Begrenzung eingegeben wurde, ein zu großer Speicherbereich angezeigt. Um die Datei abzuspeichern,<br />
muß zuerst die Anzahl der zu speichernden Bytes ermittelt werden. Zählen Sie dazu die Anzahl der<br />
Bytes beginnend bei CS:l00 bis zu dem Dollarzeichen. Es sind 32 Bytes dezimal, das entspricht der Zahl 20<br />
hexadezimal. Nun geben Sie der Datei einen neuen Namen:<br />
N HALLONEU.COM<br />
Dann schreiben Sie die Anzahl der ermittelten Bytes in das BX- CX-Registerpaar:<br />
R BX<br />
0<br />
R CX<br />
20
Rechnergrundlagen Teil 2 - 32 - Prof. Dipl.-Ing. Komar<br />
und anschließend die Datei auf Datenträger:<br />
W<br />
Jetzt testen Sie das Programm im Einzelschrittmodus aus, indem Sie zunächst ,,R ,,eingeben. Alle<br />
Registerinhalte werden angezeigt gefolgt vom Maschinenbefehl, der an der Adresse CS:IP steht. Führen Sie<br />
diesen und den nächsten Befehl aus:<br />
Eingabe:<br />
R<br />
Ausgabe:<br />
AX=0000 BX=0000 CX=0020 DX=0000 SP=FFFE BP=0000 SI= 0000 DI=0000<br />
DS =135B ES=135B SS=135B CS=135B IP=0100 NV UP EI PL NZ NA PO NC<br />
135B:0100 B409 MOV AH,09<br />
–<br />
Eingabe:<br />
T<br />
Ausgabe:<br />
AX=0900 BX=0000 CX=0020 DX=0000 SP=FFFE BP=0000 SI=0000 DI=0000<br />
DS=135B ES=135B SS=135B CS=135B IP=0102 NV UP EI PL NZ NA PO NC<br />
135B:0102 BA0B01 MOV DX,010B<br />
–<br />
Eingabe:<br />
T<br />
Ausgabe:<br />
AX=0900 BX=0000 CX=0020 DX=010B SP=FFFE BP=0000 SI=0000 DI=0000<br />
DS=135B ES=135B SS=135B CS=135B IP=0105 NV UP EI PL NZ NA PO NC<br />
135B:0105 CD21 INT 21<br />
–<br />
Nun folgt der ,,int 21“ Befehl. Hierbei handelt es sich um den Aufruf <strong>eines</strong> kompletten Unterprogramms, das von<br />
DOS zur Verfügung gestellt wird (DOS-Systemaufruf per Softwareinterrupt). Es soll den Text ausgeben. Führen<br />
Sie dieses Unterprogramm,,auf einen Schlag“ aus (da sein Inhalt nicht interessiert ) :<br />
Eingabe:<br />
P<br />
Ausgabe:<br />
Hallo MeinName !<br />
AX=0900 BX=0000 CX=0020 DX=010B SP=FFFE BP=0000 SI=0000 DI=0000<br />
DS=135B ES=135B SS=135B CS=135B IP=0107 NV UP EI PL NZ NA PO NC<br />
135B:0107 B44C MOV AH, 4C<br />
Wenn Sie richtig gearbeitet haben, hat Sie Ihr Rechner soeben namentlich begrüßt. Sie sollten nun noch die<br />
letzten beiden Befehle ausführen:<br />
Eingabe:<br />
T<br />
Ausgabe:<br />
AX=4C00 BX=0000 CX=0020 DX=010B SP=FFFE BP=0000 SI=0000 DI=0000<br />
DS=135B ES=135B SS=135B CS=135B IP=0109 NV UP EI PL NZ NA PO NC<br />
135B:0109 CD21 INT 21<br />
Eingabe:<br />
P<br />
Ausgabe:<br />
–<br />
Die Verarbeitung des Programms ist damit abgeschlossen. Sie können nun DEBUG beenden:<br />
Eingabe:<br />
Q<br />
Sie können Ihr Programm von jetzt an auch von der Kommandoebene aus starten ( Eingabe: HALLONEU ).
Rechnergrundlagen Teil 2 - 33 - Prof. Dipl.-Ing. Komar<br />
7.2.3 DEBUG - Assemblierung aus einer Textdatei<br />
Die direkte Eingabe von Assemblerbefehlen in DEBUG ist nur für kurze Programmtests handhabbar.<br />
Komfortabler ist es, die Quelltexte ( als ASCII-Datei !!! ) mit einem Texteditor (z.B. DOS - EDIT ) zu<br />
erstellen und aus einer Quelldatei in einem DEBUG-Durchlauf zu übersetzen.<br />
In der Quelldatei müssen die steuernden DEBUG-Anweisungen neben den Assemblerbefehlen so enthalten sein,<br />
als würde man direkt in DEBUG arbeiten.<br />
Dann wird der Debugger unter Verwendung der DOS–I/O–Umleitung gestartet. Und zwar wird die Eingabe für<br />
DEBUG von der Tastatur auf die Quelldatei umgeleitet und die von DEBUG erzeugte Text -Ausgabe wird nicht<br />
auf den Bildschirm sondern in eine Ausgabedatei geschrieben.<br />
> DEBUG < VERSION.ASM > VERSION.LST<br />
VERSION.ASM steht für die Quelldatei, während in VERSION.LST alle Meldungen während der Assem -<br />
blierung gespeichert werden. Damit liest DEBUG die Eingaben nicht mehr von der Tastatur, sondern aus der<br />
Datei VERSION.ASM. Die Textausgaben werden in die zweite Datei (VERSION.LST) umgeleitet.<br />
Interessant ist in diesem Zusammenhang noch eine undokumentierte Eigenschaft von DEBUG. Normalerweise<br />
lassen sich in DEBUG keine Kommentare eingeben. Ist jedoch der ASSEMBLE-Befehl aktiv, akzeptiert<br />
DEBUG Kommentarzeilen. Alle Texte mit einem vorangestellten Semikolon werden als Kommentar betrachtet<br />
und überlesen. Lediglich bei DB- und DW-Anweisungen erfolgt eine Fehlermeldung, so daß DEBUG hier keine<br />
Kommentare akzeptiert.<br />
Im folgenden Programmbeispiel bewirkt die erste " A CS:100" Anweisung, daß DEBUG den hinter Semikolons<br />
erzeugten Kommentarkopf überliest.<br />
Die Daten werden in den Bereich ab CS:200 assembliert. Dies geschieht im Beispiel durch die ORG–Anwei –<br />
sungen (ORG = Origin ) hinter deren Offset-Adresse die jeweiligen Textstrings im ASCII-Code plaziert werden.<br />
Um den DEBUG-Assembliermodus zu verlassen, muß eine Leerzeile eingegeben werden, damit deren RETURN<br />
- Zeichen das aktive A-Kommando abbricht<br />
Wichtig ist daher auch, daß in einem Block mit Assembleranweisungen keine Leerzeilen auftreten, da diese<br />
auch den ASSEMBLE-Mode beenden.<br />
Mit der W - Anweisung lassen sich 200h Byte ab CS: 100 speichern. Die Sequenz:<br />
N name.COM<br />
R BX<br />
0 ??????<br />
R CX<br />
200 ??????<br />
W<br />
Q<br />
ist deshalb in jedem Quellprogramm, getrennt durch eine Leerzeile, an den Assemblercode anzuhängen.<br />
Eine Debug-Assemblierung aus einer Textdatei könnte bei Verwendung des DOS-Editors EDIT folgenden<br />
Ablauf haben.<br />
> edit VERSION.ASM ; Erstellen der Textdatei in EDIT<br />
> debug VERSION.LST ; DEBUG-Aufruf mit Umleitungen<br />
> more VERSION.LST ; Listing am Bildschirm ansehen ( Fehler u. Adressen )<br />
> debug VERSION.COM ; in DEBUG testen oder mit G starten<br />
> VERSION ; fehlerfreies Programm von Kommandoebene aufrufen<br />
Mit mehrmaligem Durchläufen von edit–debug–more–edit... lassen sich die Fehler beseitigen und vor allem<br />
die tatsächlichen absoluten Adressen einfach ermitteln ( denn symbolische Adressierung mit Labeln ist im<br />
DEBUG-Assembler nicht möglich ).<br />
Dazu setzt man Schätzwerte in die benötigten Adresswerte der Sprungbefehle oder Unterprogrammaufrufe und<br />
startet den ersten DEBUG-Assemblierlauf, sucht mit dem more-Befehl aus der name.LST - Datei die<br />
tasächlichen Adressen, fügt mit dem Editor edit diese Adressen in der Quelltextdatei name.ASM ein und startet<br />
einen erneuten DEBUG-Assemblierlauf.
Rechnergrundlagen Teil 2 - 34 - Prof. Dipl.-Ing. Komar<br />
Nachfolgendes Beispiel erzeugt eine lauffähige COM -Datei zur Abfrage der DOS-Versionsnummer.<br />
A CS:100<br />
;__________________________________________________________<br />
; Beispiel zur Assemblierung mit dem DOS-Debugger aus einer Textdatei.<br />
; Aufruf: DEBUG < VERSION.ASM > VERSION.LST<br />
; In der Datei VERSION.LST werden alle Meldungen (auch Fehlermeldungen) des Debuggers abgelegt.<br />
; Die lauffähige COM-Datei findet sich in VERSION .COM<br />
;___________________________________________________________<br />
; Assembliere den Programmcode ab CS:100<br />
ORG 100 ;diese Assembleranweisung ist hier eigentlich überflüssig<br />
; durch A CS:100<br />
MOV DX, 0200 ; lade Adresse String 1<br />
MOV AH, 09 ; Ausgabe des Textes<br />
INT 21 ; per INT 21<br />
;<br />
MOV AH, 30 ; Abfrage der DOS-Version<br />
INT 21 ;<br />
;<br />
PUSH AX ; Zwischenspeichern auf dem Stapel<br />
;<br />
MOV DL, 30 ; Convert Main Nr.<br />
ADD DL,AL ;<br />
MOV AH, 02 ; Ausgabe Character<br />
INT 21 ;<br />
;<br />
MOV DL, 2E ; write “.“<br />
INT 21 ;<br />
;<br />
POP AX ; vom Stapel zurückholen<br />
;<br />
MOV AL,AH ; untergeordnete Versionsnummer<br />
MOV AH, 0 ;in ungepackte BCD-Ziffer in AH wandeln<br />
AAM<br />
MOV DL, 30 ; Convert Second Nr.<br />
ADD DL,AH ;<br />
MOV AH, 02<br />
INT 21 ; write char.<br />
;<br />
MOV DX, 0220 ; lade Adr. String 2<br />
MOV AH, 09 ; Ausgabe CR, LF<br />
INT 21 ; per INT 21<br />
;<br />
MOV AX, 4C00 ; Terminate Process normal<br />
INT 21 ; Programmbeendigung und Rückkehr nach DOS<br />
; ; Ende des Programmcodes<br />
ORG 200 ; Assembliere die Text-Konstanten ab CS:200, diese Anweisung erzeugt keinen Maschinencode<br />
DB "MS -DOS Version $"<br />
ORG 220 ; mit CR (Carriage Return = 0D h ) und LF (Line Feed = 0A h ) wird der Cursor auf den<br />
DB 0A, 0D,"$" ; Anfang der nächsten Zeile positioniert<br />
; speichere den Code in der Datei VERSION.COM mit den Debug-Befehlen N(ame) und W(rite)<br />
; hier muß eine Leerzeile folgen !!! damit der Debug-Assembler-Mode beendet wird<br />
N VERSION.COM<br />
R BX<br />
0<br />
R CX<br />
200<br />
W CS:100<br />
Q<br />
Listing : VERSION.ASM
Rechnergrundlagen Teil 2 - 35 - Prof. Dipl.-Ing. Komar<br />
7.3 Schnittstellen zum Betriebssystem<br />
Neben den vielen Hilfsprogrammen für die Softwareentwicklung bietet ein Betriebssystem insbesondere<br />
einen einfachen Zugang zu den Standarddiensten wie Tastatureingabe, Bildschirmausgabe, Disketten – und<br />
Festplattenzugriffe, serielle Schnittstelle, Drucker usw.<br />
Dem Anwender wird durch Systemaufrufe ( sogn. Softwareinterrupts im PC ) der Zugriff auf die peripheren<br />
Komponenten drastisch erleichtert, denn er muß diese Zugriffe nicht mehr selbst programmieren.<br />
Mit BIOS (Basic Input Output System) wird eine Gruppe von Programmen bezeichnet, die die Kontrolle beim<br />
Einschalten des PCs ( Kaltstart ) übernimmt und eine Programmsammlung zum elementaren Ansprechen der<br />
Peripherie ( Treiber ) enthält.<br />
Über das BIOS, das direkt auf der Hardware aufsetzt, wird die sogn. IBM-Kompatibilität aller PC gewähr -<br />
leistet, in dem mit dem BIOS für die unterschiedliche Hardware der verschiedenen Hersteller eine einheitliche<br />
Software -Schnittstelle in Form der BIOS-Funktionen (BIOS-Interrupts ) zur Verfügung gestellt wird.<br />
Greift der Anwender nur über die vorgegebenen BIOS-Aufrufe auf die Hardware zu, so bleiben die Hardware-<br />
Unterschiede der verschiedenen Hersteller verdeckt und das Programm sollte auf allen PC fehlerfrei laufen.<br />
Die meisten BIOS-Programme befinden sich auf einem Festwertspeicher (EPROM) und <strong>eines</strong> der Programme<br />
übernimmt nach einem RESET und Einsprung bei Adresse FFFF0 h die Kontrolle beim Hochfahren (Booten).<br />
DOS ( Disk Operating System ) dagegen wird erst im Laufe des Systemstarts von Diskette oder Festplatte<br />
geladen und ist mit den DOS-Funktionen der DOS-Interrupts ( DOS-API ) für "höhere" bzw hardwarefernere<br />
Systemaufgaben zuständig, wobei es aber seine sogn "logischen " Zugriffe mit den BIOS-Funktionen<br />
durchführt.<br />
Die Direktzugriffe auf die Hardware über I/O-Ports sind zwar erheblich schneller als die BIOS- oder DOS –<br />
Funktionen, sie bergen aber die Gefahr der Inkompatibilität, wenn das Programm auf dem Rechner <strong>eines</strong> anderen<br />
Herstellers laufen soll.<br />
Anwender<br />
Befehlsinterpreter (COMMAND.COM) Anwenderprogramme<br />
DOS Systemaufrufe<br />
logischer , hardwareferner Zugriff (z.B. INT 21h)<br />
BIOS<br />
physikalischer Zugriff auf Hardware<br />
Register Speicheradressen Portadressen<br />
Hardware<br />
Prozessor Speicher Peripherie<br />
IBM- Kompatibilität<br />
Direkt- Zugriff<br />
Programmbeispiel:<br />
Eine Tasten-Betätigung der Tastatur soll den Code ( ASCII ) des entsprechenden Zeichens einlesen.<br />
Wenn die Taste " ESC " gedrückt wurde, soll das Programm beendet und in das Betriebssystem DOS<br />
zurückgekehrt werden.<br />
Anderenfalls soll das Zeichen auf die augenblickliche Cursor-Position des Bildschirms ausgegeben werden.<br />
Die beiden vorgestellten Lösungsalternativen mit DOS- und BIOS-Funktionen zeigen als entscheidenden<br />
Nachteil des DEBUG-Assembler, daß die Adressen nicht symbolisch festgelegt werden können sondern<br />
vom Programmierer manuell ermittelt werden müssen.
Rechnergrundlagen Teil 2 - 36 - Prof. Dipl.-Ing. Komar<br />
DOS-Funktionen in BIOS-Funktionen in<br />
DEBUG-Assembler-Syntax symbolischer Assembler-Syntax<br />
ORG 100 ;Offset-Adresse d.Beginns ORG 100 h<br />
MOV AH, 07 LOOP: MOV AH, 00<br />
INT 21 ;v.Tastatur einlesen INT 16 h<br />
CMP AL, 1B ;vergleichen "ESC" CMP AL, 1B h<br />
JE 110 ;und springen JZ BEENDEN<br />
MOV DL, AL MOV AH, 0E h<br />
MOV AH, 02 ;Bildschirmausgabe INT 10 h<br />
INT 21 JMP LOOP<br />
JMP 100 BEENDEN: MOV AH, 4C h<br />
MOV AX, 4C00 ;progr. beenden und INT 21 h<br />
INT 21 ;nach DOS zurück END<br />
7.3.1 DOS-Application-Program-Interface<br />
Zu den DOS-Interrupts zählen d ie Interrupt-Nr.: 20 h – 2F h . Der wichtigste ist der INT 21 h – Aufruf einer DOS-<br />
Funktion<br />
Über den Interrupt 21h können mehr als 100 Funktionen erreicht werden, die das DOS einem Programm zur Verfügung stellt<br />
und die deshalb als Application-Program-Interface (DOS-API) bezeichnet werden.<br />
Übersicht der Funktionen des Interrupts 21h soweit in diesem Skript beschrieben<br />
Zeicheneingabe<br />
01h Zeicheneingabe mit Ausgabe<br />
03h Empfang <strong>eines</strong> Zeichens von der seriellen Schnittstelle<br />
06h Direkte Zeichenein-/-ausgabe<br />
07h Direkte Zeicheneingabe ohne Ausgabe<br />
08h Zeicheneingabe ohne Ausgabe<br />
0Ah Eingabe einer Zeichenkette<br />
0Bh Lese Eingabestatus<br />
0Ch Lösche Eingabepuffer und rufe Eingabefunktion auf<br />
Zeichenausgabe<br />
02h Ausgabe <strong>eines</strong> Zeichens<br />
04h Ausgabe <strong>eines</strong> Zeichens auf die serielle Schnittstelle<br />
05h Ausgabe auf parallele Schnittstelle<br />
06h Direkte Zeichenein-/-ausgabe<br />
09h Ausgabe einer Zeichenkette<br />
Programmbeendigung<br />
00h Programm beenden<br />
31h Programm beenden, aber im Speicher belassen<br />
4Ch Programm mit Ende-Code beenden<br />
Interrupt-Behandlung<br />
25h Setze Interrupt-Vektor<br />
35h Inhalt <strong>eines</strong> Interrupt-Vektors auslesen<br />
Uhrzeit und Datum<br />
2Ah Datum abfragen<br />
2Bh Datum setzen<br />
2Ch Uhrzeit abfragen<br />
2Dh Uhrzeit setzen
Rechnergrundlagen Teil 2 - 37 - Prof. Dipl.-Ing. Komar<br />
Interrupt 21h, Funktion 01h Zeicheneingabe mit Ausgabe<br />
Ein Zeichen wird vom Standard -Eingabegerät ausgelesen und auf dem Standard -Ausgabegerät ausgegeben. Steht zum<br />
Zeitpunkt des Funktionsaufrufs noch kein Zeichen bereit, wartet die Funkt ion, bis ein Zeichen verfügbar wird. Da die<br />
Standard -Ein - und -Ausgabe umgeleitet werden kann, liest die Funktion nicht unbedingt ein Zeichen von der Tastatur aus ein<br />
und gibt es auf dem Bildschirm aus, vielmehr können die eingelesenen Zeichen auch von einem anderen Gerät oder aus einer<br />
Datei stammen. In diesem Fall wird jedoch bei Erreichen des Datei-Endes die Eingabe nicht wieder auf die Tastatur<br />
umgeleitet, so daß die Funktion weiterhin versucht, Zeichen aus der Datei zu lesen, was jedoch nicht möglich ist.<br />
Eingabe AH = 01h<br />
Ausgabe AL = Eingelesenes Zeichen<br />
Werden erweiterte Tastatur-Codes eingelesen, wird zunächst der Code 0 im AL-Register zurückgeliefert. Die Funktion muß<br />
dann erneut aufgerufen werden, um den eigentlichen Code zu lesen.<br />
Wenn das eingelesene Zeichen das Zeichen Control-C (ASCII-Code 3) ist, wird der Interrupt 23h aufgerufen und dies führt<br />
zur Beendigung des Programms.<br />
Der Inhalt der Register AH, BX, CX, DX, SI, DI, BP, CS, DS, SS, ES und des Flag-Registers wird durch diese Funktion<br />
nicht verändert.<br />
Interrupt 21h, Funktion 02h Ausgabe <strong>eines</strong> Zeichens<br />
Durch Aufruf dieser Funktion wird ein Zeichen auf dem Standard -Ausgabegerät ausgegeben. Da dieses Gerät umgeleitet<br />
werden kann, muß das Zeichen nicht unbedingt auf dem Bildschirm ausgegeben, sondern kann auch an ein anderes Gerät<br />
oder an eine Datei gesandt werden. Wenn allerdings das Medium (Diskette, Festplatte), auf dem sich die Datei befindet,<br />
bereits voll ist, wird das von der Funktion nicht erkannt und weiterhin versucht, Zeichen in diese Datei zu schreiben.<br />
Eingabe AH = 02h<br />
DL = Code des auszugebenden Zeichens<br />
Ausgabe keine<br />
Sofern die Zeichen an den Bildschirm gesandt werden, werden die Steuercodes wie Backspace, Carriage Return und Line<br />
Feed als solche behandelt. Wird die Ausgabe hingegen in eine Datei umgeleitet, werden sie dort als ganz normale ASCII-<br />
Codes gespeichert.<br />
Nach der Ausgabe des Zeichens testet DOS, ob in der Zwischenzeit ein Control-C-Zeichen (ASCII-Code 3) empfangen bzw.<br />
eingegeben wurde. In diesem Fall wird der Interrupt 23h aufgerufen.<br />
Der Inhalt von AL wird verändert.<br />
Interrupt 21h, Funktion 03h Empfang <strong>eines</strong> Zeichens von der seriellen Schnittstelle<br />
Durch Aufruf dieser Funktion wird ein Zeichen von der seriellen Schnittstelle eingelesen. Dabei wird auf das Gerät mit der<br />
Bezeichnung AUX bzw. COM1 zugegriffen.<br />
Eingabe AH = 03h<br />
Ausgabe AL = Empfangenes Zeichen<br />
Kehrt erst zum aufrufenden Programm zurück, nachdem ein Zeichen empfangen wurde !!!<br />
Da die serielle Schnittstelle über keinen internen Puffer verfügt, kann es sein, daß sie schneller Zeichen empfängt, als durch<br />
den Aufruf dieser Funktion ausgelesen werden können. Diese Zeichen gehen dann verloren.<br />
Die Kommunikationsparameter (Baud-Rate, Anzahl der Stop-Bits etc.) müssen zuvor über den MODE-Befehl eingestellt<br />
werden. DOS gibt sonst als Default-Werte eine Baud-Rate von 2400 bei einem Stop-Bit ohne Paritätsprüfung und einer<br />
Datenlänge von 8 Bits vor. (z.B. < MODE com1: 96,n,8,1 -> COM1 auf 9600 Bd, keine Parität, 8 Datenbit, 1 Stopbit )<br />
Anstelle dieser Funktion sollte besser auf die Funktionen des BIOS zum Zugriff auf die serielle Schnittstelle zurückgegriffen<br />
werden. Sie sind über den Interrupt 14h aufrufbar und bieten eine größere Flexibilität als die DOS-Funktionen, zumal mit<br />
ihrer Hilfe auch der Status der seriellen Schnittstelle abgefragt werden kann.<br />
Wird ein Control-C-Zeichen (ASCII-Code 3) empfangen, wird der Interrupt 23h aufgerufen.<br />
Der Inhalt der Register AH, BX, CX, DX, SI, DI, BP, CS, DS, SS, ES und des Flag-Registers wird durch diese Funktion<br />
nicht verändert.<br />
Interrupt 21h, Funktion 04h Ausgabe <strong>eines</strong> Zeichens auf die serielle Schnittstelle<br />
Durch Aufruf dieser Funktion wird ein Zeichen auf die serielle Schnittstelle ausgegeben. Dabei wird auf das Gerät mit der<br />
Bezeichnung AUX bzw. COM1 zugegriffen.<br />
Eingabe AH = 04h<br />
DL = Auszugebendes Zeichen<br />
Ausgabe keine<br />
Das Zeichen wird erst ausgegeben, wenn das Gerät, das das Zeichen empfangen soll, signalisiert, daß es zum Empfang bereit<br />
ist. Erst danach wird die Kontrolle an das aufrufende Programm zurückgegeben.!!!
Rechnergrundlagen Teil 2 - 38 - Prof. Dipl.-Ing. Komar<br />
Die Kommunikationsparameter (Baud-Rate, Anzahl der Stop-Bits etc.) müssen zuvor über den MODE-Befehl eingestellt<br />
werden. DOS gibt sonst als Default-Werte eine Baud-Rate von 2400 bei einem Stop-Bit ohne Paritätsprüfung und einer<br />
Datenlänge von 8 Bits vor.<br />
Anstelle dieser Funktion sollte besser auf die Funktionen des BIOS zum Zugriff auf die serielle Schnittstelle zurückgegriffen<br />
werden. Sie sind über den Interrupt 14h aufrufbar und bieten eine größere Flexibilität als die DOS-Funktionen, zumal mit<br />
ihrer Hilfe auch der Status der seriellen Schnittstelle abgefragt werden kann.<br />
Wird ein Control-C-Zeichen (ASCII-Code 3) ausgegeben, wird der Interrupt 23h aufgerufen.<br />
Der Inhalt der Prozessor-Register wird durch diese Funktion nicht verändert. Dies gilt auch für das Flag-Register.<br />
Interrupt 21h, Funktion 05h Ausgabe auf parallele Schnittstelle<br />
Mit Hilfe dieser Funktion wird ein Zeichen an die parallele Schnittstelle gesandt, wodurch es in der Regel an einen<br />
angeschlossenen Drucker geleitet wird. Sofern nicht durch den MODE-Befehl umgeleitet, wird dabei das Gerät mit der<br />
Bezeichnung LPT1: (identisch mit PRN:) angesprochen.<br />
Eingabe AH = 05h<br />
DL = Code des auzugebenden Zeichens<br />
Ausgabe keine<br />
Das Zeichen wird erst ausgegeben, wenn das Gerät an der parallelen Schnittstelle Empfangsbereitschaft signalisiert. Danach<br />
wird die Kontrolle an das aufrufende Programm zurückgegeben.<br />
Wird ein Control-C-Zeichen (ASCII-Code 3) entdeckt, wird der Interrupt 23h aufgerufen.<br />
Größere Flexibilität bei der Ausgabe von Zeichen auf die parallele Schnittstelle bieten die BIOS-Funktionen, die über den<br />
Interrupt 17h aufgerufen werden können.<br />
Kein Prozessor-Register wird durch diese Funktion verändert. Dies gilt auch für das Flag-Register.<br />
Interrupt 21h, Funktion 06h Direkte Zeichenein-/-ausgabe<br />
Mit Hilfe dieser Funktion können Zeichen auf dem Standard -Ausgabegerät ausgegeben, oder vom Standard -Eingabegerät<br />
eingelesen werden. Das jeweils empfangene oder geschriebene Zeichen wird nicht vom Betriebssystem überprüft, so daß z.B.<br />
bei dem Auftreten <strong>eines</strong> Control-C-Zeichens nichts passiert. Da die Standard -Ein - und -Ausgabe auf andere Geräte oder in<br />
eine Datei umgeleitet werden kann, müssen die ausgegebenen Zeichen nicht auf dem Bildschirm erscheinen, bzw. die<br />
eingelesenen Zeichen müssen nicht von der Tastatur stammen. Wenn allerdings auf eine Datei zugegriffen wird, ist es für das<br />
aufrufende Programm unmöglich festzustellen, ob bereits alle Zeichen aus dieser Datei gelesen wurden, bzw. ob das<br />
Medium, auf dem sich die Datei befindet (Diskette, Festplatte) bereits voll ist.<br />
Bei der Eingabe <strong>eines</strong> Zeichens wird dabei nicht gewartet, bis ein Zeichen bereit steht, sondern in jedem Fall sofort wieder in<br />
das aufrufende Programm zurückgesprungen.<br />
Eingabe AH = 06h<br />
DL = 0 - 254: dieses Zeichen ausgeben<br />
DL = 255: ein Zeichen einlesen<br />
Ausgabe Bei der Zeichenausgabe: keine<br />
Bei der Zeicheneingabe:<br />
Zero -Flag = 1: es steht kein Zeichen bereit<br />
Zero -Flag = 0: eingelesenes Zeichen befindet sich im AL-Register<br />
Werden erweiterte Tastatur-Codes eingelesen, wird zunächst der Code 0 im AL-Register zurückgeliefert. Die Funktion muß<br />
dann erneut aufgerufen werden, um den eigentlichen Code zu lesen.<br />
Das Zeichen mit dem ASCII-Code 255 kann mit Hilfe dieser Funktion nicht ausgegeben werden, da es als Befehl zur<br />
Eingabe <strong>eines</strong> Z eichens verstanden wird.<br />
Der Inhalt der Register AH, BX, CX, DX, SI, DI, BP, CS, DS, SS und ES wird durch diese Funktion nicht verändert.<br />
Interrupt 21h, Funktion 07h Direkte Zeicheneingabe ohne Ausgabe<br />
Ein Zeichen wird vom Standard -Eingabegerät gelesen, ohne allerdings auf dem Standard -Ausgabegerät ausgegeben zu<br />
werden. Steht zum Zeitpunkt des Funktionsaufrufs kein Zeichen zur Verfügung, wartet die Funktion, bis ein Zeichen<br />
verfügbar wird.<br />
Das empfangene Zeichen wird nicht vom Betriebssystem überprüft, so daß z.B. bei dem Auftreten <strong>eines</strong> Control-C-Zeichens<br />
nichts passiert.<br />
Da die Standard -Eingabe auf ein anderes Gerät oder auf eine Datei umgeleitet werden kann, muß das eingelesene Zeichen<br />
nicht unbedingt der Tastatur entstammen. Werden die übergebenen Zeichen einer Datei entnommen, so gibt es für das<br />
aufrufende Programm keine Möglichkeit festzustellen, ob bereits alle Zeichen aus dieser Datei ausgelesen sind, das<br />
Dateiende also schon erreicht ist.<br />
Eingabe AH = 07h<br />
Ausgabe AL = Eingelesenes Zeichen<br />
Werden erweiterte Tastatur-Codes eingelesen, wird zunächst der Code 0 im AL-Register zurückgeliefert. Die Funktion muß<br />
dann erneut aufgerufen werden, um den eigentlichen Code zu lesen.<br />
Der Inhalt der Register AH, BX, CX, DX, SI, DI, BP, CS, DS, SS, ES und des Flag-Registers wird durch diese Funktion<br />
nicht verändert.
Rechnergrundlagen Teil 2 - 39 - Prof. Dipl.-Ing. Komar<br />
Interrupt 21h, Funktion 08h Zeicheneingabe ohne Ausgabe<br />
Ein Zeichen wird vom Standard -Eingabegerät gelesen, ohne allerdings auf dem Standard -Ausgabegerät ausgegeben zu<br />
werden. Steht zum Zeitpunkt des Funktionsaufrufs kein Zeichen zur Verfügung, wartet die Funktion, bis ein Zeichen<br />
verfügbar ist.<br />
Da die Standard -Eingabe auf ein anderes Gerät oder auf eine Datei umgeleitet werden kann, muß das eingelesene Zeichen<br />
nicht unbedingt der Tastatur entstammen. Werden die übergebenen Zeichen einer Datei entnommen, so gibt es für das<br />
aufrufende Programm keine Möglichkeit festzustellen, ob bereits alle Zeichen aus dieser Datei ausgelesen sind, das<br />
Dateiende also schon erreicht ist.<br />
Eingabe AH = 08h<br />
Ausgabe AL = Eingelesenes Zeichen<br />
Werden erweiterte Tastatur-Codes eingelesen, wird zunächst der Code 0 im AL-Register zurückgeliefert. Die Funktion muß<br />
dann erneut aufgerufen werden, um den eigentlichen Code zu lesen.<br />
Wird bei Aufruf dieser Funktion ein Control-C-Zeichen entdeckt, wird der Interrupt 23h aufgerufen.<br />
Der Inhalt der Register AH, BX, CX, DX, SI, DI, BP, CS, DS, SS, ES und des Flag-Registers wird durch diese Funktion<br />
nicht verändert.<br />
Interrupt 21h, Funktion 09h Ausgabe einer Zeichenkette<br />
Durch Aufruf dieser Funktion wird eine Zeichenkette auf dem Standard -Ausgabegerät ausgegeben. Da dieses Gerät auf ein<br />
anderes Gerät oder in eine Datei umgeleitet werden kann, besteht keine Gewähr, daß die Zeichenkette auf dem Bildschirm<br />
erscheint. Falls die Ausgabe in eine Datei umgeleitet wird, besteht für das aufrufende Programm keine Möglichkeit<br />
festzustellen, ob das Medium (Diskette, Festplatte), auf dem sich die Datei befindet, bereits voll ist und dadurch die<br />
Zeichenkette nicht mehr in die Datei geschrieben werden kann.<br />
Eingabe AH = 09h<br />
DS:DX = FAR-Zeiger auf die Zeichenkette<br />
Ausgabe keine<br />
Die Zeichenkette muß im Speicher als eine Folge von Byte gespeichert sein, die jeweils den ASCII-Code des auszugebenden<br />
Zeichens enthalten. Das Ende der Zeichenkette wird dem DOS durch ein $-Zeichen (ASCII-Code 36) signalisiert.<br />
Enthält die Zeichenkette Steuercodes wie Backspace, Carriage Return oder Line Feed, werden diese auch als solche<br />
behandelt.<br />
Nur der Inhalt des AL-Registers wird durch den Aufruf dieser Funktion verändert.<br />
Interrupt 21h, Funktion 0Ah Eingabe einer Zeichenkette mit Ausgabe<br />
Durch Aufruf dieser Funktion wird eine bestimmte Anzahl von Zeichen von dem Standard -Eingabegerät eingelesen, in einen<br />
Puffer übertragen und auf dem Standard -Ausgabegerät ausgegeben. Die Ausführung der Funktion wird beendet, sobald der<br />
Tastencode der [Return]-Taste (13) empfangen wird. Der Code dieser Taste wird dann als letztes Zeichen in den Puffer<br />
eingetragen. Da die Standard -Eingabe von der Tastatur auf ein anderes Gerät oder auf eine Datei umgeleitet werden kann,<br />
müssen die eingelesenen Zeichen nicht unbedingt der Tastatur entstammen. Werden die übergebenen Zeichen einer Datei<br />
entnommen, so gibt es für das aufrufende Programm keine Möglichkeit festzustellen, ob bereits alle Zeichen aus dieser Datei<br />
ausgelesen sind, das Dateiende also schon erreicht ist.<br />
Eingabe AH = 0Ah<br />
DS:DX = FAR-Zeiger auf den Puffer<br />
Ausgabe keine<br />
Das erste Byte des Puffers muß vor dem Funktionsaufruf mit der maximalen Anzahl von Zeichen geladen werden, die<br />
eingelesen werden dürfen (inklusive des Carriage Return am Ende).<br />
In das zweite Byte des Puffers trägt DOS nach Beendigung der Eingabe die Anzahl der eingelesenen Zeichen ohne das<br />
Carriage Return ein. Erst danach folgen die eingelesenen Zeichen. Der Puffer muß damit mindestens Platz für die<br />
angegebene Maximalzahl von Zeichen plus zwei Byte bieten.<br />
Ist die vorletzte Speicherstelle des Puffers erreicht, wird bei der Eingabe von weiteren Zeichen ein Piepston ausgegeben und<br />
nur noch das Return -Zeichen als Abschluß der Eingabe akzeptiert.<br />
Erweiterte Tastatur-Codes belegen im Puffer 2 Byte. Das erste Byte enthält den Code 0 und das zweite den Code der<br />
erweiterten Taste. Wird während der Eingabe ein Control-C-Zeichen entdeckt, wird der Interrupt 23h aufgerufen.<br />
Die Eingabe kann mit Hilfe der Backspace- und der Cursor-Tasten editiert werden, ohne daß diese Tasten im Puffer<br />
abgespeichert werden.<br />
Der Inhalt der Prozessor-Register wird durch diese Funktion nicht verändert. Dies gilt auch für das Flag-Register.
Rechnergrundlagen Teil 2 - 40 - Prof. Dipl.-Ing. Komar<br />
Interrupt 21h, Funktion 0Bh Lese Eingabestatus<br />
Mit Hilfe dieser Funktion kann festgestellt werden, ob Zeichen auf dem Standard -Eingabegerät bereitstehen, um eingelesen<br />
zu werden.<br />
Eingabe AH = 0Bh<br />
Ausgabe AL = 0: kein Zeichen verfügbar<br />
AL = 255: es stehen ein oder mehrere Zeichen zum Lesen bereit<br />
Wird ein Control-C-Zeichen entdeckt, wird der Interrupt 23h aufgerufen.<br />
Der Inhalt der Register AH, BX, CX, DX, SI, DI, BP, CS, DS, SS, ES und des Flag-Registers wird durch diese Funktion<br />
nicht verändert.<br />
Interrupt 21h, Funktion 0Ch Lösche Eingabepuffer und rufe Eingabefunktion auf<br />
Diese Funktion löscht zunächst den Eingabepuffer und ruft danach eine der Funktionen zur Zeicheneingabe auf. Da alle<br />
Funktionen zur Zeicheneingabe ihr Zeichen vom Standard -Eingabegerät beziehen und dieses nicht unbedingt die Tastatur<br />
sein muß, ist das Löschen des Eingabepuffers nur dann von Bedeutung, wenn das Standard -Eingabegerät die Tastatur ist. In<br />
diesem Fall kann es sein, daß vor dem Funktionsaufruf Zeichen eingegeben worden sind, die aber noch nicht von einer<br />
Funktion ausgelesen wurden. Sie werden dann gelöscht, um zu garantieren, daß die nachfolgend aufgerufene Funktion nur<br />
Zeichen empfängt, die während ihres Aufrufs eingegeben wurden.<br />
Eingabe AH = 0Ch<br />
AL = Nummer der aufzurufenden Funktion<br />
Bei Aufruf der Funktion 0Ah:<br />
DS:DX = FAR-Zeiger auf den Eingabepuffer<br />
Ausgabe Für die Funktionen 01h, 06h, 07h und 08h : AL = Eingelesenes Zeichen<br />
Für die Funktion 0Ah: keine<br />
Nur die Funktionsnummern 01h, 06h, 07h, 08h und 0Ah dürfen der Funktion als aufzurufende Funktionen übergeben werden.<br />
Nur der Inhalt des AL-Registers wird durch den Aufruf dieser Funktion verändert.<br />
Interrupt 21h, Funktion 2Ah Datum abfragen<br />
Eingabe AH = 2Ah<br />
Ausgabe AL = Tag der Woche (0=Sonntag, 1=Montag usw.)<br />
CX = Jahr<br />
DH = Monat<br />
DL = Tag<br />
Zur Abfrage des Datums ruft DOS den Uhrtreiber auf. Die Werte werden dual zurückgeliefert. Der Inhalt der Register<br />
AH, BX, SI, DI, BP, CS, DS, SS, ES und des Flag-Registers wird durch diese Funktion nicht verändert.<br />
Interrupt 21h, Funktion 2Bh Datum setzen<br />
Das aktuelle Datum, wie es von der Funktion 2Ah zurückgeliefert wird, wird durch den Aufruf dieser Funktion gesetzt.<br />
Eingabe AH = 2Bh<br />
CX = Jahr<br />
DH = Monat<br />
DL = Tag<br />
Ausgabe AL = 0: o.k.<br />
AL = 255: Datum unplausibel<br />
Das übergebene Datum wird an den Uhrtreiber übermittelt. Die Werte werden dual übergeben.<br />
Sofern der jeweilige PC nicht über eine batteriegepufferte Echtzeituhr und einen Uhrtreiber, der diese unterstützt, verfügt,<br />
bleibt das Datum nur bis zum Ausschalten bzw. Booten des Rechners erhalten.<br />
Wenn das Datum unplausibel ist, wird das alte Datum beibehalten.<br />
Der Inhalt der Register AH, BX, CX, DX, SI, DI, BP, CS, DS, SS, ES und des Flag-Registers wird durch diese Funktion<br />
nicht verändert.
Rechnergrundlagen Teil 2 - 41 - Prof. Dipl.-Ing. Komar<br />
Interrupt 21h, Funktion 2Ch Uhrzeit abfragen<br />
Eingabe AH = 2Ch<br />
Ausgabe CH = Stunde<br />
CL = Minute<br />
DH = Sekunde<br />
DL = Hundertstel Sekunden<br />
Zur Abfrage der Uhrzeit ruft DOS den Uhrtreiber auf. Die Zeitwerte werden dual ausgegeben. Der Inhalt der Register<br />
AX, BX, SI, DI, BP, CS, DS, SS, ES und des Flag-Registers wird durch diese Funktion nicht verändert.<br />
Interrupt 21h, Funktion 2Dh Uhrzeit setzen<br />
Eingabe AH = 2Dh<br />
CH = Stunde<br />
CL = Minute<br />
DH = Sekunde<br />
DL = Hundertstel Sekunden<br />
Ausgabe AL = 0: o.k.<br />
AL = 255: Uhrzeit unplausibel<br />
Die übergebene Uhrzeit wird an den Uhrtreiber übermittelt. Die Zeitwerte werden dual übergeben.<br />
Sofern der jeweilige PC nicht über eine batteriegepufferte Echtzeituhr und einen Uhrtreiber, der diese unterstützt, verfügt,<br />
bleibt die Uhrzeit lediglich bis zum Ausschalten bzw. Booten des Rechners erhalten. Wenn die Uhrzeit unplausibel ist, wird<br />
die alte Uhrzeit beibehalten. Der Inhalt der Register AH, BX, CX, DX, SI, DI, BP, CS, DS, SS, ES und des Flag-Registers<br />
wird durch diese Funktion nicht verändert.<br />
Interrupt 21h, Funktion 30h DOS -Versionsnummer ermitteln<br />
Eingabe AH = 30h<br />
Ausgabe AL = Übergeordnete Versionsnummer<br />
AH = Untergeordnete Versionsnummer<br />
BH = OEM -Code<br />
Die übergeordnete Versionsnummer ist die Zahlenangabe vor dem Punkt. Bei der Versionsnummer 2.1 ist die übergeordnete<br />
Versionsnummer die Nummer 2.<br />
Die untergeordnete Versionsnummer ist die Zahlenangabe nach dem Punkt. Sie wird immer zweistellig angegeben. Bei der<br />
Version 2.1 ist die untergeordnete Versionsnummer die Nummer 10.<br />
Die OEM -Codenummer im BH-Register ist in der Regel wenig aussagekräftig, da dieser Code nicht genormt ist.<br />
Grundsätzlich gilt jedoch, daß PC-DOS (von IBM) den Code 0 trägt.<br />
Wird im AL-Register der Wert 0 zurückgeliefert, so läuft das Programm unter der DOS-Version 1 ab, die diese Funktion<br />
noch nicht kennt. Der Inhalt der Register DX, SI, DI, BP, CS, DS, SS, ES und des Flag-Registers wird durch diese Funktion<br />
nicht verändert.<br />
Interrupt 21h, Funktion 25h Setze Interrupt-Vektor<br />
Mit Hilfe dieser Funktion kann ein beliebiger Interrupt-Vektor auf eine andere Routine verbogen werden.<br />
Eingabe AH = 25h<br />
AL = Nummer des Interrupts<br />
DS:DX = FAR-Zeiger auf die Interrupt-Routine<br />
Ausgabe keine<br />
Vor Aufruf dieser Funktion sollte zunächst der alte Inhalt des zu verändernden Interrupt-Vektors mit Hilfe der Funktion 35h<br />
ausgelesen und gespeichert werden. Nach Beendigung des Programms sollte sein alter Inhalt dann mit Hilfe dieser Funktion<br />
restauriert werden. Kein Prozessor-Register wird durch diese Funktion verändert. Dies gilt auch für das Flag-Register.
Rechnergrundlagen Teil 2 - 42 - Prof. Dipl.-Ing. Komar<br />
Interrupt 21h, Funktion 35h Inhalt <strong>eines</strong> Interrupt-Vektors auslesen<br />
Diese Funktion liefert als Resultat den aktuellen Inhalt <strong>eines</strong> Interrupt-Vektors und damit die Adresse der zugehörigen<br />
Interrupt-Routine zurück.<br />
Eingabe AH = 35h<br />
AL = Nummer des Interrupts<br />
Ausgabe ES:BX = FAR-Zeiger auf die Interrupt-Routine<br />
Um Kompatibilität zu zukünftigen DOS-Versionen zu garantieren, sollte diese Funktion zum Auslesen <strong>eines</strong> Interrupt-<br />
Vektors aufgerufen werden, anstatt den Inhalt des jeweiligen Vektors direkt aus der Interrupt-Vektor-Tabelle auszulesen.<br />
Der Inhalt der Register AX, CX, DX, SI, DI, BP, CS, DS, SS und des Flag-Registers wird durch diese Funktion nicht<br />
verändert .<br />
Interrupt 21h, Funktion 31h Programm beenden, aber im Speicher belassen<br />
Durch den Aufruf dieser Funktion wird das ausgeführte Programm beendet und die Kontrolle wieder an das Programm<br />
übergeben, das das aktuelle Programm aufgerufen hat.<br />
Im Gegensatz zu den anderen Funktionen zur Beendigung <strong>eines</strong> Programms wird der durch das Programm belegte Speicher<br />
jedoch nicht zur weiteren Verwendung freigegeben, wodurch das aktuelle Programm resident im Speicher verbleibt.<br />
Eingabe AH = 31h<br />
AL = Ende-Code<br />
DX = Anzahl der zu reservierenden Paragraphen<br />
Ausgabe keine<br />
Der Ende-Code im AL-Register dient dazu, dem aufrufenden Programm zu signalisieren, ob das von ihm aufgerufene<br />
Programm korrekt abgearbeitet werden konnte. Das aufrufende Programm kann diesen Wert durch Aufruf der Funktion 4Dh<br />
ermitteln. Innerhalb <strong>eines</strong> Batch-Programms kann dieser Wert mit Hilfe der Befehle ERRORLEVEL und IF überprüft<br />
werden.<br />
Die Anzahl der zu reservierenden Paragraphen (jeweils 16 Byte) gibt an, wie viele Byte, beginnend mit dem PSP, nicht mehr<br />
zur weiteren Verwendung freigegeben werden dürfen.<br />
Speicherblöcke, die mit Hilfe der Funktion 48h reserviert werden, werden durch den Wert im DX-Register nicht beeinflußt,<br />
da sie nur durch Aufruf der Funktion 49h wieder freigegeben werden können.<br />
Interrupt 21h, Funktion 4Ch Programm mit Ende-Code beenden<br />
Durch den Aufruf dieser Funktion wird ein Programm beendet und gleichzeitig ein Ende-Code übergeben, den das<br />
aufrufende Programm mit Hilfe der Funktion 4Dh abfragen kann. Der RAM-Speicher, den das zu beendende Programm<br />
belegt, wird nach diesem Funktionsaufruf freigegeben, so daß er wieder anderen Programmen zugeteilt werden kann.<br />
Eingabe AH = 4Ch<br />
AL = Ende-Code<br />
Ausgabe keine<br />
Diese Funktion sollte den anderen Funktionen zur Programmbeendigung vorgezogen werden.<br />
Beim Aufruf dieser Funktion werden die 3 Interrupt-Vektoren, deren Inhalt vor dem Start des Programms im PSP gespeichert<br />
wurden, restauriert.<br />
Vor Übergabe der Kontrolle an das aufrufende Programm werden alle Handles, die von diesem Programm geöffnet wurden,<br />
und die mit ihnen verbundenen Dateien geschlossen. Dies gilt allerdings nicht für Dateien, auf die über FCB zugegriffen<br />
wurde. Der Ende-Code kann innerhalb einer Batch-Datei mit Hilfe der Befehle ERRORLEVEL und IF überprüft werden.<br />
Interrupt 19h Booten des Rechners<br />
Nach Aufruf dieses Interrupts wird der Rechner gebootet.<br />
Eingabe keine<br />
Ausgabe keine<br />
Der Aufruf dieses Interrupts verursacht oftmals keinen Reboot des Rechners, sondern einen Systemabsturz. Das hängt damit<br />
zusammen, daß zwar der Inhalt des RAM-Speichers gelöscht wird, aber die Interrupt-Vektor-Tabelle im Bereich der<br />
Interrupts 00h bis 1Ch unangetastet bleibt. Hat sich ein TSR-Programm in einen dieser Interrupts gehangen, würde der<br />
nächste Aufruf dieses Interrupts deshalb unweigerlich zum Systemabsturz führen. Dies gilt insbesondere für den Timer-<br />
Interrupt 08h, der von den meisten TSR-Programmen genutzt wird.<br />
Umgehen Sie diesen Interrupt deshalb, und wenden Sie zur Auslösung des Reboot-Vorgangs folgende Technik an: Um einen<br />
Warmstart auszulösen, speichern Sie zunächst den Wert 1234h in der Speicherstelle 0040:0072 und führen anschließend<br />
einen FAR-Jump zur Speicherstelle FFFF:0000 aus.<br />
Wenn in der Speicherstelle 0040:0072 nicht der Wert 1234 h steht, dann wird ein Kaltstart ausgeführt.
Rechnergrundlagen Teil 2 - 43 - Prof. Dipl.-Ing. Komar<br />
7.3.2 BIOS-Funktionen<br />
Über die Interrupts 10h bis 1Ah können die verschiedenen Funktionen erreicht werden, die das ROM-BIOS zur<br />
grundlegenden Kommunikation zwischen einem Progra mm und der Hardware zur Verfügung stellt. Dazu zählen neben<br />
Funktionen zum Zugriff auf die Video-Hardware, Tastatur, Festplatten und Diskettenlaufwerke, aber auch die Abfrage von<br />
Konfigurationsdaten, sowie die Programmierung der seriellen und parallelen Schnittstelle und der batteriegepufferten<br />
Echtzeituhr. Übersicht der BIOS-Funktionen die in diesem Skript beschrieben sind<br />
Interrupt 10 h Bildschirm<br />
Fkt. Beschreibung<br />
00h Setzen des Video-Modus<br />
01h Definition des Erscheinungsbildes des Cursors<br />
02h Posit ionierung des Cursors<br />
03h Auslesen der Cursor-Position<br />
04h Auslesen der Lichtstiftposition<br />
05h Auswahl der aktuellen Bildschirmseite<br />
06h Textzeilen nach oben schieben (scrollen)<br />
07h Textzeilen nach unten schieben (scrollen)<br />
08h Auslesen <strong>eines</strong> Zeichens/Farb e<br />
09h Schreiben <strong>eines</strong> Zeichens/Farbe<br />
0Ah Schreiben <strong>eines</strong> Zeichens<br />
0Bh/00h Auswahl der Rahmen-/Hintergrundfarbe<br />
0Bh/01h Auswahl der Farbpalette<br />
0Ch Schreibe Grafikpunkt<br />
0Dh Lese Grafikpunkt<br />
0Eh Schreiben <strong>eines</strong> Zeichens<br />
0Fh Auslesen des Video-Modus<br />
13h Ausgabe einer Zeichenkette<br />
Interrupt 14 h Serielle Schnittstelle<br />
00h Initialisierung<br />
01h Zeichen ausgeben<br />
02h Zeichen einlesen<br />
03h Status erfragen<br />
Interrupt 16 h Tastatur<br />
00h Zeichen auslesen<br />
01h Zeichen vorhanden?<br />
02h Status der Tastatur erfragen<br />
03h Wiederholrate einstellen<br />
05h Tastendruck simulieren<br />
10h Tastaturabfrage für erweiterte Tastaturen<br />
11h Tastaturabfrage für erweiterte Tastaturen<br />
Interrupt 17 h Parallele Schnittstelle<br />
00h Zeichen ausgeben<br />
01h Drucker initialisieren<br />
02h Status des Druckers erfragen<br />
Interrupt 1A h Datum und Zeit<br />
00h Zeit -Zähler auslesen<br />
01h Zeit -Zähler setzen<br />
02h Auslesen der Echtzeit-Uhr<br />
03h Setzen der Echtzeit-Uhr<br />
04h Auslesen des Datums aus der Echtzeit-Uhr<br />
05h Setzen des Datums der Echtzeit-Uh r<br />
06h Alarmzeit setzen<br />
07h Alarmzeit löschen
Rechnergrundlagen Teil 2 - 44 - Prof. Dipl.-Ing. Komar<br />
Interrupt 10 h (BIOS) Bildschirm<br />
Interrupt 10h, Funktion 00h Bildschirm: Setzen des Video-Modus<br />
Durch Aufruf dieser Funktion wird ein Video-Modus ausgewählt und initialisiert. Dabei wird der gesamte Bildschirm<br />
gelöscht, wodurch es mit Hilfe dieser Funktion möglich ist, den aktuellen Video-Modus beizubehalten, aber auf ganz<br />
einfache Art den Bildschirm zu löschen.<br />
Eingabe AH = 00h<br />
AL = Video-Modus<br />
0 40*25 Zeichen Text, schwarz/weiß (CGA)<br />
1 40*25 Zeichen Text, farbig (CGA)<br />
2 80*25 Zeichen Text, schwarz/weiß (CGA)<br />
3 80*25 Zeichen Text, farbig (CGA)<br />
4 320*200 Punkte Grafik, 4 Farben (CGA)<br />
(die Farben werden schwarz/weiß dargestellt)<br />
5 320*200 Punkte Grafik, 4 Farben (CGA)<br />
6 640*200 Punkte Grafik, 2 Farben (CGA)<br />
7 80*25 Zeichen Text, Attribute (MDA)<br />
Ausgabe keine<br />
Die Farben für die Modi 4, 5 und 6 können mit der Funktion 0Bh eingestellt werden.<br />
Der Inhalt der Register BX, CX, DX und der Segmentregister SS, CS und DS wird durch diese Funktion nicht verändert. Der<br />
Inhalt aller anderen Register, vor allem der Register SI und DI, kann verändert werden.<br />
Interrupt 10h, Funktion 01h Bildschirm: Definition des Erscheinungsbildes des Cursors<br />
Die Start - und Endzeile des blinkenden Bildschirmcursors wird durch Aufruf dieser Funktion definiert. Sie ist unabhängig<br />
von der auf dem Bildschirm dargestellten Bildschirmseite.<br />
Eingabe AH = 01h<br />
CH = Startzeile des Cursor<br />
CL = Endzeile des Cursor<br />
Ausgabe keine Ausgabe<br />
Start- und Endzeile werden nicht in den Maßstäben von Bildschirmzeilen gemessen, sondern beziehen sich auf die<br />
Punktzeilen, aus denen das Videobild entsteht. Die gültigen Wertebereiche hängen von der installierten Videokarte ab:<br />
MDA: 0 - 13<br />
CGA: 0 - 7<br />
Vom BIOS werden folgende Werte für Start- und Endzeile voreingestellt:<br />
MDA: 11 - 12<br />
CGA: 6 - 7<br />
Mit Hilfe dieser Funktion sollten nur die erlaubten Werte eingestellt werden. Alle anderen Werte haben unvorhersehbare<br />
Resultate (in den meisten Fällen das Verschwinden des Cursors) zur Folge.<br />
Der Inhalt der Register BX, CX, DX und der Segmentregister SS, CS und DS wird durch diese Funktion nicht verändert. Der<br />
Inhalt aller anderen Register, vor allem der Register SI und DI kann verändert werden.<br />
Interrupt 10h, Funktion 02h Bildschirm: Positionierung des Cursors<br />
Der Cursor, der die Bildschirmposition für die Zeichenausgabe über eine der BIOS-Funktionen zur Zeichenausgabe<br />
bestimmt, wird durch Aufruf dieser Funktion versetzt.<br />
Eingabe AH = 02h<br />
BH = Nummer der Bildschirmseite<br />
DH = Bildschirmzeile<br />
DL = Bildschirmspalte<br />
Ausgabe keine Ausgabe<br />
Der blinkende Bildschirm-Cursor wird mit Hilfe dieser Funktion nur dann versetzt, wenn die angesprochene Bildschirmseite<br />
die aktuelle Bildschirmseite ist. Die Bildschirmzeile ist ein Wert zwischen 0 und 24.<br />
Die Bildschirmspalte ist je nach Video-Modus ein Wert zwischen 0 und 79 (80-Zeichen-Darstellung) oder 0 und 39 bei der<br />
40-Zeichen-Darstellung. Eine Methode, um den blinkenden Cursor verschwinden zu lassen, ist, ihn an eine nicht<br />
existierende Bildschirmposition (z.B. Spalte 0, Zeile 25) zu versetzen. Die Nummer der Bildschirmseite ist davon abhängig,<br />
wie viele Bildschirmseiten von der Videokarte in dem jeweiligen Video-Modus zur Verfügung gestellt werden.<br />
Der Inhalt der Register BX, CX, DX und der Segmentregister SS, CS und DS wird durch diese Funktion nicht verändert. Der<br />
Inhalt aller anderen Register, vor allem der Register SI und DI, kann verändert werden.
Rechnergrundlagen Teil 2 - 45 - Prof. Dipl.-Ing. Komar<br />
Interrupt 10h, Funktion 03h Bildschirm: Auslesen der Cursor -Position<br />
Die Position des Textcursors in einer Bildschirmseite und die Start - und Endzeile des blinkenden Bildschirm-Cursors werden<br />
ausgelesen.<br />
Eingabe AH = 03h<br />
BH = Nummer der Bildschirmseite<br />
Ausgabe DH = Bildschirmzeile, in der sich der Cursor befindet<br />
DL = Bildschirmspalte, in der sich der Cursor befindet<br />
CH= Anfangszeile des blinkenden Bildschirm-Cursors<br />
CL = Endzeile des blinkenden Bildschirm-Cursors<br />
Die Nummer der Bildschirmseite ist auch davon abhängig, wie viele Bildschirmseiten von der Videokarte zur Verfügung<br />
gestellt werden. Bildschirmzeile und -spalte beziehen sich jeweils auf das Textkoordinatensystem.<br />
Der Inhalt des BX-Registers und Inhalt der Segmentregister SS, CS und DS wird durch diese Funktion nicht verändert. Der<br />
Inhalt aller anderen Register, vor allem der Register SI und DI, kann verändert wo rden sein.<br />
Interrupt 10h, Funktion 05h Bildschirm: Auswahl der aktuellen Bildschirmseite<br />
Die aktuelle und somit auf dem Bildschirm darzustellende Bildschirmseite (nur Textmodus) wird ausgewählt.<br />
Eingabe AH = 05h<br />
AL = Nummer der Bildschirmseite<br />
Ausgabe keine Ausgabe<br />
Die Nummer der Bildschirmseite ist auch davon abhängig, wie viele Bildschirmseiten von der Videokarte zur Verfügung<br />
gestellt werden.<br />
Beim Umschalten auf eine neue Bildschirmseite wird der blinkende Bildschirm-Cursor auf die Position des Text -Cursors in<br />
dieser Seite gesetzt.<br />
Das Umschalten zwischen verschiedenen Bildschirmseiten verändert deren Inhalt (die einzelnen Zeichen) nicht.<br />
Eine Bildschirmseite muß nicht unbedingt aktiv sein, damit Zeichen in sie geschrieben werden können.<br />
Der Inhalt der Register BX, CX, DX und der Segmentregister SS, CS und DS wird durch diese Funktion nicht verändert. Der<br />
Inhalt aller anderen Register, vor allem der Register SI und DI, kann verändert werden.<br />
Interrupt 10h, Funktion 06h Bildschirm: Textzeilen nach oben schieben (scrollen)<br />
Ein Teil der aktuellen Bildschirmseite wird um eine oder um mehrere Zeilen nach oben verschoben oder gelöscht.<br />
Eingabe AH = 06h<br />
AL = Anzahl der Zeilen, um die das Fenster nach oben verschoben werden soll<br />
( 0 bedeutet Fenster löschen)<br />
CH = Bildschirmzeile der oberen linken Fensterecke<br />
CL = Bildschirmspalte der oberen linken Fensterecke<br />
DH= Bildschirmzeile der unteren rechten Fensterecke<br />
DL = Bildschirmspalte der unteren rechten Fensterecke<br />
BH= Farbe (Attribut) für die Leerzeile(n)<br />
Ausgabe keine Ausgabe<br />
Nur die aktuelle Bildschirmseite kann mit dieser Funktion beeinflußt werden.<br />
Das Löschen des Bildschirmbereichs (Anzahl Zeilen = 0) kommt einem Füllen mit Leerzeichen (ASCII-Code 32) gleich.<br />
Der Inhalt der aus dem Fenster herausgescrollten Zeilen ist unwiederbringbar verloren und kann nicht wieder zurückgeholt<br />
werden. Um den gesamten Bildschirm zu löschen, kann man sich besser der Funktion 0 dieses Interrupts bedienen.<br />
Der Inhalt der Register BX, CX, DX und der Segmentregister SS, CS und DS wird durch diese Funktion nicht verändert. Der<br />
Inhalt aller anderen Register, vor allem der Register SI und DI, kann verändert werden.<br />
Interrupt 10h, Funktion 07h Bildschirm: Textzeilen nach unten schieben (scrollen)<br />
Ein Teil der aktuellen Bildschirmseite wird um eine oder um mehrere Zeilen nach unten verschoben oder gelöscht.<br />
Eingabe AH = 07h<br />
AL = Anzahl der Zeilen, um die das Fenster nach unten<br />
verschoben werden soll (0 bedeutet Fenster löschen)<br />
CH = Bildschirmzeile der oberen linken Fensterecke<br />
CL = Bildschirmspalte der oberen linken Fensterecke<br />
DH = Bildschirmzeile der unteren rechten Fensterecke<br />
DL = Bildschirmspalte der unteren rechten Fensterecke<br />
BH = Farbe (Attribut) für die Leerzeile(n)<br />
Ausgabe keine Ausgabe
Rechnergrundlagen Teil 2 - 46 - Prof. Dipl.-Ing. Komar<br />
Nur die aktuelle Bildschirmseite kann mit dieser Funktion beeinflußt werden.<br />
Das Löschen des Bildschirmbereichs (Anzahl Zeilen = 0) kommt einem Füllen mit Leerzeichen (ASCII-Code 32) gleich.<br />
Der Inhalt der aus dem Fenster herausgescrollten Zeilen ist unwiederbringbar verloren und kann nicht wieder zurückgeholt<br />
werden.<br />
Um den gesamten Bildschirm zu löschen, kann man sich besser der Funktion 0 dieses Interrupts bedienen.<br />
Der Inhalt der Register BX, CX, DX und der Segmentregister SS, CS und DS wird durch diese Funktion nicht verändert. Der<br />
Inhalt aller anderen Register, vor allem der Register SI und DI, kann verändert worden sein.<br />
Interrupt 10h, Funktion 08h Bildschirm: Auslesen <strong>eines</strong> Zeichens/Farbe<br />
Der ASCII-Code des Zeichens an der aktuellen Cursor-Position und dessen Farbe (Attribut) werden ausgelesen.<br />
Eingabe AH = 08h<br />
BH = Nummer der Bildschirmseite<br />
Ausgabe AL = ASCII-Code des Zeichens<br />
AH = Farbe (Attribut)<br />
Die Nummer der Bildschirmseite ist auch davon abhängig, wie viele Bildschirmseiten von der Videokarte zur Verfügung<br />
gestellt werden.<br />
Diese Funktion kann auch im Grafikmodus aufgerufen werden, wobei dann das Bitmuster des Zeichens auf dem Bildschirm<br />
mit den Bitmustern der Zeichen im Zeichen-ROM der Videokarte und den Zeichenmustern, die in einer RAM-Tabelle gespeichert<br />
sind, deren Adresse der Interrupt 1Fh enthält, verglichen werden. Kann das Zeichen dabei nicht identifiziert<br />
werden, enthält das AL-Register nach dem Funktionsaufruf den Wert 0.<br />
Der Inhalt der Register BX, CX, DX und der Segmentregister SS, CS und DS wird durch diese Funktion nicht verändert. Der<br />
Inhalt aller anderen Register, vor allem der Register SI und DI, kann verändert worden sein.<br />
Interrupt 10h, Funktion 09h Bildschirm: Schreiben <strong>eines</strong> Zeichens/Farbe<br />
Ein Zeichen mit einer bestimmten Farbe wird an die aktuelle Cursor-Position (in einer vorgegebenen Bildschirmseite)<br />
geschrieben.<br />
Eingabe AH = 09h<br />
BH = Nummer der Bildschirmseite<br />
CX = Anzahl, wie oft das Zeichen hintereinander geschrieben werden soll<br />
AL = ASCII-Code des Zeichens<br />
BL = Farbe/Attribut<br />
Ausgabe keine Ausgabe<br />
Soll das angegebene Zeichen mehrmals ausgegeben werden (in dem Fall ist der Wert des CX-Registers größer 1), müssen im<br />
Grafikmodus alle Zeichen in die aktuelle Bildschirmzeile passen.<br />
Die Steuercodes Bell, Carriage Return usw. werden nicht als solche erkannt, sondern als normale ASCII-Codes ausgegeben.<br />
Mit dieser Funktion können auch Zeichen im Grafikmodus ausgegeben werden, wobei die Zeichenmuster der Zeichen mit<br />
den Codes 0 bis 127 aus einer Tabelle im ROM und die Zeichenmuster der Zeichen 128 bis 255 aus einer RAM-Tabelle<br />
ermittelt werden, die zuvor mit dem DOS-Befehl GRAFTABL installiert werden muß.<br />
Im Textmodus definiert der Inhalt des BL-Registers das Attribut-Byte des Zeichens. Im Grafikmodus bestimmt es die Farbe<br />
des Zeichens. Dabei sind im 640*200-Punkte-Modus nur die Werte 0 und 1, im 320*200-Punkte-Modus die Werte 0 bis 3 für<br />
die verschiedenen Farben der angewählten Farbpalette möglich.<br />
Ist der Grafikmodus während der Zeichenausgabe aktiv, und ist das Bit 7 des BL-Registers gesetzt, so wird das<br />
Zeichenmuster mit den Grafikpunkten unter diesem Zeichen durch ein Exklusiv-Oder verkn üpft.<br />
Der Cursor wird durch diese Funktion nicht auf die nächste Bildschirmposition versetzt.<br />
Der Inhalt der Register BX, CX, DX und der Segmentregister SS, CS und DS wird durch diese Funktion nicht verändert. Der<br />
Inhalt aller anderen Register, vor allem der Register SI und DI, kann verändert werden.<br />
Interrupt 10h, Funktion 0Ah Bildschirm: Schreiben <strong>eines</strong> Zeichens<br />
Ein Zeichen wird an die aktuelle Cursor-Position in einer vorgegebenen Bildschirmseite geschrieben, wobei die Farbe des<br />
alten Zeichens an dieser Bildschirmposition beibehalten wird.<br />
Eingabe AH = 0Ah<br />
BH = Nummer der Bildschirmseite<br />
CX = Anzahl, wie oft das Zeichen hintereinander geschrieben werden soll<br />
AL = ASCII-Code des Zeichens<br />
Ausgabe keine Ausgabe<br />
Soll das angegebene Zeichen mehrmals ausgegeben werden (in dem Fall ist der Wert des CX-Registers größer 1), müssen im<br />
Grafikmodus alle Zeichen in die aktuelle Bildschirmzeile passen.<br />
Die Steuercodes Bell, Carriage Return usw. werden nicht als solche erkannt, sondern als normale ASCII-Codes ausgegeben.
Rechnergrundlagen Teil 2 - 47 - Prof. Dipl.-Ing. Komar<br />
Mit dieser Funktion können auch Zeichen im Grafikmodus ausgegeben werden, wobei die Zeichenmuster der Zeichen mit<br />
den Codes 0 bis 127 aus einer Tabelle im ROM und die Zeichenmuster der Zeichen 128 bis 255 aus einer RAM-Tabelle<br />
ermittelt werden, die zuvor mit dem DOS-Befehl GRAFTABL installiert werden muß.<br />
Ist der Grafikmodus während der Zeichenausgabe aktiv, und ist das Bit 7 des BL-Registers gesetzt, so wird das<br />
Zeichenmuster mit den Grafikpunkten unter diesem Zeichen durch ein Exklusiv-Oder verknüpft.<br />
Der Cursor wird durch diese Funktion nicht auf die nächste Bildschirmposition versetzt.<br />
Der Inhalt der Register BX, CX, DX und der Segmentregister SS, CS und DS wird durch diese Funktion nicht verändert. Der<br />
Inhalt aller anderen Register, vor allem der Register SI und DI, kann verändert werden.<br />
Interrupt 10h, Funktion 0Bh, Unterfunktion 0 Bildschirm: Auswahl der Rahmen-/Hintergrundfarbe<br />
Die Rahmen- und Hintergrundfarbe für den Grafik- bzw. Textmodus wird mit dieser Funktion ausgewählt.<br />
Eingabe AH = 0Bh<br />
BH = 0<br />
BL = Rahmen-/Hintergrundfarbe<br />
Ausgabe keine Ausgabe<br />
Im Grafikmodus definiert der übergebene Farbwert sowohl die Farbe des Bildschirmrahmens, als auch die des<br />
Bildschirmhintergrunds. Im Textmodus wird die Hinterg rundfarbe jedes Zeichens einzeln definiert, so daß der übergebene<br />
Farbwert hier nun die Farbe des Bildschirmrahmens beschreibt.<br />
Der übergebene Farbwert kann zwischen 0 und 15 liegen und somit alle 16 möglichen Farben repräsentieren.<br />
Der Inhalt der Register BX, CX, DX und der Segmentregister SS, CS und DS wird durch diese Funktion nicht verändert. Der<br />
Inhalt aller anderen Register, vor allem der Register SI und DI, kann verändert werden.<br />
Interrupt 10h, Funktion 0Bh, Unterfunktion 1 Bildschirm: Auswahl der Farbpalette<br />
Eine der beiden Farbpaletten für den 320*200-Punkte-Grafikmodus wird ausgewählt.<br />
Eingabe AH = 0Bh<br />
BH = 1<br />
BL = Nummer der Farbpalette<br />
Ausgabe keine Ausgabe<br />
Es werden zwei Farbpaletten zur Verfügung gestellt. Sie tragen die Nummer 0 und 1 und enthalten folgende Farben:<br />
Palette 0: Grün, Rot, Gelb Palette 1: Cyan, Magenta, Weiß<br />
Der Inhalt der Register BX, CX, DX und der Segmentregister SS, CS und DS wird durch diese Funktion nicht verändert. Der<br />
Inhalt aller anderen Register, vor allem der Register SI und DI, kann verändert werden.<br />
Interrupt 10h, Funktion 0Ch Bildschirm: Schreibe Grafikpunkt<br />
Der Farbwert für einen Bildschirmpunkt im Grafikmodus wird gesetzt.<br />
Eingabe AH = 0Ch<br />
DX = Bildschirmzeile<br />
CX = Bildschirmspalte<br />
AL = Farbwert<br />
Ausgabe keine Ausgabe<br />
Der Farbwert richtet sich nach dem aktuellen Grafikmodus. Im 640*200-Punkte-Modus sind nur die Werte 0 und 1 erlaubt.<br />
Im 320*200-Punkte-Modus sind die Werte 0 bis 3 erlaubt, die je nach der angewählten Farbpalette eine bestimmte Farbe<br />
erzeugen. 0 steht dabei für die angewählte Hintergrundfarbe, 1 für die erste Farbe der angewählten Farbpalette, 2 für die<br />
zweite Farbe der Farbpalette usw.<br />
Der Inhalt der Register BX, CX, DX und der Segmentregister SS, CS und DS wird durch diese Funktion nicht verändert. Der<br />
Inhalt aller anderen Register, vor allem der Register SI und DI, kann verändert werden<br />
Interrupt 10h, Funktion 0Dh Bildschirm: Lese Grafikpunkt<br />
Der Farbwert <strong>eines</strong> Bildschirmpunktes im Grafikmodus wird ausgelesen.<br />
Eingabe AH = 0Dh<br />
DX = Bildschirmzeile<br />
CX = Bildschirmspalte<br />
Ausgabe AL = Farbwert<br />
Der Farbwert richtet sich nach dem aktuellen Grafikmodus. Im 640*200-Punkte-Modus sind nur die Werte 0 und 1 erlaubt.<br />
Im 320*200-Punkte-Modus sind die Werte 0 bis 3 erlaubt, die je nach der angewählten Farbpalette eine bestimmte Farbe<br />
erzeugen. 0 steht dabei für die angewählte Hintergrundfarbe, 1 für die erste Farbe der angewählten Farbpalette, 2 für die<br />
zweite Farbe der Farbpalette usw.<br />
Der Inhalt der Register BX, CX, DX und der Segmentregister SS, CS und DS wird durch diese Funktion nicht verändert. Der<br />
Inhalt aller anderen Register, vor allem der Register SI und DI, kann verändert werden.
Rechnergrundlagen Teil 2 - 48 - Prof. Dipl.-Ing. Komar<br />
Interrupt 10h, Funktion 0Eh Bilds chirm: Schreiben <strong>eines</strong> Zeichens<br />
Ein Zeichen wird an die aktuelle Cursor-Position in der aktuellen Bildschirmseite geschrieben, wobei die Farbe des alten<br />
Zeichens an dieser Bildschirmposition beibehalten wird.<br />
Eingabe AH = 0Eh<br />
AL = ASCII-Code des Zeichens<br />
BL = Vordergrundfarbe des Zeichens (nur im Grafikmodus)<br />
Ausgabe keine Ausgabe<br />
Diese Funktion interpretiert die verschiedenen Steuercodes wie Bell und Carriage Return nicht wie normale ASCII-Codes,<br />
sondern wie besondere Steuercodes und löst z.B. anstatt das Bell-Zeichen auszugeben einen Piepston aus.<br />
Nach der Ausgabe <strong>eines</strong> Zeichens über diese Funktion wird die Cursor-Position inkrementiert, so daß das nächste Zeichen an<br />
der folgenden Bildschirmposition ausgegeben wird. Wird die letzte Bildschirmposition erreicht, dann wird der Bildschirm um<br />
eine Zeile nach oben geschoben und mit der Ausgabe in der ersten Spalte der letzten Bildschirmzeile fortgefahren.<br />
Die Vordergrundfarbe richtet sich nach dem aktuellen Grafikmodus. Im 640*200-Punkte-Modus sind nur die Werte 0 und 1<br />
erlaubt. Im 320*200-Punkte-Modus sind die Werte 0 bis 3 erlaubt, die je nach der angewählten Farbpalette eine bestimmte<br />
Farbe erzeugen. 0 steht dabei für die angewählte Hintergrundfarbe, 1 für die erste Farbe der angewählten Farbpalette, 2 für<br />
die zweite Farbe der Farbpalette usw.<br />
Der Inhalt der Register BX, CX, DX und der Segmentregister SS, CS und DS wird durch diese Funktion nicht verändert. Der<br />
Inhalt aller anderen Register, vor allem der Register SI und DI, kann verändert werden.<br />
Interrupt 10h, Funktion 0Fh Bildschirm: Auslesen des Video-Modus<br />
Die Nummer des aktuellen Video-Modus, die Anzahl der Zeichen pro Zeile und die Nummer der aktuellen Bildschirmseite<br />
wird ausgelesen.<br />
Eingabe AH = 0Fh<br />
Ausgabe AL = Video-Modus (siehe Funktion 00h)<br />
AH = Anzahl der Zeichen pro Zeile<br />
BH = Nummer der aktuellen Bildschirmseite<br />
Der Inhalt der Register BL, CX, DX und der Segmentregister SS, CS und DS wird durch diese Funktion nicht verändert. Der<br />
Inhalt aller anderen Register, vor allem der Register SI und DI, kann verändert werden.<br />
Interrupt 10h, Funktion 13h Bildschirm: Ausgabe einer Zeichenkette<br />
Eine Zeichenkette wird ab einer vorgegebenen Bildschirmposition in einer bestimmten Bildschirmseite auf dem Bildschirm<br />
ausgegeben. Die Zeichen werden dabei einem Puffer entnommen, dessen Adresse der Funktion übergeben wird.<br />
Eingabe AH = 13h<br />
AL = Ausgabemodus (0 - 3)<br />
0 = Attribut in BL, Cursor-Position beibehalten<br />
1 = Attribut in BL, Cursor-Position aktualisieren<br />
2 = Attribut im Puffer, Cursor-Position beibehalten<br />
3 = Attribut im Puffer, Cursor-Position aktualisieren<br />
BL = Attribut-Byte der Zeichen (nur Modi 0 und 1)<br />
CX = Anzahl der auszugebenden Zeichen<br />
DH = Bildschirmzeile<br />
DL = Bildschirmspalte<br />
BH = Bildschirmseite<br />
ES:BP = FAR-Zeiger auf den Puffer<br />
Ausgabe keine Ausgabe<br />
In den Modi 1 und 3 wird die Cursor-Position nach Ausgabe der Zeichenkette hinter das letzte Zeichen der Zeichenkette<br />
gesetzt, so daß bei nachfolgenden Aufrufen einer BIOS-Funktion zur Zeichenausgabe die Zeichen hinter der Zeichenkette<br />
ausgegeben werden. Dies geschieht in den Modi 0 und 2 nicht.<br />
In den Modi 0 und 1 enthält der Puffer nur die ASCII-Codes der auszugebenden Zeichen. Die Farbe aller Zeichen der<br />
Zeichenkette wird in diesem Fall durch das BL-Register angegeben. In den Modi 2 und 3 hingegen folgt auf jedes Zeichen im<br />
Puffer das dazugehörige Attribut-Byte, so daß jedes Zeichen über ein individuelles Attribut verfügt. Das BL-Register braucht<br />
in diesen Modi nicht belegt zu werden. Obwohl in diesen Modi die Zeichenkette doppelt so groß wie die Anzahl der<br />
auszugebenden Zeichen ist, braucht im CX-Register nicht die Länge der Zeichenkette, sondern nur die Anzahl der<br />
auszugebenden ASCII-Zeichen abgespeichert werden.<br />
Die speziellen Steuercodes wie Bell und Carriage Return werden als Steuercodes und nicht als normale ASCII-Codes<br />
interpretiert. Wird die letzte Bildschirmposition erreicht, wird der Bildschirm um eine Zeile nach oben geschoben und mit der<br />
Ausgabe in der ersten Spalte der letzten Bildschirmzeile fortgefahren.<br />
Der Inhalt der Register BX, CX, DX und der Segmentregister SS, CS und DS wird durch diese Funktion nicht verändert. Der<br />
Inhalt aller anderen Register, vor allem der Register SI und DI, kann verändert werden.
Rechnergrundlagen Teil 2 - 49 - Prof. Dipl.-Ing. Komar<br />
Interrupt 14 h (BIOS) Serielle Schnittstelle<br />
Die serielle Schnittstelle, die von DOS COM1 genannt wird, trägt die Nummer 0; COM2 die Nummer 1.<br />
Der Inhalt der Register BX, CX, DX, SI, DI, BP und der Segmentregister wird durch diese Funktionen nicht verändert.<br />
Interrupt 14h, Funktion 00h Serielle Schnittstelle: Initialisierung<br />
Durch Aufruf dieser Funktion kann eine der an den PC angeschlossenen seriellen Schnittstellen initialisiert und konfiguriert<br />
werden. Dabei wird neben der Parität der Übertragung und der Anzahl der Stop-Bits auch die Baud-Rate festgelegt.<br />
Eingabe AH = 00h<br />
DX = Nummer der seriellen Schnittstelle (die erste serielle Schnittstelle COM1 trägt die Nummer 0)<br />
AL = Konfigurationsparameter<br />
Bit 0-1 Datenlänge 10(b) = 7 Bits 11(b) = 8 Bits<br />
Bit 2 Anzahl der Stop-Bits 0(b) = 1 Stop-Bit 1(b) = je nach der Baud-Rate 1,5 oder 2 Stop-Bits<br />
Bit 3-4 Paritätsprüfung 00(b) = keine 01(b) = ungerade 11(b)= gerade<br />
Bit 5-7 Baud-Rate<br />
000(b) = 110 Baud<br />
001(b) = 150 Baud<br />
010(b) = 300 Baud<br />
011(b) = 600 Baud<br />
100(b) = 1200 Baud<br />
101(b) = 2400 Baud<br />
110(b) = 4800 Baud<br />
111(b) = 9600 Baud<br />
Ausgabe AH = Status der seriellen Schnittstelle (Bit x = 1 ) AL = Modemstatus<br />
Bit 0 Daten stehen bereit Bit 0 (Delta) Modem zum Senden bereit (CTS)<br />
Bit 1 Überlauf (Overrun-Error) Bit 1 (Delta) Modem ist angeschaltet (DSR)<br />
Bit 2 Paritätsfehler Bit 2 (Delta) Telefon läutet (RI )<br />
Bit 3 Protokoll nicht eingehalten Bit 3 (Delta) Verbindung zum Empfängermodem<br />
Bit 4 Unterbrechung entdeckt Bit 4 Modem zum Senden bereit (CTS)<br />
Bit 5 Transmission-Hold-Register leer Bit 5 Modem ist angeschaltet (DSR)<br />
Bit 6 Transmission-Shift-Register leer Bit 6 Telefon läutet (RI )<br />
Bit 7 Time Out beim Empfang <strong>eines</strong> Zeichens Bit 7 Verbindung zum Empfängermodem aufgebaut<br />
Die Delta-Bits zeigen die Veränderung des jeweiligen Zustands im Verhältnis zum letzten Aufruf dieser Funktion an. Ist ein<br />
Delta-Bit gesetzt, hat sich der korrespondierende Status in der Zwischenzeit verändert.<br />
Interrupt 14h, Funktion 01h Serielle Schnittstelle: Zeichen ausgeben<br />
Eingabe AH = 01h<br />
DX = Nummer der seriellen Schnittstelle (die erste serielle Schnittstelle trägt die Nummer 0)<br />
AL = Code des auszugebenden Zeichens<br />
Ausgabe AH: Bit 7 = 0: Zeichen wurde übertragen<br />
Bit 7 = 1: Fehler in diesem Fall:<br />
Bit 0-6: Status der seriellen Schnittstelle<br />
Bit 0: Daten stehen bereit<br />
Bit 1: Überlauf<br />
Bit 2: Paritätsfehler<br />
Bit 3: Protokoll nicht eingehalten (framing error)<br />
Bit 4: Unterbrechung entdeckt<br />
Bit 5: Transmission-Hold-Register leer<br />
Bit 6: Transmission-Shift-Register leer<br />
Ist Bit 7 des AH-Registers nach dem Funktionsaufruf gesetzt, spricht man ganz allgemein von einem Time-Out-Error. Die<br />
übrigen Bits spezifizieren dann die genaue Fehlerursache.<br />
Interrupt 14h, Funktion 02h Serielle Schnittstelle: Zeichen einlesen<br />
Empfängt ein Z eichen von der seriellen Schnittstelle.<br />
Eingabe AH = 02h<br />
DX = Nummer der seriellen Schnittstelle (die erste serielle Schnittstelle trägt die Nummer 0)<br />
Ausgabe AH Bit 7 = 0: Zeichen wurde empfangen, in diesem Fall: AL = das empfangene Zeichen<br />
Bit 7 = 1: Fehler, siehe Funktion 01h<br />
Diese Funktion sollte erst dann aufgerufen werden, wenn mit Hilfe der Funktion 03h festgestellt wurde, daß ein Zeichen zum<br />
Empfang bereitsteht.
Rechnergrundlagen Teil 2 - 50 - Prof. Dipl.-Ing. Komar<br />
Interrupt 14h, Funktion 03h Serielle Schnittstelle: Status erfragen<br />
Fragt den Status der seriellen Schnittstelle und des evtl. angeschlossenen Modems ab.<br />
Eingabe AH = 03h<br />
DX = Nummer der seriellen Schnittstelle (die erste serielle Schnittstelle trägt die Nummer 0)<br />
Ausgabe AH = Status der seriellen Schnittstelle, siehe Funktion 00h<br />
AL = Modem-Statusregister, siehe Funktion 00 h.<br />
Diese Funktion sollte immer vor Aufruf der Funktion 02h (Zeichen empfangen) aufgerufen werden, um festzustellen, ob ein<br />
Zeichen zum Empfang bereit steht. In diesem Fall ist das Bit 0 im AH-Register 1.<br />
Interrupt 14h, Funktion 05h Kontrolle der seriellen Schnittstelle ( ab dem PS/2 – BIOS )<br />
Unterfunktion 00 - Modem Control Register lesen<br />
Aufruf: AH = 05h<br />
AL = 00h<br />
DX = Nummer der seriellen Schnittstelle<br />
Rückgabe: AH = Status der seriellen Schnittstelle, siehe Funktion 00<br />
AL = Modem-Statusregister , siehe Funktion 00<br />
BL = Modem-Control-Register<br />
Bit 7 – 5 reserviert (Null zurück)<br />
Bit 4 = 1, Loopback-Kontrolle =Selbsttest. Gesendete Zeichen als Input zurück<br />
Bit 3 = 1, OUT2 aktiv = es werden Interrupts generiert<br />
Bit 2 = 1, OUT1 aktiv<br />
Bit 1 = 1, RTS aktiv = PC will ein Zeichen an das Modem senden<br />
Bit 0 = 1, DTR aktiv = PC ist bereit<br />
Unterfunktion 01 - Modem Control Register setzen<br />
Aufruf: AH = 05h<br />
AL = 01h<br />
DX = Nummer der seriellen Schnittstelle<br />
BL = Modem-Control-Register setzen, siehe Funktion 05h, Unterfunktion 00h<br />
Rückgabe: AH = Status der seriellen Schnittstelle, siehe Funktion 00<br />
AL = Modem-Statusregister , siehe Funktion 00<br />
Interrupt 16 h (BIOS) Tastatur<br />
Interrupt 16h, Funktion 00h Tastatur: Zeichen auslesen<br />
Die Funktion liest ein Zeichen aus dem Tastaturpuffer aus. Ist dort kein Zeichen abgespeichert, wartet die Funktion, bis ein<br />
Zeichen eingegeben wurde. Das ausgelesene Zeichen wird aus dem Tastaturpuffer entfernt.<br />
Eingabe AH = 00h<br />
Ausgabe AL = 0: Erweiterter Tastaturcode, in diesem Fall:<br />
AH = erweiterter Tastaturcode<br />
0: Normale Taste betätigt, in diesem Fall:<br />
AL = ASCII-Code der Taste<br />
AH = Scan-Code der Taste<br />
Während der ASCII-Code <strong>eines</strong> Zeichens unabhängig von der Tastatur definiert ist, gilt der Scan-Code nur für den Typ von<br />
Tastatur, die an den PC angeschlossen ist.<br />
Der Inhalt der Register CX, DX, SI, DI, BP und der Segmentregister wird durch diese Funktion nicht verändert. Der Inhalt<br />
aller anderen Register kann verändert werden.<br />
Interrupt 16h, Funktion 01h Tastatur: Zeichen vorhanden?<br />
Diese Funktion stellt fest, ob ein Zeichen im Tastaturpuffer enthalten ist. Ist dem so, liefert sie dieses Zeichen an die<br />
aufrufende Funktion zurück. Das Zeichen wird allerdings nicht aus dem Tastaturpuffer entfernt, so daß es durch nochmaligen<br />
Aufruf der Funktion 1 oder 0 erneut ausgelesen werden kann. In jedem Fall kehrt d ie Funktion sofort nach ihrem Aufruf in<br />
das aufrufende Programm zurück.<br />
Eingabe AH = 01h<br />
Ausgabe Zero -Flag = 1: Kein Zeichen im Tastaturpuffer<br />
Zero -Flag = 0: Zeichen vorhanden, in diesem Fall:<br />
AL = 0: Erweiterter Tastaturcode, in diesem Fall:<br />
AH = Erweiterter Tastaturcode<br />
AL 0: Normale Taste, in diesem Fall:<br />
AL = ASCII-Code der Taste<br />
AH = Scan-Code der Taste
Rechnergrundlagen Teil 2 - 51 - Prof. Dipl.-Ing. Komar<br />
Während der ASCII-Code <strong>eines</strong> Zeichens unabhängig von der Tastatur definiert ist, gilt der Scan-Code nur für den Typ von<br />
Tastatur, der an den PC angeschlossen ist.<br />
Der Inhalt der Register BX, CX, DX, SI, DI, BP und der Segmentregister wird durch diese Funktion nicht verändert. Der<br />
Inhalt aller anderen Register kann verändert worden sein.<br />
Interrupt 16h, Funktion 02h Tastatur: Status der Tastatur erfragen<br />
Die Stellung bestimmter Steuertasten und der Status verschiedener Tastaturmodi wird durch Aufruf dieser Funktion<br />
abgefragt.<br />
Eingabe AH = 02h<br />
Ausgabe AL = Tastaturstatus-Byte<br />
Aufbau des Tastaturstatus-Byte Bit 0 = 1 rechte Shift-Taste betätigt<br />
Bit 1 = 1 linke Shift-Taste betätigt<br />
Bit 2 = 1 Ctrl - Taste betätigt<br />
Bit 3 = 1 Alt – Taste betätigt<br />
Bit 4 = 1 Scroll-Lock an<br />
Bit 5 = 1 Num-Lock an<br />
Bit 6 = 1 Caps-Lock an<br />
Bit 7 = 1 Insert an<br />
Der Inhalt der Register BX, CX, DX, SI, DI, BP und der Segmentregister wird durch diese Funktion nicht verändert. Der<br />
Inhalt aller anderen Register kann verändert werden.<br />
Interrupt 16h, Funktion 03h Tastatur: Wiederholrate einstellen<br />
Mit Hilfe dieser Funktion kann auf die Tastaturwiederholung Einfluß genommen werden, die automatisch einsetzt, wenn e ine<br />
Taste über eine bestimmte Zeitspanne hinaus gedrückt wird.<br />
Eingabe AH = 03h<br />
AL = 05h<br />
BH = Verzögerung, bis die Wiederholung einsetzt<br />
BL = Wiederholungsrate<br />
Ausgabe keine<br />
Achtung! Diese Funktion wird nicht von jedem BIOS unterstützt.<br />
Für die Verzögerungsdauer im BL-Register können folgende Werte angegeben werden:<br />
Code Delay-Rate<br />
00h 1/4 Sekunde<br />
01h 1/2 Sekunde<br />
10h 1/4 Sekunde<br />
11h 1 Sekunde<br />
Für die Wiederholrate im BH-Register können folgende Werte angegeben werden:<br />
Code WpS Code WpS Code WpS Code WpS<br />
1Fh 2,0 17h 4,0 0Fh 8,0 07h 16,0<br />
1Eh 2,1 16h 4,3 0Eh 8,6 06h 17,1<br />
1Dh 2,3 15h 4,6 0Dh 9,2 05h 18,5<br />
1Ch 2,5 14h 5,0 0Ch 10,0 04h 20,0<br />
1Bh 2,7 13h 5,5 0Bh 10,9 03h 21,8<br />
1Ah 3,0 12h 6,0 0Ah 12,0 02h 24,0<br />
19h 3,3 11h 6,7 09h 13,3 01h 26,7<br />
18h 3,7 10h 7,5 08h 15,0 00h 30,0<br />
WpS = Wiederholungen pro Sekunde<br />
Wiederholrate im BH-Register<br />
Der Inhalt der Register BX, CX, DX, SI, DI, BP und der Segmentregister wird durch diese Funktion nicht verändert. Der<br />
Inhalt aller anderen Register kann verändert werden.
Rechnergrundlagen Teil 2 - 52 - Prof. Dipl.-Ing. Komar<br />
Interrupt 16h, Funktion 05h Tastatur: Tastendruck simulieren<br />
Diese Funktion bietet einem Programm die Möglichkeit, die Betätigung einer Tastatur zu simulieren, indem ein bestimmter<br />
Tastencode an das aktuelle Ende des Tastaturpuffers angehängt wird.<br />
Eingabe AH = 05h<br />
CH = Scan-Code der Taste<br />
CL = ASCII-Code der Taste<br />
Ausgabe AL = 00h : O.k.<br />
AL = 01h : Tastatur-Puffer voll, kein Anhängen möglich<br />
Achtung! Diese Funktion wird nicht von jedem BIOS unterstützt.<br />
Der Inhalt der Register BX, CX, DX, SI, DI, BP und der Segmentregister wird durch diese Funktion nicht verändert. Der<br />
Inhalt aller anderen Register kann verändert werden.<br />
Interrupt 16h, Funktion 10h Tastatur: Tastaturabfrage für erweiterte Tastaturen<br />
Speziell für die Abfrage von erweiterterten Tastaturen (F11 + F12) mit 101 bzw. 102 Tasten steht diese Funktion zur<br />
Verfügung. Sie arbeitet wie die Funktion 00h, bildet die Scan-Codes der Tasten aber nicht auf das Layout einer normalen<br />
Tastatur mit 84 Tasten an.<br />
Eingabe AH = 10h<br />
Ausgabe AH = Scan-Code der Taste<br />
AL = ASCII-Code der Taste<br />
Achtung! Diese Funktion wird nicht von jedem BIOS unterstützt.<br />
Der Inhalt der Register BX, CX, DX, SI, DI, BP und der Segmentregister wird durch diese Funktion nicht verändert. Der<br />
Inhalt aller anderen Register kann verändert werden.<br />
Interrupt 17 h (BIOS) Parallele Schnittstelle<br />
Die erste an den PC angeschlossene parallele Schnittstelle trägt die Nummer 0 und wird auf DOS-Ebene als LPT1:<br />
bezeichnet. Der Inhalt der Register BX, CX, DX, SI, DI, BP und der Segmentregister wird durch die Funktionen des Interrupt<br />
17h nicht verändert. Der Inhalt aller anderen Register kann verändert werden.<br />
Interrupt 17h, Funktion 00h Parallele Schnitts telle: Zeichen ausgeben<br />
Durch Aufruf dieser Funktion wird ein Zeichen auf der parallelen Schnittstelle ausgegeben. In der Regel wird das Zeichen<br />
dadurch an einen Drucker gesandt.<br />
Eingabe AH = 00h<br />
AL = Code des auszugebenden Zeichens<br />
DX = Nummer der Schnittstelle<br />
Ausgabe AH = Druckerstatus<br />
Der Druckerstatus in AH muß als Bitfeld nach folgendem Format interpretiert werden:<br />
Bit 0 = 1 Time-Out-Fehler<br />
Bit 3 = 1 Übertragungs-Fehler<br />
Bit 4 = 1 Drucker ON-LINE<br />
Bit 5 = 1 Drucker hat kein Papier<br />
Bit 6 = 1 Empfangsbestätigung<br />
Bit 7 = 0 Drucker ist beschäftigt<br />
Aufbau des Status-Byte des Druckers<br />
Interrupt 17h, Funktion 01h Parallele Schnittstelle: Schnittstelle initialisieren<br />
Durch Aufruf dieser Funktion wird eine parallele Schnittstelle und mit ihr der daran angeschlossene Drucker initialisiert.<br />
Dies sollte jeweils vor der ersten Übertragung <strong>eines</strong> Zeichens geschehen.<br />
Eingabe AH = 01h<br />
DX = Nummer der Schnittstelle<br />
Ausgabe AH = Druckerstatus: siehe Funktion 00h<br />
Interrupt 17h, Funktion 02h Parallele Schnittstelle: Status der Schnittstelle abfragen<br />
Aufgabe dieser Funktion ist es, den Status einer parallelen Schnittstelle und <strong>eines</strong> daran angeschlossenen Druckers<br />
zurückzuliefern.<br />
Eingabe AH = 02h<br />
DX = Nummer der Schnittstelle<br />
Ausgabe AH = Druckerstatus: siehe Funktion 00h
Rechnergrundlagen Teil 2 - 53 - Prof. Dipl.-Ing. Komar<br />
Interrupt 1A h (BIOS) Datum und Uhrzeit<br />
Interrupt 1Ah, Funktion 00h Datum und Zeit: Zeitzähler auslesen<br />
Mit Hilfe dieser Funktion wird der Inhalt des Zeitzählers ausgelesen. Er wird 18,2 mal in der Sekunde erhöht. Dadurch läßt<br />
sich über ihn die seit dem Anschalten des Rechners bzw. seit 0 Uhr vergangene Zeit berechnen.<br />
Eingabe AH = 00h<br />
Ausgabe CX = Hi-Word des Zeitzählers<br />
DX = Lo-Word des Zeitzählers<br />
AL = 0: Seit dem letzten Auslesen der Uhrzeit sind weniger als<br />
24 Stunden vergangen.<br />
AL 0: Seit dem letzten Auslesen der Uhrzeit sind mehr als 24 Stunden<br />
vergangen. In diesem Fall spiegelt der Inhalt dieses Registers<br />
die Anzahl der vergangenen Tage wieder.<br />
Der AT, der über eine batteriegepufferte Uhr verfügt, setzt beim Booten des Rechners den Zeitzähler auf die aktuelle Uhrzeit.<br />
PCs, die nicht über eine solche Uhr verfügen, setzen ihn beim Booten auf 0.<br />
Der Inhalt der Register BX, SI, DI, BP und der Segmentregister wird durch diese Funktion nicht verändert. Der Inhalt aller<br />
anderen Register kann verändert werden.<br />
Interrupt 1Ah, Funktion 01h Datum und Zeit: Zeitzähler setzen<br />
Mit Hilfe dieser Funktion wird der Inhalt des Zeitzählers gesetzt. Er wird 18,2 mal in der Sekunde erhöht. Dadurch läßt sich<br />
über ihn die seit dem Anschalten des Rechners bzw. seit 0 Uhr vergangene Zeit berechnen bzw. mit Hilfe dieser Funktion<br />
einstellen.<br />
Eingabe AH = 01h<br />
CX = High-Word des Zeitzählers<br />
DX = Low -Word des Zeitzählers<br />
Ausgabe keine<br />
Der AT, der über eine batteriegepufferte Uhr verfügt, setzt beim Booten des Rechners den Zeitzähler auf die aktuelle Uhrzeit.<br />
PCs, die nicht über eine solche Uhr verfügen, setzen ihn beim Booten auf 0. Aus diesem Grund sollte bei diesen PCs die Zeit<br />
mit Hilfe dieser Funktion auf die aktuelle Uhrzeit gesetzt werden.<br />
Der Inhalt der Register AX, BX, CX, DX, SI, DI, BP und der Segmentregister wird durch diese Funktion nicht verändert. Der<br />
Inhalt aller anderen Register kann verändert werden.<br />
Interrupt 1Ah, Funktion 02h Datum und Zeit: Auslesen der Echtzeituhr<br />
Die Uhrzeit wird aus der batteriegepufferten Echtzeituhr ausgelesen.<br />
Eingabe AH = 02h<br />
Ausgabe Carry -Flag = 0: O.k., in diesem Fall: CH = Stunde<br />
CL = Minute<br />
DH = Sekunde<br />
Carry -Flag = 1: Batterie der Uhr ist leer<br />
Alle Angaben werden im BCD-Format zur Verfügung gestellt. Der Inhalt der Register BX, SI, DI, BP und der<br />
Segmentregister wird durch diese Funktion nicht verändert. Der Inhalt aller anderen Register kann verändert werden.<br />
Interrupt 1Ah, Funktion 03h Datum und Zeit: Setzen der Echtzeituhr<br />
Die Uhrzeit der batteriegepufferten Echtzeituhr wird mit dieser Funktion gesetzt.<br />
Eingabe AH = 03h<br />
CH = Stunde<br />
CL = Minute<br />
DH = Sekunde<br />
DL = 1: Sommerzeit<br />
DL = 0: Keine Sommerzeit<br />
Ausgabe keine<br />
Die Angaben der Stunde, Minute und Sekunde müssen im BCD-Format vorliegen. Der Inhalt der Register BX, SI, DI, BP<br />
und der Segmentregister wird durch diese Funktion nicht verändert. Der Inhalt aller anderen Register kann verändert werden.<br />
Interrupt 1Ah, Funktion 04h Datum und Zeit: Auslesen des Datums aus der Echtzeituhr<br />
Das aktuelle Datum, das im RAM-Speicher der batteriegepufferten Echtzeituhr gespeichert ist, wird mit dieser Funktion<br />
ausgelesen. Diese Funktion wird nur vom AT unterstützt.<br />
Eingabe AH = 04h<br />
Ausgabe Carry -Flag = 0: O.k., in diesem Fall:<br />
CH = Jahrhundert (19 or 20)<br />
CL = Jahr<br />
DH = Monat<br />
DL = Tag<br />
Carry -Flag = 1: Batterie der Uhr ist leer
Rechnergrundlagen Teil 2 - 54 - Prof. Dipl.-Ing. Komar<br />
Alle Angaben, die von der Funktion zurückgeliefert werden, erfolgen im BCD-Format.<br />
Der Inhalt der Register BX, SI, DI, BP und der Segmentregister wird durch diese Funktion nicht verändert. Der Inhalt aller<br />
anderen Register kann verändert werden.<br />
Interrupt 1Ah, Funktion 06h Datum und Zeit: Alarmzeit setzen<br />
Eine Alarmzeit, die sich immer auf den aktuellen Tag bezieht, kann mit Hilfe dieser Funktion gesetzt werden. Bei Erreichen<br />
dieser Zeit wird der Interrupt 4Ah ausgelöst. Die batteriegepufferte Echtzeituhr; ist nur in ATs vorhanden.<br />
Eingabe AH = 06h<br />
CH = Stunde<br />
CL = Minute<br />
DH = Sekunde<br />
Ausgabe Carry -Flag = 0: O.k.<br />
Carry -Flag = 1: Entweder ist die Batterie der Uhr leer, oder es ist<br />
bereits eine Alarmzeit programmiert.<br />
Alle Angaben, die der Funktion übergeben werden, müssen im BCD-Format kodiert sein.<br />
Der Interrupt 4Ah wird beim Booten auf einen Maschinensprache-IRET-Befehl gelegt. Wird er nicht auf eine spezielle<br />
Routine umg elegt, geschieht dadurch bei Erreichen der Alarmzeit nichts. Es kann immer nur eine Alarmzeit gleichzeitig aktiv<br />
sein. Ist bereits eine Alarmzeit programmiert, muß diese zunächst mit Hilfe der Funktion 7 gelöscht werden.<br />
Der Inhalt der Register BX, CX, SI, DI, BP und der Segmentregister wird durch diese Funktion nicht verändert. Der Inhalt<br />
aller anderen Register kann verändert werden.<br />
Interrupt 1Ah, Funktion 07h Datum und Zeit: Alarmzeit löschen<br />
Mit Hilfe dieser Funktion kann eine einprogrammierte Alarmzeit wieder gelöscht werden. Bei Erreichen dieser Zeit wird<br />
dann kein Alarm mehr ausgelöst (ab AT).<br />
Eingabe AH = 07h<br />
Ausgabe keine<br />
Diese Funktion muß auch immer dann aufgerufen werden, wenn die Alarmzeit geändert werden soll. In diesem Fall kann erst<br />
nach Aufruf dieser Funktion durch Aufruf der Funktion 6 eine neue Alarmzeit programmiert werden.<br />
Der Inhalt der Register BX, CX, SI, DI, BP und der Segmentregister wird durch diese Funktion nicht verändert. Der Inhalt<br />
aller anderen Register kann verändert werden.<br />
Der Ctrl-Break -Interrupt 23h<br />
wird nach einer unvorhergesehenen Anwender- Betätigung von [Control]+[Break] bzw. [Control]+[C] durch DOS<br />
aufgerufen und der Interrupt-Vektor zeigt beim Start <strong>eines</strong> Programmes auf eine DOS-Routine, die die Beendigung des<br />
Programmes herbeiführt.<br />
Doch steht es einem Programm frei, diesen Interrupt-Vektor auf eine eigene Routine umzuleiten und dadurch die Kontrolle<br />
über die Abläufe bei der Betätigung von [Ctrl]+[Break] selbst in die Hand zu nehmen.<br />
Der Aufruf dieses Interrupts ist jedoch nicht unmittelbar mit der Betätigung einer der beiden Tastenkombinationen<br />
verbunden. Vielmehr ist der Zeitpunkt, an dem DOS die Betätigung einer der beiden Tastenkombinationen überprüft, vom<br />
sogenannten Break-Flag abhängig. Dieses Flag kann zum einen über die DOS-Oberfläche mit dem Befehl BREAK<br />
(ON/OFF), und zum anderen mit Hilfe der DOS -Funktion 33h, Unterfunktion 01h, gesetzt oder gelöscht werden.<br />
Ist es gesetzt, wird bei jedem Aufruf einer Funktion des DOS-Interrupts 21h im Tastaturpuffer nach dem Tastencode von<br />
[Ctrl]+[Break] bzw. [Ctrl]+[C] gefahndet. Ist das Break-Flag hingegen gelöscht, erfolgt diese Überprüfung nur beim Aufruf<br />
der DOS-Funktionen, die dem Zugriff auf das Standard -Ein- oder -Ausgabegerät dienen.<br />
Soll die Betätigung von [Ctrl]+[Break] oder [Ctrl]+[C] hingegen ignoriert werden, muß die Kontrolle lediglich mit Hilfe des<br />
IRET-Maschinensprache-Befehls an das DOS zurückgegeben werden. Allerdings muß das Programm in diesem Fall dafür<br />
Sorge tragen, daß alle Prozessor-Regis ter die Werte enthalten, die sie auch beim Aufruf des Interrupts 23h aufwiesen.<br />
Andernfalls kann die ursprünglich aufgerufene DOS-Funktion nicht einwandfrei beendet werden.<br />
Der Critical -Error -Interrupt 24h<br />
ist meist die Reaktion auf einen Fehler. der beim Zugriff auf ein externes Gerät aufgetreten ist.<br />
Um den verschiedenen Fehlerkategorien Rechnung zu tragen, zeigt der Critical-Error-Interrupt, der Interrupt 24h,<br />
normalerweise auf eine DOS-Routine, die in der englischen DOS-Version die bekannte Meldung " (A)bort, (R)etry, (I)gnore"<br />
("Abbrechen, Wiederholen, Ignorieren") auf dem Bildschirm ausgibt und auf die Eingabe des Anwenders wartet.
Rechnergrundlagen Teil 2 - 55 - Prof. Dipl.-Ing. Komar<br />
7. 4 Serielle, asynchrone Kommunikation über die RS232C/V.24-Schnittstelle<br />
Jeder Rechner verfügt über eine oder mehrere RS232C- bzw V.24-Schnittstellen, über die Daten asynchron<br />
seriell übertragen werden ( d.h. die einzelnen Datenbit werden nacheinander für die Bitzeit auf die Leitung<br />
gelegt, wobei die Synchronisation der beiden Partner durch Start- und Stoppbits erfolgt ).<br />
Die beiden Standards RS232C und V24 unterscheiden sich praktisch nur durch die Leitungsbezeichnungen und<br />
sind für den bidirektionalen Datenverkehr zwischen einer Datenendeinrichtung DTE ( Data Terminal<br />
Equipment ) und einem Modem DCE ( Data Communication Equipment ) konzipiert und genormt.<br />
Der Standard definiert 25 Signale, wovon aber nur die folgenden in der Praxis genutzt werden:<br />
Die wichtigsten RS232C-Signale einer DTE ( Endgerät z.B. Rechner PC )<br />
DTE<br />
25 polig 9 polig Signalbezeichnung<br />
Pin-Nr. Pin-Nr.<br />
2 3 TxD �� Transmit Data Sendedaten<br />
3 2 RxD �� Receive Data Empfangsdaten<br />
7 5 GND - Ground Signalmasse<br />
4 7 RTS �� Request To Send Sendeteil einschalten<br />
5 8 CTS �� Clear To Send Sendebereitschaft<br />
6 6 DSR �� Data Set Ready Betriebsbereitschaft<br />
20 4 DTR �� Data Terminal Ready Endgerät betriebsbereit<br />
8 1 DCD �� Data Carrier Detect Empfangssignalpegel<br />
Die Signal-Paare RTS / CTS und DSR / DTR sind Hardware -"Handshake"-Leitungen (Anforderung /<br />
Bestätigung ) über die der Datenfluß gesteuert oder die Betriebsbereitschaft gegenseitig mitgeteilt werden kann.<br />
Für Rechner-Rechner-Verbindungen (heute allgemein DTE-DTE-Verbindungen ) benötigt man sogn.<br />
Nullmodemkabel, bei denen die gekreuzten Adern typisch sind.<br />
Beim sogn. universellen Null-Modem-Kabel sind alle Signal und Steuerleitungen gekreuzt durchverbunden,<br />
wohingegen beim einfachsten 3-Draht-Nullmodemkabel nur die drei Signalleitungen TxD,RxD und GND<br />
gekreuzt durchverbunden und die Steuerleitungen im Stecker so gebrückt sind, daß die von der Gegenseite<br />
erwarteten Steuersignale durch die eigenen "vorgetäuscht" werden.<br />
Da hierbei keine Leitungen für einen Hardware-Handshake zur Datenflußkontrolle vorhanden sind, benutzt man<br />
einen Software-Handshake mit den beiden ASCII-Steuerzeichen<br />
- ASCII #19 : XOFF<br />
- ASCII #17 : XON<br />
Kann der Empfänger die eintreffenden Daten nicht mehr schnell genug verarbeiten, sendet er XOFF. Der Sender<br />
"hört" während der Sendung seine RxD-Leitung ab. Empfängt er das Zeichen "XOFF", stoppt er seine Sendung<br />
solange, bis der Empfänger mit "XON" signalisiert, daß er zur weiteren Datenaufnahme bereit ist.<br />
DTE DTE DTE DTE<br />
TxD TxD TxD TxD<br />
RxD RxD RxD RxD<br />
GND GND GND GND<br />
RTS RTS RTS RTS<br />
CTS CTS CTS CTS<br />
DSR DSR DSR DSR<br />
DTR DTR DTR DTR<br />
DCD DCD DCD DCD<br />
3-Draht Nullmodemverbindung Universelle Nullmodemverbindung
Rechnergrundlagen Teil 2 - 56 - Prof. Dipl.-Ing. Komar<br />
Die RS232C/V.24 – Schnittstelle arbeitet bipolar mit +12V/-12V-Spannungspegeln ( Low/High-Logikpegel )<br />
und die maximale Leitungslänge von Verbindungskabeln ist auf 15 m begrenzt.<br />
Die DTE hat Stifte und ein Nullmodemkabel hat somit an beiden Enden Buchsen.<br />
Kommunikations-Steuerung zwischen DTE und DCE (Modem) mittels Steuerleitungen (Handshake ).<br />
Die Kommunikation zwischen serieller Schnittstelle ( UART -Baustein ) und Modem erfolgt über vier<br />
Steuerleitungen. Darunter die beiden Leitungen DTR (Data Terminal Ready ) und RTS ( Ready To Send ), die<br />
vom PC zum Modem führen und sich über die Bits 0 und 1 im Modem-Control-Register des UART (Int 14 h<br />
Funktion 05h, Unterfunktion 01h ) steuern lassen.<br />
Gemäß dem RS-232-Protokoll muß der PC dabei zunächst das DTR-Flag auf 1 setzen, damit das Modem<br />
erkennt, daß der PC bereit ist.<br />
Anschließend muß der PC auch das RTS-Flag auf 1 setzen, damit das Modem von der gewünschten<br />
Zeichenübertragung in Kenntnis gesetzt wird.<br />
In beiden Fällen sollte das Modem durch Setzen der entsprechenden Handshake-Signale antworten.<br />
Werden die DTR- und die RTS-Leitung gesetzt, funkt das Modem über die DSR- (auf DTR) und die CTS- (auf<br />
RTS ) Leitung zurück. Abfragen läßt sich dies über die Bits 4 und 5 im Modem Status Register. Sie spiegeln<br />
permanent den Status dieser beiden Leitungen wider.<br />
Aber auch der Status der Leitungen DCD und RI kann über das Modem-Status-Register abgefragt werden. Hier<br />
sind es die Bits 6 und 7, die dem Abfrager mitteilen, ob ein Anruf am Modem empfangen wird ( RI ) bzw. am<br />
anderen Ende der Leitung ein Modem hängt ( Data Carrier Detect DCD ).<br />
Da die Kommunikation zwischen zwei DTE (Rechner PC) ohne Modem stattfindet, werden im 3-Draht-<br />
Nullmodemkabel die Steuersignale so gebrückt, daß vom eigenen Steuersignal das erwartete Handshakesignal<br />
<strong>eines</strong> Modems "vorgetäuscht" wird.<br />
Beim universellen Nullmodemkabel werden die Steuersignalleitungen so gekreuzt, daß die Signale des anderen<br />
DTE die benötigte DCE-Reaktion "vortäuschen".<br />
Abseits von DTR und RTS läßt sich die serielle Schnittstelle mittels des Bit 4 im Modem-Control-Register in<br />
den sogenannten "Loopback-Modus" schalten ( Int 14 h Funktion 05h, Unterfunktion 01h ).<br />
Er unterstützt den Programmierer bei der Entwicklung von Programmen, die über die serielle Schnittstelle mit<br />
anderen Geräten kommunizieren. Nach dem Einschalten dieses Flags leitet der UART alle Ausgaben in das<br />
Empfangsregister um. Man benötigt also kein angeschlossenes Gerät mehr, um die Fähigkeit s<strong>eines</strong> Programms<br />
zu testen und auf den Empfang von Zeichen zu reagieren. Es genügt, selbständig Zeichen auszugeben, um damit<br />
den Empfang von Zeichen zu emulieren.<br />
Ist der Interrupt-Modus aktiv (OUT2 = 1), werden sogar die entsprechenden Interrupts ausgelöst.<br />
Terminalemulation und Kommunikationsprogramme.<br />
Unter Terminalemulation versteht man die Reduktion eine Arbeitsplatzrechners PC durch ein Programm auf die<br />
Funktionalität <strong>eines</strong> "dummen Terminals" um z.B. über die serielle Schnittstelle mit einer zentralen Rechen -<br />
anlage zu kommunizieren. Der PC kann somit einerseits lokal unter einem Betriebssystem arbeiten , andererseits<br />
durch ein Terminalprogramm direkt mit dem Host kommunizieren.<br />
Werden durch die Software auf dem PC die speziellen Eigenarten <strong>eines</strong> bestimmten Terminals nachgebildet, so<br />
spricht man von einer Terminalemulation (Verbreitet VT100 Emulation des DEC VT100 oder die 3270-<br />
Emulation des IBM 3270-Terminals.)<br />
Bei der Terminalemulation wird bei jedem Tastendruck das entsprechende ASCII-Zeichen über die TxD-<br />
Leitung der RS232-Schnittstelle gesendet und über RxD empfangene Zeichen werden am Bildschirm dargestellt.<br />
Alternativ können auch Daten von der Festplatte / Diskette gesendet und empfangen werden.<br />
Da die DOS und BIOS-Funktionen ( INT 14h ) für die serielle Übertragung jedes einzelnen Zeichens den<br />
gesamten Hardware -Handshake-Zyklus der Kommunikation zwischen DTE ( Rechner ) und DCE ( Modem)<br />
durchführen, ist die Übertragung mit diesen Funktionen vergleichsweise langsam (max. 9600 Bd ) und erfordert<br />
unbedingt ein Nullmodemkabel zwischen den beiden Rechnern. (eine einfache 3-Draht-Verbindung reicht nicht<br />
aus).<br />
Bei der Terminal-Emulation-Realisierung mit Hilfe der BIOS-Funktionen (Int 14h) ist ein 3-Draht-Nullmodem –<br />
kabel mit seinen gebrückten Steuerleitungen am besten geeignet. Mit den gekreuzt durchverbundenen<br />
Steuersignalen des universellen Nullmodemkabels können bei Verwendung der BIOS-Funktionen Probleme<br />
auftreten.
Rechnergrundlagen Teil 2 - 57 - Prof. Dipl.-Ing. Komar<br />
Anhang: Gleitpunktrechnung mit der Floating-Point-Einheit FPU ( Coprozessor 80x87 )<br />
Ab dem 80486 verfügen die INTEL-Prozessoren über eine On-Chip-FPU. Bis dahin mußten die Gleitpunktoperationen<br />
entweder mit einem zusätzlichen Arithmetik-Coprozessor 80x87 oder durch softwaremäßige<br />
Emulation (viel Speicherplatz, hoher Rechenzeitverbrauch, langsam !!! ) unterstützt werden.<br />
Die 80x87-Coprozessoren hängen parallel zum jeweiligen Prozessor am Systembus und führen die für sie<br />
bestimmten Befehle aus.<br />
Beim Einsatz von Coprozessoren wird die zeitliche Synchronisation zwischen FPU und CPU mit Hilfe der<br />
WAIT-Befehle ausgeführt, wobei die WAIT-Codes weitgehend automatisch von den jeweiligen Assemblern<br />
erzeugt werden. Durch die Integration der FPU ( ab Prozessor 80486) wird die Synchronisation zwischen IU<br />
( Integer Unit ) und der FPU durch den Prozessor automatisch durchgeführt und dadurch ist der spezielle<br />
Synchronisationscode FWAIT = 9B h vor den Floating-Point-Befehlen nicht mehr nötig und wird auch von den<br />
Assemblern nicht mehr generiert.<br />
Für den Assemblerprogrammierer erscheint die FPU nur als eine Erweiterung des Programmiermodells, denn<br />
um die Kommunikation und Synchronisation zwischen CPU und FPU muß er sich n icht kümmern. Die FPU<br />
erscheint wie ein zusätzlicher Satz von Registern und Datentypen mit einer Menge von zusätzlichen Befehlen,<br />
die auf diesen Registern operieren.<br />
Die CPU identifiziert die Befehle für die FPU durch das Bitmuster 1 1011 b ( 1Bh -> ESC ) das den FPU-<br />
Numerik-Befehlen vorangestellt ist ( ESCAPE-Befehle oder ESC-Befehle).<br />
Die Berechnung und Ausgabe der Datenadressen übernimmt die CPU und den Rest des Befehles führt die FPU<br />
aus. Die von der FPU zu verarbeitenden Zahlen stehen entweder im Arbeitsspeicher oder in den Stapelregistern<br />
der FPU. Eine Verbindung zwischen den Registern der beiden Prozessoren kann nur über den Arbeitsspeicher<br />
hergestellt werden.<br />
Die FPU rechnet intern nur mit dem einheitlichen 80-Bit-Datenformat, das dem Datenformat TEMPORARY<br />
REAL (64-Bit-Mantisse, 15-Bit-Charakteristik, 1 Bit Vorzeichen ) entspricht. Da alle arithmetischen<br />
Operationen intern nur in diesem Format durchgeführt werden, muß bei der Übertragung der Operanden von und<br />
zum Arbeitsspeicher eine Formatumwandlung in dieses interne FPU-Datenformat durchgeführt werden.<br />
Numerik-Register<br />
Der FPU-Register-Stapel (Stack) besteht aus acht 80-Bit-Registern im Temporary -Real-Format mit 1Bit-Vor -<br />
zeichen, 15 Bit Charakteristik und 64 Bit-Mantisse. Der Push-Down Stack adressiert die 8 Register zyklisch.<br />
Tag-Feld Datenfeld (80-Bit – Temporary Real-Format )<br />
Vorz. Exponent Mantisse<br />
1 0 79 78 64 63 0<br />
R7 ST(2)<br />
R6 ST(1)<br />
R5 ST(0) = ST<br />
_ _<br />
_ _<br />
R2 ST(5)<br />
R1 ST(4)<br />
R0 ST(3)<br />
FPU–Register-Stapel<br />
15 0<br />
Steuerregister Environment (Umgebung , 14 Byte für 8087/80287 )<br />
28 Byte ab 80387 im 32Bit-Modus )<br />
Statusregister<br />
Tag-Wort<br />
Befehlszähler Befehlszeiger<br />
Datenzeiger Operandenzeiger
Rechnergrundlagen Teil 2 - 58 - Prof. Dipl.-Ing. Komar<br />
Die Adressierung der Stack-Register übernimmt der sogn. Numerik-Stackpointer, der immer auf die<br />
augenblickliche Spitze ( Top, ST = ST(0) ) des Stapels zeigt. Die 3 Bit des Numerik-Stackpointers befinden<br />
sich im FPU-Statusregister an den Bitpositionen 11-13 und kennzeichnen mit ihrem Wert ein Rx-Register als<br />
das augenblickliche Stack-Top-Register ST(0) = ST.<br />
Die 8 Stapelregister R0-R7 bilden einen "Ring". Bei einem Befehl, der mit einem "PUSH" verbunden ist, rückt<br />
das unterste Register an die oberste Stelle und wird mit einem neuen Wert überschrieben. Bei einem "POP"-<br />
Befehl rückt das oberste Register an die unterste Stelle und wird als leer gekennzeichnet.<br />
FPU-Statuswort<br />
stellt den augenblicklichen Betriebszustand der FPU dar.<br />
15 14 7 6 5 4 3 2 1 0<br />
B C3 ST C2 C1 C0 ES SF PE UE OE ZE DE IE<br />
B: Busy-Bit 0 = FPU nicht aktiv 1 = aktiv<br />
C3...C0 Codition-Bits , abhängig vom Ergebnis arithmetischer Operationen, werden für bedingte Programm-<br />
verzweigungen genutzt. Zwei dieser Bits entsprechen dem Carry- und Zero-Flag des<br />
CPU-Statuswortes und befinden sich sogar in der gleichen Bitposition<br />
ST-Bits (13-11) zeigen , welches der acht Numerik-Stack-Register das augenblickliche Top-Stack-Register<br />
ST = ST(0) ist ( Beispiel: Bit 13 = 1, Bit 12 = 0, Bit 11 = 1 � R5 ist ST(0) )<br />
Bits 7... 0 sind die sogn. Exception-Flags, die einen Fehler bei der Ausführung von Floating-Point-Operationen<br />
durch 1 signalisieren<br />
PE Precision-Exception -> die Mantissen-Genauigkeit der Ergebnis -Ausgabe reicht für eine exakte<br />
Darstellung nicht aus und wird gerundet<br />
UE Underflow-Exception -> der Exponent des Ergebnisses ist zu klein, um im gewünschten Real-Format<br />
dargestellt werden zu können<br />
OE Overflow-Exception -> der Exponent des Ergebnisses ist zu groß, um im gewünschten Real-Format<br />
dargestellt werden zu können.<br />
ZE Zerodivide-Exception-> Versuch, einen Nicht-Null-Operanden durch 0 zu teilen, wird angezeigt.<br />
DE Denormalized Operand-Exception -> Versuch, einen Denormal-Operanden zu verarbeiten, wird angezeigt.<br />
IE Invalid Operation-Exception-> zeigt Fehler bei Numerik-Stack- oder bei arithmetischen Operationen an<br />
Stack Fault -Flag SF = 1 -> Numerik-Stack-Over- oder Under-flow<br />
Condition Bit C1 = 1 -> Numerik-Stack-Overflow - Schreiben in nicht leeres<br />
Stackregister<br />
C1 = 0 ->Numerik-Stack-Underflow - Lesen aus leerem Stack-<br />
Register<br />
SF = 0 -> ungültige arithmetische Operation z.B. Division 0/0<br />
ES Error Summary Status -> zeigt das Auftreten einer Exception und einer daraus resultierenden Interrupt-<br />
anforderung an
Rechnergrundlagen Teil 2 - 59 - Prof. Dipl.-Ing. Komar<br />
FPU-Kontrollwort (Steuerwort)<br />
Über das Kontrollwort läßt sich die FPU steuern.<br />
15 14 13 12 11 10 9 8 7 6 5 4 3 2 1 0<br />
X X X IC RC PC IEM PM UM OM ZM DM IM<br />
IC Infinity Control Darstellung von Unendlich , ab 80387 bedeutungslos, denn es werden die Vorzeichen von<br />
Unendlich immer berücksichtigt<br />
RC Rounding Control Steuerbits für Rundung<br />
0 0 = Runden zum nächsten Wert ( eingestellt )<br />
0 1 = Abrunden in Richtung – Unendlich<br />
1 0 = Aufrunden in Richtung + Unendlich<br />
1 1 = Abschneiden des gebrochenen Anteils in Richtung Null<br />
PC Precision Control Die FPU kann ihre Rechnungen mit einer Mantissengenauigkeit von<br />
0 0 = 24 Bits ( Short Real )<br />
0 1 = reserviert<br />
1 0 = 53 Bits ( Long Real )<br />
1 1 = 64 Bits ( Temporary Real ) , nach Initialisierung eingestellt<br />
IEM Interrupt Freigabe Maske für die Anforderung <strong>eines</strong> Interrupts durch die FPU, ab 80387 bedeutungslos<br />
Maskenbits PM = Genauigkeitsverlust<br />
UM = Unterlauf<br />
OM = Überlauf<br />
ZM = Division durch Null<br />
DM = denormalisierter Operand<br />
IM = ungültiger Befehl<br />
legen mit einer 0 fest, das im Fehlerfall ein Interrupt (exception ) ausgelöst wird. Bei maskierten Exception-<br />
Flags = 1 behandelt die FPU diese Exceptions selbst, indem sie ein angemessenes Ergebnis produziert und dann<br />
das Numerik-Programm fortführt<br />
Das FPU-Tagwort<br />
enthält für jedes der acht Numerik-Stack-Register ein 2-Bit-Tagfeld, das den Inhalt des zugehörigen Numerik-<br />
Stack-Registers charakterisiert<br />
TA G(7) TAG(6) TAG(5) TAG(4) TAG(3) TAG(2) TAG(1) TAG(0)<br />
Tag-Wert Numerik-Register-Inhalt<br />
0 0 gültig<br />
0 1 Null<br />
1 0 spezielle Werte : NaN, Unendlich, Denormal<br />
1 1 leer
Rechnergrundlagen Teil 2 - 60 - Prof. Dipl.-Ing. Komar<br />
Datentypen und Formate<br />
(zwischen dem Gleitpunktstandard IEEE und der Realisierung im 8087/80287 bestehen einige wenige kleinere<br />
Unterschiede, die aber ab 80387 durch zusätzliche Befehle korrigiert worden sind )<br />
Die FPU kennt sieben verschiedene Datentypen, die in drei Klassen unterteilt werden können und die nur im<br />
Arbeitsspeicher existieren, da sie beim Laden in die FPU in das interne 80-Bit erweiterte Real-Format<br />
konvertiert werden:<br />
- Binär Integer sind vorzeichenbehaftete 2-, 4-, oder 8-Byte Dualzahlen<br />
Vorzeichen ( S=Sign) Wertebereich<br />
Word Integer 16 Bit Bit 15 -32768 � � + 32767 - einfache Genauigkeit<br />
Short Integer 32 Bit 31 - 2 * 10 9 � � + 2 * 10 9 - doppelte Genauigkeit<br />
Long Integer 64 Bit 63 - 9 * 10 18 � � + 9 * 10 18 - erweiterte Genauigkeit<br />
- Packed Dezimal Integer -> Gepackte 10 Byte BCD-Zahl mit höchstwertigem Bit 79 als Vorzeichen S,<br />
die restlichen Bit 72-78 des höchstwertigen Byte haben keine Bedeutung<br />
und in den restlichen 9 Byte sind jeweils zwei Dezimalziffern gepackt.<br />
Genauigkeit dieses Typs ist 18 Dezimalstellen (Digits) +/- 10 18<br />
Länge [Bit] Vorzeichen Characteristik Bias k Mantisse [Bit]<br />
- Binär Real Short Real 32 1 8 127 24<br />
Long Real 64 1 11 1023 53<br />
Temporary Real 80 1 15 16383 64<br />
Beachtung: Die Mantisse des Temporary Real-Formats beinhaltet in Abweichung zum Short- und Long-Real-<br />
Format auch die 1 der normalisierten Dualzahl vor dem Komma und zwar in Bit-Position 63.<br />
Damit entspricht die Mantisse einer Normalisierung nach (0.m)2 mit Minimalwert 0.5<br />
Die Mehrbyte-Operanden werden im Arbeitsspeicher nach dem INTEL-Prinzip höher-/niederwertiges Byte<br />
(High-/Low-Byte) nach höherer / niedrigerer Adresse ( High-/Low-Adresse) angeordnet.<br />
Spezielle Numerikzahlen<br />
Neben den typischen Real und Intergerwerten können bei gewissen Berechnungssituationen und Operationen<br />
Spezialwerte auftreten.<br />
Denormal-Realzahlen entstehen immer dann, wenn eine sehr kleine Realzahl in der normalisierten Form nicht<br />
mehr exakt dargestellt werden kann, weil sie im Bereich – 2 Emin < R < + 2 Emin liegt.<br />
Denormal-Operanden haben wie die beiden Nullen (+ 0 und – 0 ) die Charakteristik 0, im Gegensatz zu diesen<br />
aber eine Mantisse ≠ 0.<br />
Wenn nach einer Floating-Point-Operation ein Unterlauf (Underflow) auftritt, weil der wahre Exponent E des<br />
Ergebnisses zu klein ist (E < Emin), dann denormalisiert die FPU das Ergebnis und zeigt dies im DE-Bit des<br />
Statuswortes an ( DE = 1 ).<br />
NaN (Not-a-Number) werden durch ihre Charakteristik 11....11 2 gekennzeichnet. Die Mantisse kann bis auf<br />
.10....00 2 jeden beliebigen Bitstring enthalten.<br />
Sonderfälle (zeigen ungültige Operationen und Ausnahme Bedingungen an :<br />
- Signaling NaNs , das MSB der Mantisse ist gelöscht (MSB = 0)<br />
- Quiet NaNs , das MSB der Mantisse ist gesetzt (MSB = 1)<br />
Infinity (Unendlich)<br />
Alle Realformate unterstützen die vorzeichenbehaftete Darstellung von + und – Unendlich.<br />
Darstellung: Vorzeichenbit 0 oder 1, Charakteristik 11....11 2 und Mantisse 00...0002<br />
Nicht-unterstützte Datenformate sind Bitmuster, die zum großen Teil vom 8087/80287 unterstützt werden<br />
aber vom 80387 und der FPU der späteren Prozessoren nicht mehr.<br />
Trifft die FPU auf solche Operanden, so führt dies zur Exception Ungültige Operation.
Rechnergrundlagen Teil 2 - 61 - Prof. Dipl.-Ing. Komar<br />
Ausnahmen im IEEE-Format<br />
Zu beachten bei den IEEE-Zahlenformaten ist, daß die Charakteristiken c = 0 und c = 2 r – 1 zur<br />
Zahlendarstellung nicht zugelassen sind und zur Kennzeichnung von Ausnahmesituationen dienen.<br />
1.) c = 0 m = 0 : Z = 0 0000 000016 => + 0 8000 000016 => – 0<br />
2.) c = 0, m ≠ 0 : Z = (-1) VZ * 2 Cmin-k * ( 0.m )2 bedeutet, die Zahl Z wird in denormalisierter<br />
Form dargestellt, weil sie betragsmäßig kleiner ist als 2 Cmin - k .<br />
und hat den konstanten Exponenten emin= Cmin - k<br />
3.) c = 2 r – 1, m ≠ 0 : Z ist keine gültige Gleitpunktzahl ( not a number – NaN )<br />
4.) c = 2 r – 1, m = 0 : Z = (– 1) VZ * ∞ d.h. das Ergebnis ist positiv oder negativ unendlich<br />
Damit bestimmen sich die darstellbaren Zahlen im IEEE-Format zu :<br />
Z = ( – 1 ) VZ * 2 C– k * ( 1.m )2<br />
mit 0 < c < 2 r – 1 –> wg. Ausnahmen cmin = 1 , cmax = 2 r – 2<br />
k = 2 r – 1 – 1<br />
– p<br />
( 1.m ) min = 1.0 ( 1.m ) max = 2 – 2<br />
| Z min | = 2 exp(cmin – k ) * ( 1.m ) min = 2 1– k * 1<br />
| Zmax | = 2 exp(cmax – k ) * ( 1.m ) max = 2 exp( 2 r – 2 – k ) * ( 2 – 2 – p ) ≈ 2exp( 2 r – 1 – k )<br />
k |Z min | |Zmax| Dezimalstellen<br />
32-Bit -Format 127 2 –126 = 1.175 *10 –38 2 128 = 3.40 * 10 38 ≈ 7<br />
64-Bit -Format 1023 2 –1022 = 2.23 *10 –308 2 1024 = 1.80 * 10 308 ≈ 15<br />
80-Bit -Format 16383 2 –16382 = 3.36 *10 –4932 2 16384 = 1.18 * 10 4932 ≈ 19<br />
Das 80-Bit -Format ( Temporary Real ) ist in den IEEE-Normen nicht festgelegt.<br />
Normalisiert + 0< Exp < max Beliebiges Bitmuster<br />
Denormalisiert + 0 Beliebiges Nicht-Null-Bitmuster<br />
Null + 0 0<br />
Unendlich + 1 1 1 1. . . . 1 0<br />
Keine Zahl + 1 1 1 1 . . . .1 Beliebiges Nicht-Null-Bitmuster<br />
Vorzeichen-Bit<br />
Numerische Typen nach IEEE 754
Rechnergrundlagen Teil 2 - 62 - Prof. Dipl.-Ing. Komar<br />
Befehlssatz der FPU<br />
Die Vereinbarung von Konstanten und Variablen im Arbeitsspeicher erfolgt mit Hilfe <strong>eines</strong> symbolischen<br />
Assemblers für folgende Zahlendarstellungen:<br />
Typ Darstellung Vereinbarung indirekt adr.<br />
INTEGER WORD 16-Bit dual mit Vorzeichen DW WORD PTR<br />
INTEGER SHORT 32-Bit dual mit Vorzeichen DD DWORD PTR<br />
INTEGER LONG 64-Bit dual mit Vorzeichen DQ QWORD PTR<br />
REAL SHORT 32-Bit, 8-Bit-Char.,23-Bit-Mant. DD DWORD PTR<br />
REAL LONG 64-Bit,11-Bit-Char.,52-Bit-Mant. DQ QWORD PTR<br />
REAL TEMPORARY 80-Bit,15-Bit-Char.,64-Bit-Mant. DT TBYTE PTR<br />
BCD PACKED 80-Bit,,VZ-Byte, 18 Dezimalstellen DT TBYTE PTR<br />
Datentransportbefehle<br />
Mit Transportbefehlen können die internen 10-Byte-Daten des Registerstapels auf die Stapelspitze<br />
umgespeichert oder bei gleichzeitiger Konvertierung in das Anwenderdatenformat vom Speicher gelesen oder in<br />
den Speicher geschrieben werden. Der Austausch mit dem Speicher erfolgt nur über die Stapelspitze ST = ST(0).<br />
Der Ladebefehl schreibt Daten aus dem Arbeitsspeicher oder aus dem FPU-Registerstack auf den Registerstack<br />
Der Schreibbefehl schreibt den Inhalt der FPU-Registerstack-Spitze ST (0) in den Arbeitsspeicher<br />
Der Tauschbefehl tauscht den Inhalt zweier Register des Registerstacks aus.<br />
Jede Übertragung von Operanden zwischen der FPU und dem Arbeitsspeicher ist mit einer Zahlenumwandlung<br />
verbunden, denn die FPU stellt intern alle Zahlen im 80-Bit-Temporary-Real-Format dar.<br />
Für alle FPU-Befehle ( Transportbefehle ) gilt folgende Form:<br />
1.Buchstabe F<br />
2.Buchstabe I für Integer, B für BCD-Zahlen, kein Zeichen für Gleitpunktzahlen<br />
weitere Buchstaben LD für PUSH und lade Stapelspitze ST(0) mit Operand<br />
ST für Speichere Stapelspitze ST(0) nach Operand ( Speicher oder Stapel )<br />
STP für Speichere Stapelspitze nach Operand und POP<br />
XCH für Vertausche Stapelspitze ST(0) mit Stapeloperand<br />
FLD mem PUSH und lade Stapelspitze ST(0) mit REAL-Speicheroperand FLD QWORD PTR[SI]<br />
FILD mem PUSH und lade Stapelspitze ST(0) mit INTEGER-Speicherop. FILD WORD PTR[BP]<br />
FBLD mem PUSH und lade Stapelspitze ST(0) mit BCD-PACKED-Speicherop. FBLD TBYTE PTR[0200]<br />
FLD ST(i) PUSH und lade Stapelspitze ST(0) mit Stapeloperand i FLD ST(3)<br />
FSTP mem Speichere Stapelspitze ST(0) nach REAL-Speicheroperand und POP<br />
FISTP mem Speichere Stapelspitze ST(0) nach INTEGER-Speicheroperand und POP<br />
FBSTP mem Speichere Stapelspitze ST(0) nach BCD-PACKED-Speicheroperand und POP<br />
FSTP ST(i) Speichere Stapelspitze ST(0) nach Stapeloperand i und POP<br />
Die folgenden zwei Befehle FST und FIST sind nicht möglich mit den Sonderformaten INTEGER LONG und<br />
REAL TEMPORARY<br />
FST mem Speichere Stapelspitze ST (0) nach REAL-Speicheroperand (ohne POP )<br />
FIST mem Speichere Stapelspitze ST(0) nach INTEGER-Speicheroperand (ohne POP )<br />
FST ST(i) Speichere Stapelspitze ST(0) nach Stapeloperand i ( ohne POP )<br />
FXCH ST(i) Vertausche Stapelspitze ST(0) mit Stapeloperand i<br />
FXCH Vertausche Stapelspitze ST(0) mit Stapeloperand ST(1)<br />
Das Laden von Konstanten in das oberste Stapelregister ST, wobei eine PUSH-operation ausgeführt wird<br />
FLDZ PUSH und lade Stapelspitze ST mit 0.0<br />
FLD1 PUSH und lade Stapelspitze ST mit 1.0<br />
FLDPI PUSH und lade Stapelspitze ST mit PI<br />
FLDL2T PUSH und lade Stapelspitze ST mit log 2 10<br />
FLDL2E PUSH und lade Stapelspitze ST mit log 2 e<br />
FLDLG2 PUSH und lade Stapelspitze ST mit log 10 2<br />
FLDLN2 PUSH und lade Stapelspitze ST mit ln 2
Rechnergrundlagen Teil 2 - 63 - Prof. Dipl.-Ing. Komar<br />
Beispiele in DEBUG-Assembler-Syntax:<br />
FILD QWORD PTR [0200] ; lade INTEGER LONG-Operanden aus Arbeitsspeicheradresse DS:0200<br />
FBSTP TBYTE PTR [BX] ; speichere Stapelspitze als BCD-PACKED-Operand nach DS:BX und POP<br />
FST DWORD PTR [220] ;speichere Stapelspitze als REAL SHORT-Operand nach Arbeitsspeicher-<br />
adresse DS:0220 (ohne POP)<br />
FSTP ST(0) ;POP-Operation ohne Datentransport<br />
FISTP QWORD PTR[SI] ; Stapelspitze ST(0) nach 8-Byte-Integer-Operand in DS:SI speichern und POP<br />
FST ST(4) ; ST(4) := ST (0)<br />
Arithmetische Befehle<br />
Die arithmetischen Befehle können nur auf die vier Normalformen (INTEGER WORD und – SHORT sowie<br />
REAL SHORT und –LONG ) sowie auf Operanden in den Stapelregistern angewendet werden.<br />
Aufbau der Befehlssymbolik:<br />
F I operation R P<br />
INTEGER ADD Rückwärts POP<br />
SUB den Stapel<br />
MUL<br />
DIV<br />
I kennzeichnet alle Befehle mit INTEGER-Operanden im Arbeitsspeicher.<br />
R bedeutet bei den Operationen Subtrahieren SUB und Dividieren DIV , daß die Reihenfolge der beiden<br />
Operanden vor der Operation zu vertauschen ist.<br />
P kennzeichnet eine Operation mit POP, bei der nach der Ausführung der Operation der Stapelzeiger erhöht und<br />
damit das oberste Stapelregister ST(0) freigegeben wird. ST(0) darf in diesem Fall nicht Zielregister für das<br />
Ergebnis sein, da dieses damit verloren gehen würde.<br />
Alle nicht besonders gekennzeichneten arithmetischen Befehle werden in der Reihenfolge<br />
1.Operand Funktion-(verknüpfung) mit 2.Operand = > 1.Operand<br />
ausgeführt, wobei das Ergebnis in den 1.Operanden geschrieben wird.<br />
Einer der beiden Operanden muß sich im obersten Stapelregister ST(0) befinden. Der andere Operand kann eine<br />
Speicherstelle oder ein anderes Stapelregister sein.<br />
FSUB ST, ST(1) ST(0) = ST(0) – ST(1)<br />
FSUBR ST,ST(1) ST(0) = ST(1) – ST(0)<br />
Befehle der vier Grundrechenarten<br />
Fxxx mem ST = ST + | – | * | / Speicheroperand ( SHORT oder LONG REAL )<br />
FIxxx mem ST = ST + | – | * | / Speicheroperand ( WORD oder SHORT INTEGER )<br />
Fxxx ST,ST(i) ST = ST + | – | * | / Stapeloperand i<br />
Fxxx ST(i),ST ST(i) = ST(i) + | – | * | / Stapelspitze ST<br />
FxxxP ST(i),ST ST(i) = ST(i) + | – | * | / Stapelspitze ST und POP: ST geht verloren<br />
Fxxx ST(1) = ST(1) + | – | * | / Stapelspitze ST und POP: Ergebnis in ST<br />
xxx => ADD + | SUB – | MUL * | DIV / |
Rechnergrundlagen Teil 2 - 64 - Prof. Dipl.-Ing. Komar<br />
FyyyR mem ST = Speicheroperand ( SHORT oder LONG REAL ) – | / ST<br />
FIyyyR mem ST = Speicheroperand ( WORD oder SHORT INTEGER ) – | / ST<br />
FyyyR ST,ST(i) ST = Stapeloperand i – | / Stapelspitze ST<br />
FyyyR ST(i),ST ST(i) = Stapelspitze ST – | / Stapeloperand ST(i)<br />
FyyyRP ST(i),ST ST(i) = Stapelspitze ST – | / ST(i) und POP: ST geht verloren<br />
FyyyR ST(1) = Stapelspitze ST – | / ST(1) und POP: Ergebnis in ST<br />
yyy => SUB – oder DIV / ; R bewirkt Vertauschung der Operandenreihenfolge<br />
Beispiele:<br />
FIADD WORD PTR[BX] ; ST = ST + 2-Byte-Integerwert in DS:BX<br />
FDIV DWORD PTR [0200] ; ST = ST/ 4-Byte-Realwert in DS:200<br />
Vergleichsbefehle<br />
Die Vergleichsbefehle bilden eine Testsubtraktion zwischen dem obersten Stapelregister ST = ST(0) und einer<br />
Speicherstelle oder einem anderen Stapelregister, wobei die beiden Operanden nicht verändert werden sondern<br />
nur die beiden Bedingungsbits C3 und C0 des FPU-Statusregisters entsprechend dem Ergebnis gesetzt oder<br />
gelöscht werden.<br />
Da die FPU keine eigenen bedingten Sprungbefehle hat, müssen die Bedingungsbits in das Statusregister der<br />
CPU gebracht und dort durch die bedingten Sprünge der CPU ausgewertet werden.<br />
Die FPU-Bedingungsbits C3 und C0 werden in die Bedingungsbits Z (Zero) und C (Carry) des CPU-Statusregisters<br />
kopiert und es kann mit den bedingten Sprungbefehlen JA, JAE, JE, JNE, JBE und JB verzweigt<br />
werden.<br />
FCOM mem Differenz ST – Speicheroperand ( SHORT oder LONG REAL )<br />
FICOM mem Differenz ST – Speicheroperand ( WORD oder SHORT INTEGER )<br />
FCOM ST(i) Differenz ST – Stapeloperand i<br />
FCOM Differenz ST – Stapeloperand ST(1)<br />
FCOMP mem Differenz ST – Speicheroperand und POP ( POP löscht Operanden der Stapelspitze)<br />
FICOMP mem Differenz ST – Speicheroperand und POP "<br />
FCOMP ST(i) Differenz ST – Stapeloperand i und POP, ST geht verloren<br />
FCOMPP Differenz ST – ST(1) und POP und POP, beide Operanden gehen verloren<br />
FTST Differenz ST – 0.0: verändert Bedingungsbit C3 und C0<br />
FXAM Untersuche Operanden in Stapelspitze ST ( C3, C2, C1, C0 )<br />
Die Bedungungsbit C3 C0 zeigen das Vergleichsergebnis<br />
0 0 ST > 2. Operand<br />
0 1 ST < 2. Operand<br />
1 0 ST = 2. Operand<br />
1 1 nicht möglich<br />
Beispiele:<br />
FCOM ; Vergleiche ST mit ST(1)<br />
FCOM ST(5) ; Vergleiche ST mit ST(5)<br />
FCOM DWORD PTR[0200] ; Vergleiche ST mit 4-Byte-Realwert in DS:200<br />
Beispiel für Auswertung der Bedingungsbit im Bedingungscodefeld des FPU-Statuswortes mit 80x86-Befehlen<br />
FCOMxx op ; beliebiger Vergleichsbefehl<br />
FSTSW [0200] ; FPU-Statusregisterinhalt in den Arbeitsspeicher nach DS:200<br />
MOV AX,[200] ; AX mit FPU-Statusregisterinhalt laden<br />
SAHF ; speichere AH in das Bedingungsregister, dem Low-Teil des Statusregisters<br />
Jxx ziel ; Auswertung der Bedingungsbits durch bedingte Sprungbefehle
Rechnergrundlagen Teil 2 - 65 - Prof. Dipl.-Ing. Komar<br />
Arithmetische Sonderbefehle und mathematische Funktionen<br />
können nur auf das oberste Stapelregister ST angewendet werden, bzw bei zwei Operanden auch auf das<br />
folgende Stapelregister ST(1)<br />
FSQRT ST = Quadratwurzel ( ST ), Radikand muß positiv sein<br />
FSCALE ST = ST * 2 hoch ST(1), ST(1) muß ganzzahlig sein ( WORD INTEGER )<br />
FPREM ST = ST - ST(1), bildet teilweise ST = ST MODulo ST(1) unvollständige Modulodiv.<br />
C2=0: Rest in ST < Modulus in ST(1)<br />
C2=1: Rest in ST > Modulus in ST (1) � FPREM wiederholen<br />
FPREM1 berechnet wie FPREM eine Modulo-Division, allerdings nach dem IEEE-Standard<br />
Dieser Befehl steht erst ab 80387 zur Verfügung<br />
FRNDINT mache ST ganzzahlig ( INTEGER ) durch runden oder abschneiden<br />
FXTRACT zerlege ST in Exponent und Mantisse dann PUSH neu : ST = Mantisse , ST(1)Exponent<br />
FABS ST = |ST| bilde Absolutwert von ST<br />
FCHS ST = – ST wandle das Vorzeichen von ST um<br />
Mathematischen Funktionen<br />
werden auf das oberste Stapelregister ST = ST(0) und bei zwei Operanden auch auf das folgende Stapelregis ter<br />
ST(1) angewendet.<br />
Bei den trigonometrischen Funktionen stehen nur Tangens und Arcustangens zur Verfügung, aus denen die<br />
anderen Funktionen abgeleitetet werden müssen.<br />
FPTAN ( 0 < δ ≤π / 4 ) PUSH und bilde tan (ST) = Y/X Stapel (neu): ST=X ST(1) = Y<br />
FPATAN ( 0 < y < x< ∞ ) bilde atan ( ST(1) / ST ) und POP Stapel (neu): ST= atan ( y/x)=atan (ST(1)/ST)<br />
F2XM1 ( 0 < x < 0.5 ) ST = 2 ST – 1 Funktion : z = 2 x – 1<br />
FYL2X ( 0 < x < ∞ ) ST = ST(1) * log 2 (ST) und POP Stapel (neu): ST = y log 2 x<br />
2<br />
FYL2XP1 ( 0 < |x|< (1 – )) ST = ST(1)*log 2 (ST+1) und POP Stapel (neu): ST = y log 2 (x + 1)<br />
2<br />
FPU-Steuerbefehle<br />
dienen zur Programmierung des Steuerregisters und zum Speichern der FPU-Register in den Arbeitsspeicher.<br />
FINIT FPU in Grundeinstellung bringen ( initialisieren )<br />
FDISI verhindert Interrupts durch FPU<br />
FENI erlaubt Interrupts durch FPU<br />
FLDCW mem lade Steuerwort mit Inhalt von Speicherwort mem<br />
FSTCW mem speichere Steuerwort nach Speicherwort mem<br />
FSTSW mem speichere Statuswort nach Speicherwort mem<br />
FCLEX lösche Ausnahme-, IR- und Busy-Bits im Statuswort<br />
FSTENV mem speichere Environment-Register nach 14 Bytes (mem)<br />
FLDENV mem lade Environment-Register mit 14 Bytes (mem)<br />
FSAVE mem speichere Environment und Stapel nach 94 Bytes (mem)<br />
FRSTOR mem lade Environment-Register und Stapel mit 94 Bytes (mem)<br />
FINCSTP erhöhe Stapelzeiger um 1 (ähnlich POP ), ke ine Freigabe<br />
FDECSTP vermindere Stapelzeiger um 1 (ähnlich PUSH )<br />
FFREE ST(i) kennzeichne Stapeloperand i als leer (empty)<br />
FNOP warte 13 Takte (lade ST mit ST = no operation )<br />
FWAIT wie 8086-Befehl WAIT = warte bis TEST-Eingang LOW
Rechnergrundlagen Teil 2 - 66 - Prof. Dipl.-Ing. Komar<br />
Das DEBUG-Programm unter DOS unterstützt nicht die Fehlersuche in Programmen für die FPU, denn bei<br />
einem Haltepunkt werden nicht die Inhalte der FPU-Register dargestellt.<br />
Außerdem kennt der DEBUG-Assemb ler nicht die symbolischen Format-Vereinbarungen DWORD und<br />
QWORD, sondern es stehen nur BYTE , WORD und TBYTE (10 Byte) zur Verfügung .<br />
Von den Anweisungen für die Vereinbarungen von Speicherbelegungen DB (1 Byte), DW (Word =2 Byte),<br />
DD ( Doubl e Word =4 Byte), DQ (Vierfachwort = 8 Byte ) und DT ( 10 Byte) akzeptiert der DEBUG-<br />
Assembler nur DB und DW.<br />
Im unten dargestellte DEBUG-Assembler-Programmbeispiel wird mit dem Euklidischen Algorithmus der<br />
größte gemeinsame Teiler zweier natürlicher Zahlen berechnet.<br />
Im Beispiel werden die beiden Zahlen 65535 und 255 als jeweils 18-stellige Dezimalzahlen ( 10 Byte Packed<br />
Dezimal Integer ) mittels DB-Anweisung im Speicher vereinbart, da dieses Beispielprogramm ohne Ein-und<br />
Ausgabe arbeitet. Das Ergebnis wird als 10 Byte BCD-Wert ab Offset-Adresse 0230 abgespeichert.<br />
Euklidischer Algorithmus (Programmablauf)<br />
p:= Zahl 1<br />
q:= Zahl 2<br />
1. p mod q = r (Teilerrest r von p/q )<br />
2. r = 0 ? �� ja, dann ist q der größte gemeinsamr Teiler ; END<br />
3. nein, dann p:= q ; q:= r<br />
4. gehe zu 1.<br />
a 100<br />
ORG 100<br />
;Euklidischer Algorithmus mit FPU ( Programm EUKLFPU.ASM )<br />
;<br />
FBLD TBYTE PTR [210] ; q als 18-stellige BCD-Zahl nach ST(0)<br />
FBLD TBYTE PTR [200] ; p auf Stapel nach ST, q dadurch nach ST(1)<br />
;<br />
FPREM ; ST = ST - ST(1) Teilschritt von p mod q = r<br />
FSTSW [220] ; FPU-Statuswort nach DS:0220<br />
TEST WORD PTR [220],400 ;C2-Flag auf 1 testen, modulo-Division beendet?<br />
JNZ 108 ;********************<br />
FTST ;modulo-Div. beendet aber ist r = ST = 0 ?<br />
FSTSW [220]<br />
TEST WORD PTR [220],4000 ;C3-Flag auf 1 testen, Teilerrest r = 0 ?<br />
JNZ 128 ;*********************<br />
FXCH ;Vertausche ST mit ST(1), p � q, q � r<br />
JMP 108<br />
FXCH ;Vertausche ST mit ST(1), r mit q<br />
FBSTP [230] ;q in Speicher bringen für Ergebnisausgabe<br />
MOV AX,4C00<br />
INT 21 ;Programm beenden<br />
;<br />
ORG 200<br />
DB 35,55,65,00,00,00,00,00,00,00 ;65535 in 10 Byte BCD<br />
ORG 210<br />
DB 55,02,00,00,00,00,00,00,00,00 ; 255<br />
n euklfpu.com<br />
r bx<br />
0<br />
r cx<br />
200<br />
w<br />
q
Rechnergrundlagen Teil 2 - 67 - Prof. Dipl.-Ing. Komar<br />
Literatur zur FPU/80x87:<br />
John F. Palmer, Stephen P. Morse<br />
Die mathematischen Grundlagen der Numerik-Prozessoren 8087/80287<br />
te-wi Verlag GmbH, München 1985 ISBN 3-921803-33-0<br />
Klaus-Diether Thies<br />
80486 Systemsoftware -Entwicklung<br />
Carl Hanser Verlag 1992 ISBN 3-446-16554-1<br />
G.Schmitt<br />
Mikrocomputertechnik mit dem 16-Bit-Prozessor 8086<br />
R.Oldenbourg 1986 ISBN 3-486-20255-3<br />
David J. Bradley<br />
Programmieren in Assembler für die IBM Personal Computer<br />
Carl Hanser Verlag 1986 ISBN 3-446-14275-4<br />
Jorke, Lampe, Wengel<br />
Arithmetische Algorithmen der Mikrorechnertechnik<br />
VEB Verlag Technik Berlin 1989 ISBN 3-341-00515-3<br />
Isa Brors<br />
Maschinensprache des IBM-PC/AT<br />
Hüthig, 1992 ISBN 3-7785-2076-8<br />
(Befehlssatz ausführlich )