ASM Tutorial:


Inhalt:


1. Einleitung
2. Übersetzen/Compiliern
3. Der Prozessor (CPU Central Prozess Unit)
4. Die Register und Flagen
5. Kleines Programm
6. Bedingter Sprung mit jne (Jump not equal)
7. Unterprogramm


8. Die Bedeutung von Interrupts (am Beispiel vom BIOS Interrupt 10h)
9. Nachwort



Einleitung

Zum Inhaltsverzeichnis Dieses Tutorial soll einen kleinen Einstieg und Einblick in die 80/86 Assambler Programmierung geben. Erstmal ein kommen ein paar Grundlagen. Ein Compiler (DOS) wär nicht schlecht, damit ihr eure Programme übersetzen könnt. Am Anfang braucht ihr noch keinen. Assambler ist extrem Hardware nah, dass heißt man kommuniziert direkt mit der Hardware und müsst deswegen auch über die Hardeware bescheid wissen und bedenkt, dass unser Pc beim Programmieren wie ein 8086 behandelt wird.


Übersetzen/Compiliern

Zum Inhaltsverzeichnis Ihr schreibt euer Programm im Editor von Windows und speichert das ganze dann unter beliebig.asm. Zum übersetzen reicht dann die Dos Box. Zuerst wird die .obj Datei erstellt. Diese müßt ihr dann (nochmals) linken/compiliern um eine .exe zu erhalten die unter Windows läuft. Ein Compiler und Linker hier zum Download. Wir nennen unsere Datei zum Beispiel test.asm Wechselt in das richtige Verzeichnis (dort wo euer Linker und Quellcode ist) und gebt ein: asm test Nun wird die obj. Datei erstellt, wenn kein Fehler vorliegt. Bei einem Fehler wird oft die Zeile angegeben in der sich der Fehler Befindet. Die obj. Datei linkt ihr jetzt mit: link dann den namen der .obj Datei angeben also: test dann angeben wie die .exe heißen soll z.B: test Dann ein paar mal ENTER, der Rest ist nämlich egal.


Der Prozessor (CPU Central Prozess Unit)

Zum Inhaltsverzeichnis Eine CPU steuert, regelt und kontrolliert Arbeitsprozesse in einem Computer. Die CPU besteht in ihrem Aufbau aus zwei unterschiedlichen Funktionseinheiten, zum einen aus der Verarbeitungseinheit EU (Execute Unit) und aus der Busverbindungseinheit BIU (Bus Interface Unit). Die EU hat sogenannte Register die sehr wichtig in der Assambler Programmierung sind. Ein Register hat die größe von 16 Bit. Die Allgemeinen Register kann man in Heigh und Low Register teilen, die dann jeweils 8 Bit groß sind. Es gibt ausserdem noch sogennante Flags (Flagen).


Die Register und Flagen

Zum Inhaltsverzeichnis
Allgemeine Register:Abkürzung:Art:HighLow
AkkumulatorAX(Arbeitsregister - Ergebnisregister))AHAL
BasisregisterBX(Base - Zeiger)BHBL
ZählregisterCX(Count)CHCL
DatenregisterDX(Data - Zeiger)DHDL

Offsetregister: (Adressabstand im Segment)Abkürzung:Art:
BasiszeigerBP(Base Pointer)
QuellindexSI(String Index - Zeiger)
ZielindexDI(Destination Index - Ziel)
StapelzeigerSP(Stack Pointer)

Segmentregister: (Adressabschnitt des RAMs)Abkürzung:Art:
CodesegmentCS(Code Segment)
DatensegmentDS(Data Segment)
ExtrasegmentES(Extra Segment)
StapelsegmentSS(Stack Segment)

Statusregister:Abkürzung:Art:
BefehlszählerIP(Instruction Pointer)
FlagregisterFLAGS(Fahne)

Abkürzung:Name:Art:
CFCarry Flag(Übertrag)
PFParity Flag(Parität)
AFAuxiliary Carry Flag(Zusatzübertag)
ZFZero Flag(Null)
SFSign Flag(Vorzeichen)
TFTrap Flag(Fall)
IFInterrupt Flag(Unterbrechung)
DFDirection Flag(Richtung)
OFOverflow Flag(Überlauf)

Das ist euch natürlich alles noch sehr unverständlich. Mit diesen Registern wird gearbeitet wenn man programmiert. Die Wert in den Registern werden mit 4 Ziffern Hexadezimal dagestelt. Deswegen auch die größe von 16 Bit. Das Hexadezimalsystem ist das 16 System:
Dezimal:HexadezimalBinär
111
2210
3311
44100
55101
66110
77111
881000
991001
10101010
11A1011
12B1100
13C1101
14D1110
15E1111
16F10000
171110001
181210010
191310011
201410100
65535FFFF (4 Ziffern)1111111111111111 (16 Bit)


Schauen wir uns mal die Register und Flags in der Praxis an. Wechseln mal in die MS-Dos Eingabeaufforderung und gebt ein: debug. Das Dienstprogramm Debug gehört zum Lieferumfang von MSDOS. Die wichtigsten Befehle:
?Hilfe
RRegisteranzeige
AAssamblieren
TSchrittweise ausführen
QBeenden

Jetzt erscheint ein Spieglstrich, nun gebt ihr mal r ein und ENTER nun werden die Register und Flags aufgezeigt. So jetzt schreiben wir ein kleins Programm. Gebt a ein und schreibt: mov ax,100h (Enter) mov ax,200h (Enter) add ax,50 (Enter) mov bx,ax (Enter) Enter drücken. Jetzt mit t schrittweise ausführen. Es werden die Register und Flagen angezeigt und in der letzten Zeile ist der aktuelle Befehl zu sehen der beim nächsten t ausgeführt wird. Nun werdet ihr sehen das in ax,100 ist. Dann 200 und beim nächsten mal ist ax in 250 und dann ist auch in bx 250. Wir bewegen also einen Wert in ax bzw. bx oder addieren zu einem Register einen Wert. Mit q beendet ihr die debugger wieder. Ein Beispiel zu den Flags: Was ist wenn ein Registern den höchsten Wert erreicht hat (ffff) und man 1 dazu addiert? Das Register fängt wieder bei Null an, wie bei einer Waage mit Zeiger, wenn der Zeiger eine Umdrehung hat seit ihr auch wieder bei null. Gut in dem Fall wird das Carry Flag gesetzt, bei einem Übertrag. Experimentiert ein bischen mit dem Debug rum. In den nächsten Programmen werden wir aber nicht mehr den Debug benutzten.


Ein kleines Programm:

ZumInhaltsverzeichnis Gut schreibt nun folgendes Programm und übersetzt es: code segment assume cs:code start: mov ax,0b800h ;Kommentar mov ds,ax mov al,03h mov ah,0ch mov di,2000 mov ds:[di],ax ; mov ah,4ch int 21h code ends end start end Wenn ihr dieses Programm übersetzt hab erscheit ein Herz ziemlich in der Mitte des Bildschirms. Jetzt wird alles erklärt. code segment assume cs:code das ist der Programmkopf, der Compiler weiß z.B das es ein Assambler Programm ist. start: mov ax,0b800h start: hier beginnt das Programm mov heißt bewege, also bewege 0b800h nach ax das h am ende der 0b800 heißt Hexadezimal, Hexadezimal ist das 16 System, Werte in den Register sind immer Hexadezimal deswegen auch die 16 Bit. Gut also nach dem Anweisung steht im ax Register 0b800h. 0b800 ist nicht anders als der Begin des Videospeichers, für die Bildschirmausgabe. ; Kommentar wird vom Compiler nicht übersetzt dient dazu Kommentare zu Programm zu machen. mov ds,ax Hier wird der Inhalt von ax nach ds (Datensegmentregister) bewegt. mov al,03h Hier wird in das al, also das High Register von ax, 03h bewegt. Wenn ihr mal einen Blick auf die ASCII Tabelle werfen werdet ihr merken, dass das das Herz ist. Jetzt kommen wir der Sache schon näher. mov ah,0ch Hier wird in das ah also das Low Register der Wert 0ch bewegt. 0ch ist die Farbe in dem Fall Rot. Warum ist das Rot werden sie sich Fragen. EGA /VGA - Farbattribut im Textmodus Hintergrund | Vordergrund Blinken Rot Grün Blau x(Intensität) x(rot) x(grün) x (blau) 7 Bit x x x x Hintergrund Vordergrund 0c Hexadezimal == 1100 Binär == 0000 1100 Binär

Also, Hintergrund: Blinken=0 Rot=0 Grün=0 folgt: Schwarz Vordergrund Intensität=1 Rot=1 grün=0 blau=0 folgt: Rot Intensiv
Für jedes x wurde der endsprechenden Binär Wert ( 1 oder 0 ) eingesetzen. Bei einer 1 ist die Farbe gesetzt bei einer 0 nicht. So jetzt haben wir das mit der Farbe geklärt. mov di,2000 2000 wird ins di Register bewegt. Jetzt werdet ihr denken das müsste 2000h heißen. Könnte es da wäre das aber eine andere Zahl. 2000 ist in dem Fall dezimal. Die andern Angaben hättet ihr näturlich auch dezimal schreiben können. Aber richtig umrechnen. Ihr hättet statt 2000 also auch 7D0h schreiben können. Noch was genau das wird die Stelle sein an der das Herz ausgegeben wird. Der Offset. In dem Modus in dem wir uns befinden gibt es 80 Zeilen und 25 Spalten also 80 Buchstaben in einer Reihe und 25 nach unten. Also rechnen ist angesagt. 2000 (Offeset) : 80 Zeilen = 25 Spalte Das würd doch heißen das unser Herz ganz unten rechts ausgeben wird. Das Herz wird aber in der Mitte des Bildschirms ausgegeben. 25 : 2 == 12,5 Also in der 12 Spalte und 40 Reihe, weil zuerst einmal die Farbe und einmal das Zeichen ausgegeben werden muss und die brauchen zusammen den Offset 2 und nicht 1. mov ds:[di],ax Das ist das schwerste von allem. Hier wird das ganze was wir hin und her bewegt haben endgültig auf den Bildschirm gebracht. Das was in den [] steht ist der Offset an den das was dannach ,ax steht (Zeichen und Farbe) im Grafikmodus Modus (b800h) auf den Bildschirm gebracht. mov ah,4ch int21h code ebds end start end Jetzt kommt der Ausstieg zum Dos und das Beenden des Programms wird später noch mal genauer erklärt. Kurz noch zu int. int ist ein Interuppt. Dazu aber auch später mal. Jetzt heißt es für euch das ganze irgennwie zu kapieren und mal ein bischen rumzuspeilen. Die Stelle an der das Herz ausgegeben wird verändern, die Farbe verändern und statt dem Herz mal irgenntein anders ASCII Zeichen ausgeben. Versucht mal andere Register zu benutzten, statt z.B statt ax, bx ob das Programm dann auch läuft?


Bedingter Sprung mit jne (Jump not equal)

Zum Inhaltsverzeichnis Jetzt wird das Herz Programm etwas erweitert. code segment assume cs:code start: mov ax,0b800h mov ds,ax mov al,03h mov ah,0ch mov di,2000 marke: mov ds:[di],ax inc di inc di cmp di,2010 jne marke ; mov ah,4ch int 21h code ends end start end Die meißtens Sachen wurden schon erklärt kommen wir zu den neuen Sachen. Es wird ein rotes Herz ausgegeben, dann geht es jetzt noch weiter: marke: Hier haben wir eine Marke gesetzt man könnte ihr auch jeden x beliebigen Namen geben. inc di inc di Hier wird die jeweils das di Register um 1 erhöht. Also 2000 + 2. cmp di,2000 cmp heißt so was wie compare was auf deutsch Vergleichen heißt. Es wird also verglichen ob der Wert von di 2010 ist. Es ist nicht auf 2010 sondern auf 2002. Wenn ja (di == 2000) dann wird das Zero Flag gesetzt! jne marke jne heißt Jump not equal was zu deutsch heißt Sprung nicht möglich. Wir springen aber nur dann wenn das Zero Falg nicht gesetzt ist! Das heißt wenn cmp das Zero setzt, also di == 2000 dann wird nicht mehr gesprungen. Aber wir springen zu: marke: mov ds:[di],ax. Nun wird wieder ein Herz ausgegeben, aber da di 2002 ist wird das Herz eine Stelle weiter ausgegeben. Das ist wie eine Schleife. di wird so lange erhöht bis di den Wert 2010 hat, erst dann kehrten wir zum Dos zurück. Also gibt das Programm fünf Herzen in der Mitte aus. ; Ende der Schleife zur Übersicht. Jetzt könnt ihr wieder ein bischen rumexperimentiern zum Beispiel cmp di 2100 schreiben. Anmerkung:
Es gibt auch noch jz(Jump Zero). Es wird nur dann gesprungen wenn das Zero Flag 0 ist, also das Gegenstück zu jne.


Unterprogramm

Zum Inhaltsverzeichnis Jetzt werden wir ein Programm mit einem Unterprogramm schreiben. Das Programm wird jetzt schon etwas umfangreicher. code segment assume cs:code start:mov ax,0b800h mov ds,ax mov bx,10*160+20 mov ah,14 mov al,'A' agn: mov ds:[bx],ax call zeit add bx,2 inc al cmp al,05bh jne agn ; mov ah,4ch int 21h ;----------------Unterprogramm------------------- zeit: push ax push bx ; mov bx,1000 mov ax,0 schl1:dec ax cmp ax,0 jne schl1 dec bx cmp bx,0 jne schl1 ; pop bx pop ax ret ;---------------Ende---------------------------- code ends end start end Das am Anfang ist klar. mov bx,10*160+20 So kann man auch einen Wert in bx bewegen. Also steht in bx jetzt 1620 (10*160+20) mov ah,14 Hier wird in ah 14 bewegt. Das h fehlt am Ende also ist dies dezimal. Schaun wir mal was 14 für eine Farbe ist. 14 Dezimal == 0000 1110 Binär. Das ist der Vordergrund: Intensiv grün + rot =gelb. mov al,'A' agn: mov ds:[bx],ax Hier ist bx der Offset, nicht wie vorher di. Hier wird das ein gelbes A auf den Bildschirm ausgeben. call zeit call ruft das Unterprogramm zeit auf. call springt also zu zeit. Jetzt sind wir im Unterprogramm. push ax push bx ; Wisst ihr was ein Stack (Stapel) ist? Ihr habt 20 Blatt Papier und legt diese aufeinander, ihr habt einen Stapel. Gut genau das wird mit push ax und push bx gemacht. Jetzt könnt ihr z.B ax den Wert 20 zuweisen. Jetzt nimmt ihr ax wieder vom Stapel und der Ursprungswert ist wieder da. Das heißt also wir können jetzt mit ax und bx beliebig arbeiten und dann ax und bx wieder vom Stack holen und haben in ah 14 und in al ein 'A'. Bedenkt aber das gilt was zuerst auf den Stapel kommt wird als letztes wieder vom Stapel geholt. mov bx,1000 mov ax,0 bx == 1000 ax== 0 schl1:dec ax cmp ax,0 jne schl1 dec bx cmp bx,0 jne schl1 ; dec zieht vom ax Register eins ab. 0 - 1 = -1 ?! Nein das funktioniert wie eine Waage. Nun steht im ax der höchste Wert den ein Register einnehmen kann nämlich ffff Hexadezimal. Das ganze ist eine riesig Schleife die als Zeitverzögerung dient. Es wird solange ax verringert bis ax 0 ist, dann wird bx um eins verringert und dann wird wieder ax solange verringert bis ax 0 ist und das 1000 mal. pop bx pop ax ret Mit pop bx und pop ax wird das ax und bx wieder auf den Ursprünglichen Wert zurückgeholt(vom Stapel). Zuerst bx und dann ax weil gilt was zuerst auf den Stabel geht geht zuletzt raus, sonst hätte ax den Wert von bx. Mit ret kehren wir zum Hauptprogramm zurück. add bx,2 Das bx Register wird um 2 erhöht. Damit die Bildschirmausgabe eins weiter nach rechts ist. inc al Das al wird um eins erhöht, was den nach der ASCII Tabelle ein B ist. cmp al,05bh jne agn ; Wieder eine Schleife. Solange al nicht 05b hex ist springt das Programm wieder nach agn und wieder holt das ganze. 05b ist das Z. Das Programm gibt also das Alfabet mit einer Zeitverzögerung aus.


Die Bedeutung von Interrupts (am Beispiel vom BIOS Interrupt 10h)

Zum Inhaltsverzeichnis Ein Interrupt ist eine Programmunterbrechung. Es gibt Software und Hardwareinterrupts. Der Softwareinterrupt Ein Softwareinterrupt wird wie der Name schon sagt von Software bzw von Betriebsystemen (OS Operating System) ausgeführt. Was ein bestimmter Interrupt macht kann man anhand einer sogenannten Vektortabelle entnehmen. Beim Bootvorgang von MS DOS zum Beispiel wird im untersten Bereich des RAM's diese Tabelle aufgebaut. Bei einem Softwareinterrupt muss die CPU die Adresse des Vektors in der Tabelle finden. Wie das geht würde den Rahmen ersteinmal sprengen, weil ich dann erstmal die Adressierung des Ram erklären müsste. Der wichtigste DOS Interrupt ist INT 21h, damit können mit Hilfe des AH Registers alle MS Dos Funktionen aufgerufen werden. Nun versteht ihr auch den aus stieg zum DOS,denmit mov ah,4ch wird das Programm beendet. Es gibt auch Windows Interrupts aber wir Programmieren unter Dos. Der Hardewareinterrupt Wenn zum Beispiel die Maus bewegt oder eine Taste gedrückt wird, wird ein Hardewareinterrupt ausgelöst, dieser wird an den Programmierbaren Interrupt Controller geleitet der diesen auswertet (welches Gerät Maus oder Tastatur?) und das an die CPU weiterleitet. Jedes Gerät (Peripheri) hat einen IRQ (Interrupt Request), so ist über IRQ 1 die Tastatur angeschlossen, so wertet der Interrupt Controller aus von welchem Gerät der Interrupt kommt. Und nun kommen wir zu den wohin ich hin will, nämlich den BIOS (Basic Input output System) Interrupts. Diese gehören zu den Softwareinterrupts. Wer nicht weiß was das Bios ist sollte mal im Internet suchen. Kurz: Beim Starten des Pc beginnt der Betriebsystem unabhängige Vorgang Post. Der Taktgeber beginnt zu arbeiten. Dann wird das Bios geladen. Die Hardware wird nun vom BIOS geprüft bzw erkannt. Das Bios sind also Dienstprogramm die auf unterster Ebene mit der Hardware komunizieren. Genauso hat das Bios Interrupts die in auch in einer Vektortabelle stehen. Jetzt werdet ihr spätestens gemerkt haben wie Hardwarenah Assambler ist. Es gibt jede Menge Interrupts die dann hunderte weiter Funktionen haben. Kommen wir entlich zu einem weiteren Programm: ;Gibt ein Pixel aus das sich mit w, a, s, d bewegen lässt code segment assume cs:code .286 start: mov al,12h mov ah,0 int 10h ; mov al,14 mov bh,0 mov cx,20 mov dx,100 mov ah,0ch pix: pusha int 10h popa ; push ax mov ah,8 int 21h cmp al,'w' je oben cmp al,'s' je unten cmp al,'a' je links cmp al,'d' je rechts jmp aus oben: dec dx pop ax jmp pix unten: inc dx pop ax jmp pix links: dec cx pop ax jmp pix rechts:inc cx pop ax jmp pix ; aus: pop ax mov al,3 mov ah,0 int 10h ; mov ah,4ch int 21h ; code ends end start end Gehen wir das Programm durch. .286 Sagt beim Übersetzter das der Pc ein 286 ist, das brachen wir weil wir uneren Pc in einen Grafikmodus versetzen und diesen gab es beim 8086 noch nicht. (ab dem 286 kann der Prozessor auch in den Protected Mode geschaltet werden. Kurz man kann mehr als 1MB Ram addressieren) Merkt euch einfach wir arbeiten stehts im Real Mode, indem nur 1 MB Ram verwaltet werden können, weil in diesem Modus nur 20 Addressleitungen zu Verfügung stehen. start: mov al,12h mov ah,0 int 10h ; Hier wird der Grafikmodus gesetzt, der durch den Bios Interrupt 10h aufgerufen wird. al bestimmt den Modus zum Beispiel Auflösung, in der Vektortabelle sieht man was man mit 10h alles machen kann. mov al,14 mov bh,0 mov cx,20 mov dx,100 mov ah,0ch mov al,14 wird die Farbe des Pixels (gelb) mov bh,0 ist Bildschirmseite 0 (wird noch erklärt) mov cx,20 x Koordinate des ausgegebenen Pixels mov dx,100 y Koordinate des ausgegebenen Pixels mov ah,0ch Funktion vom Bios Interrupt 10h pix: pusha int 10h popa ; Mit pusha werden alle Register auf den Stapel gelegt anschliessend wird der Pixel ausgegeben (int 10h) Die Koordinaten stehen in cx und dx und die Farbe in al. Mit popa werden alle Register wieder vom Stapel geholt. push ax mov ah,8 int 21h ax wird auf den Stapel gelegt. Mit mov ah,8 wird auf einen Tastendruck gewartet. Der wichtigste DOS Interrupt ist INT 21h, damit können mit Hilfe des AH Registers alle MS Dos Funktionen aufgerufen werden. cmp al,'w' je oben cmp al,'s' je unten cmp al,'a' je links cmp al,'d' je rechts jmp aus oben: dec dx pop ax jmp pix unten: inc dx pop ax jmp pix links: dec cx pop ax jmp pix rechts:inc cx pop ax jmp pix ; Hier wird geprüft ob das eingebene Zeichen ein w,s,a,d ist. Wenn ja wird zur Marke oben, unten, links oder rechts gesprungen die dann die Koordinaten entsprechend verändert. Dann springt das Programm wieder zu pix, in der der Pixel ausgegeben wird usw. Wenn einen andere Taste gedrückt wird springt das Programm zur Marke aus: Noch was jede Taste hat einen Hexadezimalen werd über die sie auch angesprochen werden kann. cmp al,'s', was macht man wenn man die Pfeiltaste statt es verwenden will, man nimmt den Hexwert für die Pfeiltasten. aus: pop ax mov al,3 mov ah,0 int 10h ; mov ah,4ch int 21h ; code ends end start end ax wird wieder vom Stapel geholt anschliessend wird der Textmodus mit mov al,3 gesetzt. mov ah,0 ist eine Funktion vom int 10h die dann mit int 10h ausgeführt wird. Dannach gehts zurück zum Dos. Damit ihr eine kleine Vorstellung von einer Interrupttabelle hab oder was sie beinhaltet und wie groß sie ist hier die Funktion des BIOS Interrupts 10h. Ihr werdet vieles nicht versehen macht aber nix, ich versteh auch nicht alles. Wie gesagt das ist nur einer von hunderten Interrupts.

Die Funktionen den Interruptes 10h (Video-BIOS) stellt die folgende Tabelle dar:

FunktionUnter- FunktionBedeutungEingabeAusgabeBIOS - ImplementierungAnmerkungen
00h-Video - Modus setzenAH=00h
AL=Videomodus
keinePC, XT, AT, PS/2Videomodi
01h-Cursor - GrößeAH=01h
CH=Startzeile
CL=Endzeile
keinePC, XT, AT, PS/2Die Angaben im CX-Register beziehen sich auf die logische Zeile eines Zeichens (von oben). Der Bereich der Werte hängt von der Zeichengröße und der verwendeten Videokarte ab.
02h-Cursorposition ändernAH=02h
BH=Nummer der Bildschirmseite
DH=Zeile
DL=Spalte
keinePC, XT, AT, PS/2Liegt ein angegebener Bereich im Register DX nicht innerhalb einer sichtbaren Position, kann der Cursor verschwinden.
03h-Cursorposition lesenAH=03h
BH=Nummer der Bildschirmseite
DH=Zeile
DL=Spalte
CH=Startzeile
CL=Endzeile
PC, XT, AT, PS/2Start- und Endzeile sind Werte entsprechend Funktion 01h.
04h-Lichtstiftposition abfragen??????EGAEs lagen leider nicht genügend Informationen zu dieser Funktion vor.
05h-Bildschirmseite wählenAH=05h
AL=Nummer der Bildschirmseite
keinePC, XT, AT, PS/2Zulässige Werte sind von der installierten Videokarte abhängig
06h-Rechteckigen Bereich des Bildschirms aufwärts rollenAH=06h
AL=Anzahl Zeilen
CH=obere Zeile
CL=linke Spalte
DH=untere Zeile
DL=rechte Spalte
BH=Attribut für neue Zeilen
keinePC, XT, AT, PS/2Wird für AL 0 übergeben, wird der ganze Bereich gelöscht. Die Funktion bezieht sich immer auf die aktuelle Bildschirmseite.
07h-Rechteckigen Bereich des Bildschirms abwärts rollenAH=07h
AL=Anzahl Zeilen
CH=obere Zeile
CL=linke Spalte
DH=untere Zeile
DL=rechte Spalte
BH=Attribut für neue Zeilen
keinePC, XT, AT, PS/2Wird für AL 0 übergeben, wird der ganze Bereich gelöscht. Die Funktion bezieht sich immer auf die aktuelle Bildschirmseite.
08h-Lesen eines Zeichens an der aktuellen CursorpositionAH=08h
BH=Nummer der Bildschirmseite
AL=ASCII - Code des Zeichens
AH=Attribut des Zeichens
PC, XT, AT, PS/2-
09h-Schreiben eines ZeichensAH=09h
BH=Nummer der Bildschirmseite
CX=Anzahl der Wiederholungen
AL=ASCII - Code
BL=Attribut / Farbe
keinePC, XT, AT, PS/2Es werden CX Zeichen ausgegeben. Steuercodes werden nicht berücksichtigt. Im Grafikmodus erfolgt kein Zeilenumbruch, außerdem bedeutet ein gesetztes Bit 7 im Register BL, daß die Zeichenfarbe mit dem aktuellen Zeichenmuster XOR-verknüpft wird.
0Ah-Schreiben eines ZeichensAH=0Ah
BH=Nummer der Bildschirmseite
CX=Anzahl der Wiederholungen
AL=ASCII - Code
BL=Farbe im Grafikmodus
keinePC, XT, AT, PS/2Es werden CX Zeichen ausgegeben. Steuercodes werden nicht berücksichtigt. Im Grafikmodus erfolgt kein Zeilenumbruch, außerdem bedeutet ein gesetztes Bit 7 im Register BL, daß die Zeichenfarbe mit dem aktuellen Zeichenmuster XOR-verknüpft wird.
0Bh00hRahmen- / Hintergrundfarbe setzenAH=08h
BH=0
BL=Rahmen- / Hintergrundfarbe
keinePC, XT, AT, PS/2Im Textmodus wird nur der Bildschirmrahmen, im Grafikmodus der gesamte Bildschirm bestimmt.
0Bh01hFarbpalette wählenAH=0Bh
BH=1
BL=Nummer der Farbpalette
keinePC, XT, AT, PS/2Diese Funktion wählt eine der beiden Farbpaletten für den 320x200-Grafikmodus aus.
0Ch-Bildpunkt setzen (Grafik-Modus)AH=0Ch
BH=Nummer der Bildschirmseite
DX=Zeile
CX=Spalte
AL=Farbe
keinePC, XT, AT, PS/2Der Wertebereich in BL ist abhängig vom momentanen Videomodus und gilt als relativer Wert zur aktuellen Farbpalette.
0Dh-Bildpunkt lesen (Grafik-Modus)Ah=0Dh
BH=Nummer der Bildschirmseite
DX=Zeile
CX=Spalte
AL=FarbePC, XT, AT, PS/2Der Wertebereich in BL ist abhängig vom momentanen Videomodus und gilt als relativer Wert zur aktuellen Farbpalette.
0Eh-Zeichen an aktuelle Cursorposition schreiben und Position aktualisieren AH=0Eh
AL=ASCII - Code
BL=Farbe im Grafikmodus
keinePC, XT, AT, PS/2Als Farbe wird das aktuelle Attribut verwendet. Es erfolgt wenn nötig ein Zeilenumbruch. Steuerzeichen werden als solche erkannt.
0Fh-Video - Modus lesenAH=0FhAL=Nummer des Video - Modus
AH=Anzahl der Zeichen pro Zeile
BH=Nummer der aktuellen Bildschirmseite
PC, XT, AT, PS/2
10h00hPalettenregister setzenAH=10h
AL=0
BL=Nummer des Palettenregisters
BH=Farbwert
keineEGA, VGA, PS/2Bestimmt den Farbwert eines Punktes in den 16-Farb-Modi.
10h01hRahmenfarbe setzenAH=10h
AL=1
BH=Farbwert
keineEGA, VGA, PS/2-
10h02hAlle Palettenregister setzenAH=10h
AL=2
ES=Segmentadresse der Farbtabelle
DX=Offsetadresse der Farbtabelle
keineEGA, VGA, PS/2Verändert alle Palettenregister einschließlich des Rahmens. ES:DX zeigt auf eine Tabelle mit 17 Einträgen für die Palettenregister.
10h03hHintergrund - Intensität / Blinkenattribut setzenAH=10h
AL=3
BL=Blink - Attribut (0: helle Hintergrundfarben, 1: Blinken)
keineEGA, VGA, PS/2Diese Funktion ermöglicht die Darstellung von 16 Hintergrundfarben und legt damit fest, wie Bit 7 des Attribut - Bytes interpretiert wird.
10h07hPalettenregister lesenAH=10h
AL=7
BL=Nummer des Palettenregisters
BH=FarbwertVGA, PS/2-
10h08hRahmenfarbe lesenAH=10h
AL=8
BH=RahmenfarbeVGA, PS/2-
10h09hAlle Palettenregister lesenAH=10h
AL=9
ES=Segmentadresse der Farbtabelle
DX=Offsetadresse der Farbtabelle
Farbtabelle in ES:DXVGA, PS/2Gegenstück zu Unterfunktion 2h.
10h10hDAC - Register setzenAH=10h
AL=10h
BX=Registernummer
CL=Blauanteil
CH=Grünanteil
DH=Rotanteil
keineVGA, PS/2Für die Farbwerte sind Werte zwischen 0 und 63 (6 Bit) zulässig. Die VGA-Karte verwendet DAC (Digital - Analog - Converter) - Register, um digitale Farbsignale, bestehend aus 18 Bit, in analoge Monitorsignale umzuwandeln.
10h12hMehrere DAC - Register setzenAH=10h
AL=12h
BX=Nummer des ersten Registers
CX=Anzahl der Register
ES=Segmentadresse der Farbtabelle
DX=Offsetadresse der Farbtabelle
keineVGA, PS/2Setzt CX DAC - Register mit den Werten aus dem Puffer, die in der Reihenfolge Rot-Grün-Blau abgelegt sein müssen.
10h13hMethode der Farbauswahl festlegen oder DAC - Register - Gruppe auswählen?????????Zu dieser Funktion standen leider nicht genügend Informationen zur Verfügung.
10h15hDAC - Register lesenAH=10h
AL=15h
BX=Registernummer
CL=Blauanteil
CH=Grünanteil
DH=Rotanteil
VGA, PS/2Farbwerte liegen zwischen 0 und 63.
10h17hMehrere DAC - Register lesenAH=10h
AL=17h
BX=Nummer des ersten Registers
CX=Anzahl Register
ES=Segmentadresse der Farbtabelle
DX=Offsetadresse der Farbtabelle
Farbtabelle in ES:DXVGA, PS/2-
10h18hDAC - Mask - Register laden?????????Zu dieser Funktion standen leider nicht genügend Informationen zur Verfügung.
10h19hInhalt des DAC - Mask - Registers auslesen?????????Zu dieser Funktion standen leider nicht genügend Informationen zur Verfügung.
10h1AhMethode der Farbauswahl und Inhalt des Color - Select - Registers ermitteln ?????????Zu dieser Funktion standen leider nicht genügend Informationen zur Verfügung.
10h1BhInhalt der DAC - Farbregister in Grauwerte umwandeln?????????Zu dieser Funktion standen leider nicht genügend Informationen zur Verfügung.
11h00hZeichensatz ladenAH=11h
AL=0
BH=Byte pro Zeichen
BL=Zeichentabelle (0 oder 1)
CX=Zeichenzahl
DX=ASCII - Code des ersten Zeichens
ES=Segmentadresse der Zeichentabelle
Offsetadresse der Zeichentabelle
keineEGA, VGA, PS/2Lädt einen benutzerdefinierten Zeichensatz in den Grafikspeicher der Videokarte. Der Zeichensatz wird nicht aktiviert, die Größe der Zeichen nicht der Bildschirmdarstellung angepaßt.
11h01h8*14 - Zeichensatz ladenAH=11h
AL=1
BL=Zeichentabelle
keineEGA, VGA, PS/2Lädt 8*14 - Zeichensatz, aktiviert ihn aber nicht.
11h02h8*8 - Zeichensatz ladenAH=11h
AL=2
BL=Zeichentabelle
keineEGA, VGA, PS/2Lädt 8*8 - Zeichensatz, aktiviert ihn aber nicht.
11h03hZeichensatz aktivierenAH=11h
AL=3
BL=Nummer des Zeichensatzes
keineEGA, VGA, PS/2Diese Funktion aktiviert einen der vier Zeichensätze.
11h04h8*16 - Zeichensatz ladenAH=11h
AL=4
BL=Zeichentabelle
keineVGA, PS/2Lädt 8*16 - Zeichensatz, aktiviert ihn aber nicht.
11h10hZeichensatz laden & aktivierenAH=11h
AL=10h
BH=Byte pro Zeichen
BL=Zeichentabelle (0 oder 1)
CX=Zeichenzahl
DX=ASCII - Code des ersten Zeichens
ES=Segmentadresse der Zeichentabelle
BP=Offsetadresse der Zeichentabelle
keineEGA, VGA, PS/2Lädt einen benutzerdefinierten Zeichensatz in den Grafikspeicher der Videokarte. Der Zeichensatz wird aktiviert und die Größe der Zeichen der Bildschirmdarstellung angepaßt.
11h11h8*14 - Zeichensatz aktivierenAH=11h
AL=11h
BL=Zeichentabelle
keineVGA, PS/2Lädt den 8*14 - Zeichensatz und aktiviert ihn. Die VGA - Karte schaltet dazu in den 28 - Zeilen - Modus.
11h12h8*8 - Zeichensatz aktivierenAH=11h
AL=12h
BL=Zeichentabelle
keineEGA, VGA, PS/2Lädt den 8*8 - Zeichensatz und aktiviert ihn. Die VGA - Karte schaltet dazu in den 50 - Zeilen - Modus (EGA 43).
11h14h8*16 - Zeichensatz aktivierenAH=11h
AL=14h
BL=Zeichentabelle
keineVGA, PS/2Lädt den 8*16 - Zeichensatz und aktiviert ihn.
11h30hZeichensatz - InformationenAH=11h
AL=30h
BH=Zeichensatz
CX=Bytes pro Zeichen
DL=Anzahl der Bildschirmzeilen
ES=Segmentadresse der Zeichentabelle
BP=Offsetadresse der Zeichentabelle
EGA, VGA, PS/2Informationen über einen Zeichensatz, dessen Code Sie in BH übergeben haben folgt am Ende dieser Tabelle.
12h10hEGA - Konfiguration ermitteln?????????Zu dieser Funktion standen leider nicht genügend Informationen zur Verfügung.
12h20halternative Hardcopy - Routine aktivieren?????????Zu dieser Funktion standen leider nicht genügend Informationen zur Verfügung.
12h30hAnzahl der Bildschirmzeilen (Scan - Lines) festlegen?????????Zu dieser Funktion standen leider nicht genügend Informationen zur Verfügung.
12h31hLaden der Standard-PaletteAH=12h
BL=31h
AL=Modus (0: automatisches Laden erlauben; 1: dto. verbieten)
AL=12hVGA, PS/2Legt fest, ob bei der Umschaltung des Videomodus mit Funktion 00h die Palettenregister mit den Standardwerten geladen werden.
12h32hZugriff auf Video - RAMAH=12h
BL=32h
AL=Modus (0: erlauben; 1: verbieten)
keineVGA, PS/2Legt fest, ob der CPU ein Zugriff auf das Video - RAM oder Hardware - Register gestattet wird.
12h33hAutomatische Grau-Umwandlung der DAC - Farbregister an- / ausschalten?????????Zu dieser Funktion standen leider nicht genügend Informationen zur Verfügung.
12h34hCursor - Emulation an- / ausschalten?????????Zu dieser Funktion standen leider nicht genügend Informationen zur Verfügung.
12h36hBildschirm dunkelschaltenAH=12h
BL=36h
AL=Modus (0: Bildschirm an; 1: Bildschirm aus)
keineVGA, PS/2Ermöglicht es, den Bildschirmaufbau zu unterdrücken und damit den Bildschirm dunkelzuschalten.
13h-TextausgabeAH=13h
AL=Modus
BL=Attribut
BH=Bildschirmseite
CX=Anzahl Zeichen
DH=Zeile
DL=Spalte
ES=Segmentadresse des Puffers
BP=Offsetadresse des Puffers
keineEGA, VGA, PS/2Gibt eine Zeichenkette entsprechend dem in AL gesetzten Modus (unter dieser Tabelle) aus. Steuercodes werden interpretiert. Der Bildschirm wird bei Bedarf automatisch gerollt.
14h-reserviert----
15h-reserviert----
16h-reserviert----
17h-reserviert----
18h-reserviert----
19h-reserviert----
1Ah00hPrimären und sekundären Video - Adapter ermitteln ?????????Zu dieser Funktion standen leider nicht genügend Informationen zur Verfügung.
1Ah01hPrimären und sekundären Video - Adapter einstellen ?????????Zu dieser Funktion standen leider nicht genügend Informationen zur Verfügung.
1Bh-Statusinformationen über den Video-Modus und das VGA-BIOS einholen ?????????Zu dieser Funktion standen leider nicht genügend Informationen zur Verfügung.
1Ch00hGröße der Save - Area abfragen?????????Zu dieser Funktion standen leider nicht genügend Informationen zur Verfügung.
1Ch01hVideo - Status sichern?????????Zu dieser Funktion standen leider nicht genügend Informationen zur Verfügung.
1Ch02hVideo - Status restaurieren?????????Zu dieser Funktion standen leider nicht genügend Informationen zur Verfügung.

Zeichensatz - Codes

CodeBedeutung
00hZeichensatz von Interrupt 1Fh
01hZeichensatz von Interrupt 43h
02h8*14 - ROM -Zeichensatz
03h8*8 - ROM -Zeichensatz (ASCII 00 - 7Fh)
04h8*8 - ROM -Zeichensatz (ASCII 80 - FFh)
05h9*14 - ROM -Zeichensatz
06h8*16 - ROM -Zeichensatz
07h9*16 - ROM -Zeichensatz

Werte für AL (Funktion 13h)

ModusBedeutung
0Cursorposition wird nicht aktualisiert, BL wird als Attribut verwendet.
1Cursorposition wird aktualisiert, BL wird als Attribut verwendet.
2Cursorposition wird nicht aktualisiert, das Attribut jedes Zeichens ist im Puffer enthalten.
3Cursorposition wird aktualisiert, das Attribut jedes Zeichens ist im Puffer enthalten.

Alle Angaben ohne Gewähr.



Wer noch mehr Interrupt Tabellen anschauen will geht am bessten auf www.datasource.de

Nachwort

Zum Inhaltsverzeichnis Das letzte Kapitel ist sehr kurz gefasst und sehr vereinfacht, weil das Kapitel sehr groß ist und sehr kompliziert, es sollte euch einfach den kleinen Einblick der hardwarenahen Programmierung verdeutlichen. Ich hoffe ihr hattet Spaß. Bis zum nächstenmal. Geschrieben von Philipp
Bei Fragen könnt ihr mir mailen.