software:diy:assembler:kkurs
Unterschiede
Hier werden die Unterschiede zwischen zwei Versionen angezeigt.
Beide Seiten der vorigen RevisionVorhergehende ÜberarbeitungNächste Überarbeitung | Vorhergehende Überarbeitung | ||
software:diy:assembler:kkurs [21/12/2005 23:12] – 8088 | software:diy:assembler:kkurs [12/11/2024 21:11] (aktuell) – [Teil 2: Prozessorregister und Befehlssatz (aus PofoInfo 3/97)] bttr | ||
---|---|---|---|
Zeile 8: | Zeile 8: | ||
Doch jetzt zur Sache. Bekanntlich tut im Portfolio ein Intel-Prozessor namens 8088 seinen Dienst. Das Faszinierende an dieser 1979 mit dem 8086 (16-Bit-Datenbus, | Doch jetzt zur Sache. Bekanntlich tut im Portfolio ein Intel-Prozessor namens 8088 seinen Dienst. Das Faszinierende an dieser 1979 mit dem 8086 (16-Bit-Datenbus, | ||
+ | |||
==== Maschinensprache und Assembler ==== | ==== Maschinensprache und Assembler ==== | ||
Zeile 17: | Zeile 18: | ||
In den Zeiten als die Programme noch kurz, Disketten Luxus und Mailboxen die Domäne von Hackern waren, wurden Listings ja gern in so einer Form gedruckt. Zur Programmentwicklung ist diese Darstellung jedoch denkbar ungeeignet. Um sich nicht für jeden Maschinenbefehl eine Zahl merken zu müssen, bedient man sich einer anderen Schreibweise. Für alle Maschinenbefehle des Prozessors existieren eingängige Abkürzungen, | In den Zeiten als die Programme noch kurz, Disketten Luxus und Mailboxen die Domäne von Hackern waren, wurden Listings ja gern in so einer Form gedruckt. Zur Programmentwicklung ist diese Darstellung jedoch denkbar ungeeignet. Um sich nicht für jeden Maschinenbefehl eine Zahl merken zu müssen, bedient man sich einer anderen Schreibweise. Für alle Maschinenbefehle des Prozessors existieren eingängige Abkürzungen, | ||
- | | + | <code asm> |
- | xor ax,ax ; Zähler auf 0 | + | |
- | Marke: | + | xor ax,ax ; Zähler auf 0 |
- | dec ax ; Zähler -1 | + | Marke: |
- | jnz Marke ; Schleife | + | dec ax ; Zähler -1 |
- | mov ax,4c80h | + | jnz Marke ; Schleife |
- | out dx,al ; Ton aus | + | mov ax,4c80h |
- | int 21h ; beenden | + | out dx,al ; Ton aus |
+ | int 21h ; beenden | ||
+ | </ | ||
==== Unser Handwerkszeug ==== | ==== Unser Handwerkszeug ==== | ||
Zeile 30: | Zeile 33: | ||
Dieser Quelltext muß nun in zwei Schritten mit einem Assembler und einem Linker in ein lauffähiges Programm übersetzt werden. Man kann diese zwei Schritte mit einem Batchprogramm zusammenfassen. Die bekanntesten Assembler sind MASM von Microsoft (zugehöriger Linker: LINK), TASM (Linker: TLINK) von Borland sowie der Sharewareassembler A86. Ich selbst benutze Borlands Turbo Assembler, jedoch scheint mir A86 den einfachsten Einstieg zu ermöglichen, | Dieser Quelltext muß nun in zwei Schritten mit einem Assembler und einem Linker in ein lauffähiges Programm übersetzt werden. Man kann diese zwei Schritte mit einem Batchprogramm zusammenfassen. Die bekanntesten Assembler sind MASM von Microsoft (zugehöriger Linker: LINK), TASM (Linker: TLINK) von Borland sowie der Sharewareassembler A86. Ich selbst benutze Borlands Turbo Assembler, jedoch scheint mir A86 den einfachsten Einstieg zu ermöglichen, | ||
- | Neben einem Assembler sollten zur Grundausstattung aber auch Nachschlagewerke zu den Themen Prozessorarchitektur, | + | Neben einem Assembler sollten zur Grundausstattung aber auch Nachschlagewerke zu den Themen Prozessorarchitektur, |
==== Das erste Programm ==== | ==== Das erste Programm ==== | ||
Zeile 42: | Zeile 45: | ||
Die wichtigsten Befehle, die in Debug immer hinter einem Minuszeichen als Prompt eingegeben werden, lauten: | Die wichtigsten Befehle, die in Debug immer hinter einem Minuszeichen als Prompt eingegeben werden, lauten: | ||
- | | + | ^ Kommando ^ Funktion |
- | e Adr | + | | ? |
- | a Assemble | + | | e // |
- | u Unassemble | + | | a |
- | | + | | u |
- | r cx | + | | |
- | w Write | + | | r cx | Dateilänge festlegen |
+ | | w | ||
Weiterführende Erläuterungen zu Debug sowie eine ältere Version (knapp 10KB), die auch auf dem PF funktioniert, | Weiterführende Erläuterungen zu Debug sowie eine ältere Version (knapp 10KB), die auch auf dem PF funktioniert, | ||
Zeile 90: | Zeile 94: | ||
Der klassische Weg vom Quelltext zum Code führt über die sogenannte Objektdatei. Sie wird vom Assembler aus dem Quelltext erzeugt und enthält einen Mix aus Symbolen und Code. Erst durch das anschließende Linken gelangt man zum ausführbaren Programm. Dieses Verfahren ist zwar vielseitiger (man kann z.B. mehrere Objektdateien zusammenlinken), | Der klassische Weg vom Quelltext zum Code führt über die sogenannte Objektdatei. Sie wird vom Assembler aus dem Quelltext erzeugt und enthält einen Mix aus Symbolen und Code. Erst durch das anschließende Linken gelangt man zum ausführbaren Programm. Dieses Verfahren ist zwar vielseitiger (man kann z.B. mehrere Objektdateien zusammenlinken), | ||
- | | + | <code asm> |
- | .code | + | .model tiny |
- | ORG 100h | + | .code |
- | Start: | + | ORG 100h |
- | xor ax,ax ; Zähler auf 0 | + | Start: |
- | Marke: | + | xor ax,ax ; Zähler auf 0 |
- | dec ax ; Zähler -1 | + | Marke: |
- | jnz Marke ; Schleife | + | dec ax ; Zähler -1 |
- | mov ax,4c80h | + | jnz Marke ; Schleife |
- | out dx,al ; Ton aus | + | mov ax,4c80h |
- | int 21h ; beenden | + | out dx,al ; Ton aus |
- | END Start | + | int 21h ; beenden |
+ | END Start | ||
+ | </ | ||
Die hinzugekommenen Assemblerdirektiven machen Angaben über das Speichermodell, | Die hinzugekommenen Assemblerdirektiven machen Angaben über das Speichermodell, | ||
Zeile 127: | Zeile 133: | ||
Das umständlichste - pardon professionellste - Werkzeug stammt, wie sollte es anders sein, aus dem Hause Microsoft. Die hier verwendete MASM-Version 1.25 ist allerdings schon leicht in die Jahre gekommen, so daß das Beispiel eventuell nicht mit aktuelleren Versionen nachvollziehbar ist. Trotzdem hier der angepaßte Quelltext: | Das umständlichste - pardon professionellste - Werkzeug stammt, wie sollte es anders sein, aus dem Hause Microsoft. Die hier verwendete MASM-Version 1.25 ist allerdings schon leicht in die Jahre gekommen, so daß das Beispiel eventuell nicht mit aktuelleren Versionen nachvollziehbar ist. Trotzdem hier der angepaßte Quelltext: | ||
- | | + | <code asm> |
- | ASSUME CS: | + | code SEGMENT |
+ | ASSUME CS: | ||
ORG 100h | ORG 100h | ||
- | | + | Start: |
- | xor ax,ax ; Zähler auf 0 | + | xor ax,ax ; Zähler auf 0 |
- | Marke: | + | Marke: |
- | dec ax ; Zähler -1 | + | dec ax ; Zähler -1 |
- | jnz Marke ; Schleife | + | jnz Marke ; Schleife |
- | mov ax,4c80h | + | mov ax,4c80h |
- | out dx,al ; Ton aus | + | out dx,al ; Ton aus |
- | int 21h ; beenden | + | int 21h ; beenden |
- | code ENDS | + | code ENDS |
- | END Start | + | END Start |
+ | </ | ||
Bis zum Endprodukt sind jetzt drei Schritte erforderlich. Zunächst wie beim Borland-Produkt die Assemblierung und das Linken. LINK erzeugt allerdings eine ausführbare Datei im .EXE-Format (783 Bytes), die danach noch ins COM-Format konvertiert werden muß: | Bis zum Endprodukt sind jetzt drei Schritte erforderlich. Zunächst wie beim Borland-Produkt die Assemblierung und das Linken. LINK erzeugt allerdings eine ausführbare Datei im .EXE-Format (783 Bytes), die danach noch ins COM-Format konvertiert werden muß: | ||
Zeile 177: | Zeile 185: | ||
Mit der Anweisung ASM lassen sich Assemblerbefehle auch in ein Pascalprogramm einbauen. Dabei ist zu beachten, daß Labels mit dem Klammeraffen beginnen müssen und Kommentare in geschweifte Klammern gestellt werden müssen: | Mit der Anweisung ASM lassen sich Assemblerbefehle auch in ein Pascalprogramm einbauen. Dabei ist zu beachten, daß Labels mit dem Klammeraffen beginnen müssen und Kommentare in geschweifte Klammern gestellt werden müssen: | ||
- | | + | <code asm> |
- | ASM | + | begin |
- | mov dx,8020h {Portadresse | + | ASM |
- | xor ax,ax {Zähler auf 0 } | + | mov dx,8020h {Portadresse |
- | @Marke: out dx,al {Ton erzeugen } | + | xor ax,ax {Zähler auf 0 } |
- | dec ax | + | @Marke: out dx,al {Ton erzeugen } |
- | jnz @Marke | + | dec ax |
- | mov ax,4c80h | + | jnz @Marke |
- | out dx,al {Ton aus } | + | mov ax,4c80h |
- | int 21h {beenden | + | out dx,al {Ton aus } |
- | end; | + | int 21h {beenden |
- | end. | + | end; |
+ | end. | ||
+ | </ | ||
Kompiliert mit TP 6.0 ergibt dieser Quelltext ein 1488 Bytes langes .EXE-Programm. Da der Befehl int 21h das Programm vorzeitig beendet, sollte man diese Zeile besser weglassen. Es ist aber auch möglich (z.B. mit DEBUG), unsere 15 Bytes aus dem .EXE Programm herauszuschneiden und als .COM-Programm zu speichern. Der betreffende Abschnitt reicht übrigens vom 16. bis zum 30. der 1488 Bytes. | Kompiliert mit TP 6.0 ergibt dieser Quelltext ein 1488 Bytes langes .EXE-Programm. Da der Befehl int 21h das Programm vorzeitig beendet, sollte man diese Zeile besser weglassen. Es ist aber auch möglich (z.B. mit DEBUG), unsere 15 Bytes aus dem .EXE Programm herauszuschneiden und als .COM-Programm zu speichern. Der betreffende Abschnitt reicht übrigens vom 16. bis zum 30. der 1488 Bytes. | ||
Zeile 201: | Zeile 211: | ||
Von Jan Laitenberger gibt es den __Freeware-Assembler__ JASMIN, der unkomprimiert nur knapp 20 KByte groß ist und speziell für den Einsatz auf dem Portfolio konzipiert wurde. Der begrenzte Funktionsumfang (keine Makros, nur 8086/88, nur COM-Programme) ermöglicht eine sehr einfache Bedienung, so daß JASMIN besonders für Einsteiger gut geeignet ist. Trotz seiner Eigenheiten (Labels müssen mit @ beginnen, Speicherzugriffe sind durch eckige Klammern kenntlich zu machen) ist dieser Assembler ein Muß für Portfolio-Fans! (Bezugsquelle: | Von Jan Laitenberger gibt es den __Freeware-Assembler__ JASMIN, der unkomprimiert nur knapp 20 KByte groß ist und speziell für den Einsatz auf dem Portfolio konzipiert wurde. Der begrenzte Funktionsumfang (keine Makros, nur 8086/88, nur COM-Programme) ermöglicht eine sehr einfache Bedienung, so daß JASMIN besonders für Einsteiger gut geeignet ist. Trotz seiner Eigenheiten (Labels müssen mit @ beginnen, Speicherzugriffe sind durch eckige Klammern kenntlich zu machen) ist dieser Assembler ein Muß für Portfolio-Fans! (Bezugsquelle: | ||
+ | |||
+ | **Update 12.11.2024: | ||
+ | |||
+ | Auszug aus '' | ||
+ | |||
+ | Seit dem 7.10.2006 ist fuer dieses Programm auch der Source-Code | ||
+ | | ||
+ | | ||
+ | in Teilen bedarf der schriftlichen Einwilligung des Autors! | ||
Vielleicht wartet der eine oder andere Leser bereits ungeduldig darauf, endlich die ersten 8086-Befehle (der 8088 ist bekanntlich kompatibel) zu lernen, um selbst ein Assemblerprogramm zu " | Vielleicht wartet der eine oder andere Leser bereits ungeduldig darauf, endlich die ersten 8086-Befehle (der 8088 ist bekanntlich kompatibel) zu lernen, um selbst ein Assemblerprogramm zu " | ||
Zeile 212: | Zeile 231: | ||
Diese Register sind am vielseitigsten einsetzbar. Die oberen bzw. unteren 8 Bits lassen sich auch getrennt verwenden, d.h. es stehen hiermit bis zu acht 8-Bit-Register zur Verfügung. Für die ersten Assembler-Gehversuche reichen die Allzweckregister bereits. | Diese Register sind am vielseitigsten einsetzbar. Die oberen bzw. unteren 8 Bits lassen sich auch getrennt verwenden, d.h. es stehen hiermit bis zu acht 8-Bit-Register zur Verfügung. Für die ersten Assembler-Gehversuche reichen die Allzweckregister bereits. | ||
- | | + | ^ Register |
- | BX = BH|BL Basisregister | + | | |
- | CX = CH|CL Count-Register | + | | BX = BH+BL | Basisregister |
- | DX = DH|DL Daten-Register | + | | CX = CH+CL | Count-Register |
+ | | DX = DH+DL | Daten-Register | ||
__2. Die Index- und Pointerregister__ | __2. Die Index- und Pointerregister__ | ||
Zeile 221: | Zeile 241: | ||
Abgesehen von SP und IP dürfen auch diese Register nach Belieben verwendet werden. Insbesondere eignen sie sich aber zur indirekten Adressierung und für die sog. Stringbefehle. | Abgesehen von SP und IP dürfen auch diese Register nach Belieben verwendet werden. Insbesondere eignen sie sich aber zur indirekten Adressierung und für die sog. Stringbefehle. | ||
- | | + | ^ Register ^ Name/ |
- | SP Stackpointer (Finger weg!) PUSH, POP | + | | |
- | BP Basepointer | + | | |
- | SI Sourceindex | + | | |
- | DI Dest.index | + | | |
+ | | | ||
Zeile 232: | Zeile 253: | ||
Die Segmentregister haben eine spezielle Funktion, die später noch genauer erklärt wird. Nur ES steht zur freien Verfügung. | Die Segmentregister haben eine spezielle Funktion, die später noch genauer erklärt wird. Nur ES steht zur freien Verfügung. | ||
- | | + | ^ Register ^ Name/ |
- | DS Datensegment (Vorsicht!) | + | | |
- | SS Stacksegment (Vorsicht!) | + | | |
- | ES Extrasegment | + | | |
+ | | | ||
__4. Das Flag-Register__ | __4. Das Flag-Register__ | ||
Zeile 246: | Zeile 268: | ||
Wie die Namen der Segmentregister vermuten lassen, ist es vorgesehen, für Programmcode, | Wie die Namen der Segmentregister vermuten lassen, ist es vorgesehen, für Programmcode, | ||
+ | |||
==== Eine handvoll Befehle ==== | ==== Eine handvoll Befehle ==== | ||
Zeile 255: | Zeile 278: | ||
Der vielseitigste und meist genutzte Assemblerbefehl ist sicherlich der MOV-Befehl (move). Er überträgt ein Datenwort z.B. aus dem Speicher in ein Register oder aus einem Register in ein anderes. Zudem unterstützt dieser Befehl verschiedene Adressierungsarten für Speicherzugriffe. Hierzu eine Auswahl an Beispielen: | Der vielseitigste und meist genutzte Assemblerbefehl ist sicherlich der MOV-Befehl (move). Er überträgt ein Datenwort z.B. aus dem Speicher in ein Register oder aus einem Register in ein anderes. Zudem unterstützt dieser Befehl verschiedene Adressierungsarten für Speicherzugriffe. Hierzu eine Auswahl an Beispielen: | ||
+ | |||
+ | <code asm> | ||
mov al,2 ; Lädt das Register al mit dem Wert 2 | mov al,2 ; Lädt das Register al mit dem Wert 2 | ||
mov al, | mov al, | ||
Zeile 261: | Zeile 286: | ||
mov al, | mov al, | ||
; bx im Datensegment steht (indirekte Adressierung) | ; bx im Datensegment steht (indirekte Adressierung) | ||
- | mov cl,[si+3] ; Lädt al mit dem Byte-Wert, der an der Speicherstelle | + | mov cl,[si+3] ; Lädt cl mit dem Byte-Wert, der an der Speicherstelle |
; si+3 im Datensegment steht (indirekte indizierte Adr.) | ; si+3 im Datensegment steht (indirekte indizierte Adr.) | ||
mov [7], | mov [7], | ||
+ | </ | ||
Diese Beispiele wickeln den Datenaustausch mit dem Speicher nur über die 8-Bit-" | Diese Beispiele wickeln den Datenaustausch mit dem Speicher nur über die 8-Bit-" | ||
Wer sich mit DEBUG einmal den Maschinencode für obige Varianten des MOV-Befehls ansieht, kann feststellen, | Wer sich mit DEBUG einmal den Maschinencode für obige Varianten des MOV-Befehls ansieht, kann feststellen, | ||
+ | <code asm> | ||
B002 MOV | B002 MOV | ||
A00200 | A00200 | ||
Zeile 274: | Zeile 301: | ||
8A4C03 | 8A4C03 | ||
88360700 | 88360700 | ||
+ | </ | ||
Besonders effizient codiert wurden die ersten beiden Zeilen: Die Befehlscodes (OP-Codes) bestehen dort aus einem einzigen Byte (B0 bzw. A0), gefolgt von einem bzw. zwei Bytes für den zweiten Parameter. Man sieht auch, daß die 16-Bit-Konstante 0002 im Format Lowbyte/ | Besonders effizient codiert wurden die ersten beiden Zeilen: Die Befehlscodes (OP-Codes) bestehen dort aus einem einzigen Byte (B0 bzw. A0), gefolgt von einem bzw. zwei Bytes für den zweiten Parameter. Man sieht auch, daß die 16-Bit-Konstante 0002 im Format Lowbyte/ | ||
Zeile 300: | Zeile 328: | ||
Dieser Befehl ruft die durch Nummer spezifizierte Interruptroutine auf. Der INT-Befehl stellt die Schnittstelle zum Betriebssystem dar, denn sowohl BIOS als auch DOS belegen etliche Interruptvektoren mit Routinen, die von Anwendungsprogrammen genutzt werden können (und sollen). Je nach Funktion müssen zuvor diverse Parameter in bestimmten Registern abgelegt werden. Beispiel: | Dieser Befehl ruft die durch Nummer spezifizierte Interruptroutine auf. Der INT-Befehl stellt die Schnittstelle zum Betriebssystem dar, denn sowohl BIOS als auch DOS belegen etliche Interruptvektoren mit Routinen, die von Anwendungsprogrammen genutzt werden können (und sollen). Je nach Funktion müssen zuvor diverse Parameter in bestimmten Registern abgelegt werden. Beispiel: | ||
+ | <code asm> | ||
mov ah,7 ; 7=Zeicheneingabe nach al | mov ah,7 ; 7=Zeicheneingabe nach al | ||
int 21h ; 21=wichtigster DOS-Interrupt | int 21h ; 21=wichtigster DOS-Interrupt | ||
Zeile 305: | Zeile 334: | ||
mov ah,6 ; 6=Zeichenausgabe (dl=ASCII) | mov ah,6 ; 6=Zeichenausgabe (dl=ASCII) | ||
int 21h | int 21h | ||
+ | </ | ||
Übrigens lautet der Maschinencode für Int 21h 'CD 21' (dezimal 205, 33) und dürfte eine der häufigsten Bytekombinationen in DOS-Programmen darstellen. | Übrigens lautet der Maschinencode für Int 21h 'CD 21' (dezimal 205, 33) und dürfte eine der häufigsten Bytekombinationen in DOS-Programmen darstellen. | ||
Zeile 312: | Zeile 342: | ||
Eine wichtige Eigenart der 80x86-Prozessorfamilie sind die Portadressen. Parallel zum Arbeitsspeicher existiert ein 64 KByte großer Adreßraum, über den Peripheriebausteine (z.B. paralleles Interface) angesprochen werden. Der Prozessorbefehl IN liest einen 8-Bit- oder 16-Bit-Wert von der Portadresse dx ein. Folgendes Beispiel übernimmt den Zustand der Statusleitungen des Druckerports in das Register al: | Eine wichtige Eigenart der 80x86-Prozessorfamilie sind die Portadressen. Parallel zum Arbeitsspeicher existiert ein 64 KByte großer Adreßraum, über den Peripheriebausteine (z.B. paralleles Interface) angesprochen werden. Der Prozessorbefehl IN liest einen 8-Bit- oder 16-Bit-Wert von der Portadresse dx ein. Folgendes Beispiel übernimmt den Zustand der Statusleitungen des Druckerports in das Register al: | ||
+ | <code asm> | ||
mov dx, | mov dx, | ||
in al,dx ; nur dx möglich! | in al,dx ; nur dx möglich! | ||
+ | </ | ||
**OUT dx, | **OUT dx, | ||
Zeile 324: | Zeile 356: | ||
Addiert zum Operand1 den Operand2. Falls das Ergebnis zu groß für Operand1 ist, wird das Carry-Flag gesetzt (Abfrage z.B. über den bedingten Sprungbefehl JC - jump if carry), welches somit das im Ergebnis fehlende höchste Bit repräsentiert. Beispiel: | Addiert zum Operand1 den Operand2. Falls das Ergebnis zu groß für Operand1 ist, wird das Carry-Flag gesetzt (Abfrage z.B. über den bedingten Sprungbefehl JC - jump if carry), welches somit das im Ergebnis fehlende höchste Bit repräsentiert. Beispiel: | ||
+ | <code asm> | ||
mov cx, | mov cx, | ||
add cx,3 ; cx=2000 | add cx,3 ; cx=2000 | ||
+ | </ | ||
**SUB Operand1, | **SUB Operand1, | ||
Zeile 331: | Zeile 365: | ||
Subtraktion analog zu ADD. Beispiel: | Subtraktion analog zu ADD. Beispiel: | ||
+ | <code asm> | ||
mov bx, | mov bx, | ||
sub bl,bh ; bl=FFh | sub bl,bh ; bl=FFh | ||
+ | </ | ||
Hier wird das Carry-Flag gesetzt, was bedeutet, daß FFh als -1 zu interpretieren ist. | Hier wird das Carry-Flag gesetzt, was bedeutet, daß FFh als -1 zu interpretieren ist. | ||
Zeile 340: | Zeile 376: | ||
Der pure Luxus: Strukturierte Programmierung in Maschinensprache durch Unterprogramme! | Der pure Luxus: Strukturierte Programmierung in Maschinensprache durch Unterprogramme! | ||
+ | <code asm> | ||
| | ||
call PortAus | call PortAus | ||
Zeile 351: | Zeile 388: | ||
pop dx ; Reihenfolge | pop dx ; Reihenfolge | ||
ret | ret | ||
+ | </ | ||
**Weitere Prozessorbefehle** | **Weitere Prozessorbefehle** | ||
Zeile 356: | Zeile 394: | ||
Aus Platzgründen kommen hier leider viele nützliche Befehle zu kurz. Wenigstens nicht unerwähnt bleiben sollten diese Instruktionen: | Aus Platzgründen kommen hier leider viele nützliche Befehle zu kurz. Wenigstens nicht unerwähnt bleiben sollten diese Instruktionen: | ||
- | | AND, OR, XOR | bitweise | + | ^ Mnemonic |
- | | INC, DEC | Operand um 1 erhöhen/ | + | | AND, OR, XOR | Bitweise |
- | | ADC, SBC | Addition/Subtr. | + | | INC, DEC | Operand um 1 erhöhen/ |
- | | LOOP | Schleife mit cx als Zähler | + | | ADC, SBC | Addition/Subtraktion |
- | | SHL,SHR ROL,ROR | Schieben und Rotieren | + | | LOOP | Schleife mit cx als Zähler |
- | | LODSB, STOSB | Stringbefehle | + | | SHL,SHR ROL,ROR | Bitweises |
+ | | LODSB, STOSB | Stringbefehle | ||
==== Ein Wort zur Ausführungsgeschwindigkeit ==== | ==== Ein Wort zur Ausführungsgeschwindigkeit ==== | ||
Zeile 428: | Zeile 467: | ||
Summe: DW ? ; wird 900 | Summe: DW ? ; wird 900 | ||
- | Die meisten Assembler unterstützen für die hier auftretenden Speicherreferenzen eine spezielle Form von Labels ohne Doppelpunkt, | + | Die meisten Assembler unterstützen für die hier auftretenden Speicherreferenzen eine spezielle Form von Labels ohne Doppelpunkt, |
mov ax, | mov ax, | ||
Zeile 440: | Zeile 479: | ||
==== Auf Nummer sicher ==== | ==== Auf Nummer sicher ==== | ||
- | Dank der " | + | Dank der " |
- | Eine einfache Möglichkeit, | + | Eine einfache Möglichkeit, |
Noch nobler ist es aber, dem Betriebssystem zur Laufzeit mitzuteilen, | Noch nobler ist es aber, dem Betriebssystem zur Laufzeit mitzuteilen, | ||
Zeile 500: | Zeile 539: | ||
Die Bedeutung der Ein-/ | Die Bedeutung der Ein-/ | ||
+ | ^ Adresse ^ Funktion | ||
| 8000 | Keyboard-Scancode (>128 => losgelassen) | | 8000 | Keyboard-Scancode (>128 => losgelassen) | ||
| 8010 | LCD controller Datenregister | | 8010 | LCD controller Datenregister | ||
Zeile 544: | Zeile 584: | ||
| ; | | ; | ||
| = | | = | ||
- | | links | | + | | links |
- | | rechts| | + | | rechts |
- | | | + | | |
- | | unten | | + | | unten |
- | | lShift| | + | | lShift |
- | | rShift| | + | | rShift |
- | | Fn | | + | | Fn | |
- | | | + | | |
- | | Enter | | + | | Enter |
- | | Space | | + | | Space |
- | | Ä | + | | |
- | | Ü | + | | |
- | | \ / < | | + | | |
- | | + / ] | | + | | |
- | | Caps | | + | | |
- | | | + | | |
Zur Verdeutlichung wieder ein konstruierter Programmausschnitt, | Zur Verdeutlichung wieder ein konstruierter Programmausschnitt, | ||
Zeile 618: | Zeile 658: | ||
==== Verkehrte Welt ==== | ==== Verkehrte Welt ==== | ||
- | Völlig unverständlich, | + | Völlig unverständlich, |
- | {{software: | + | {{software: |
Wenn das komplette Bild am Stück berechnet werden kann und nicht wieder ausgelesen werden muß, kann man davon absehen, überhaupt ein Abbild der Grafik im Arbeitsspeicher zu erzeugen und stattdessen die Bilddaten direkt Byte für Byte dem LCD-Controller übergeben. Wenn die Bilddaten noch nicht komplett im Speicher vorbereitet wurden, kann zudem die ohnehin nötige Wartezeit (ca. 25 Taktzyklen beim Standard-Pofo, | Wenn das komplette Bild am Stück berechnet werden kann und nicht wieder ausgelesen werden muß, kann man davon absehen, überhaupt ein Abbild der Grafik im Arbeitsspeicher zu erzeugen und stattdessen die Bilddaten direkt Byte für Byte dem LCD-Controller übergeben. Wenn die Bilddaten noch nicht komplett im Speicher vorbereitet wurden, kann zudem die ohnehin nötige Wartezeit (ca. 25 Taktzyklen beim Standard-Pofo, | ||
Zeile 628: | Zeile 668: | ||
Die Kommunikation mit dem bereits mehrfach angesprochenen LCD-Controller des Portfolio erfolgt über nur zwei Portadressen: | Die Kommunikation mit dem bereits mehrfach angesprochenen LCD-Controller des Portfolio erfolgt über nur zwei Portadressen: | ||
- | | + | ^ Adresse (hex) ^ Funktion |
- | 8011h = Befehlsregister | + | | 8010 |
+ | | 8011 | ||
Ein Kommando wird übergeben, indem zuerst ein gültiger Kommandocode in das Befehlsregister und anschließend das zugehörige Argument ins Datenregister geschrieben wird. Für unsere Zwecke sind folgende Kommandos des HD61830 von Interesse: | Ein Kommando wird übergeben, indem zuerst ein gültiger Kommandocode in das Befehlsregister und anschließend das zugehörige Argument ins Datenregister geschrieben wird. Für unsere Zwecke sind folgende Kommandos des HD61830 von Interesse: | ||
- | 8 = Bildspeicher-Startadresse Low festlegen | + | ^ Kommando ^ Funktion |
- | | + | | 8 | Bildspeicher-Startadresse Low festlegen |
- | 10 = Cursorposition Low festlegen | + | | 9 | Bildspeicher-Startadresse High festlegen |
- | 11 = Cursorposition High festlegen | + | | |
- | 12 = Byte(s) zum LCD übertragen | + | | |
- | 14 = Bit setzen | + | | |
- | 15 = Bit löschen | + | | |
+ | | | ||
Die weiteren Erläuterungen und Programmbeispiele setzen voraus, daß der LCD-Controller wie beschrieben in den Grafikmodus versetzt wurde. | Die weiteren Erläuterungen und Programmbeispiele setzen voraus, daß der LCD-Controller wie beschrieben in den Grafikmodus versetzt wurde. | ||
Zeile 734: | Zeile 776: | ||
So viel zum Thema Grafik auf dem Portfolio. Weitere Informationen rund um den LCD-Controller finden sich in [3], [4] und [5]. Ganz im Sinne von Multimedia geht es im nächsten (bislang nicht erschienenen) Teil weiter mit Wissenswertem über die Tonerzeugung beim Portfolio. | So viel zum Thema Grafik auf dem Portfolio. Weitere Informationen rund um den LCD-Controller finden sich in [3], [4] und [5]. Ganz im Sinne von Multimedia geht es im nächsten (bislang nicht erschienenen) Teil weiter mit Wissenswertem über die Tonerzeugung beim Portfolio. | ||
- | Referenzen: | + | |
+ | ---- | ||
+ | |||
+ | |||
+ | **Autor:** Klaus Peichl, http:// | ||
+ | |||
+ | **Referenzen** | ||
[1] Prozedur " | [1] Prozedur " |
software/diy/assembler/kkurs.1135204011.txt.gz · Zuletzt geändert: 16/02/2024 17:02 (Externe Bearbeitung)