18.12.2012 Aufrufe

6. Funktionseinheiten eines Computers / Mikrocomputers

6. Funktionseinheiten eines Computers / Mikrocomputers

6. Funktionseinheiten eines Computers / Mikrocomputers

MEHR ANZEIGEN
WENIGER ANZEIGEN

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 )

Hurra! Ihre Datei wurde hochgeladen und ist bereit für die Veröffentlichung.

Erfolgreich gespeichert!

Leider ist etwas schief gelaufen!