Maschinensprache i8086/ Filter/ 09-SP-V2

Aus Wikibooks

Übersicht[Bearbeiten]

Das nachfolgende Programm kann auf folgende Weise verwendet werden:

  1. Das Programm erwartet die Dateneingabe von Tastatur und gibt sie auf den Bildschirm aus. Es ist daher nur eine Verwendung als Filter sinnvoll. Das kann mit einem der folgenden Befehle erreicht werden:
  • In der Testphase erfolgt Ausgabe auf Bildschirm:
       type quelle.txt | 09-sp
       09-sp <quelle.txt
  • Im praktischen Einsatz gibt es ebenfalls zwei gleichwertige Varianten:
       type quelle.txt | 09-sp >ziel.txt
       09-sp <quelle.txt >ziel.txt

Der interne Programmablauf ist folgender:

  1. Die Standardeingabe wird in den Speicherbereich ab 1000 eingelesen.
  2. Die eingelesenen Daten werden in den Speicherbereich der Zieldatei (ab 8000) umkopiert, wobei alle vorgefundenen Tabulatoren (ASCII-Zeichen = 09) in Leerzeichen (ASCII-Code=20) umgewandelt werden.
  3. Der umgewandelte Text wird an die Standardausgabe geschrieben.

Quelldatei einlesen[Bearbeiten]

Um diesen Abschnitt zu verstehen, sollten Sie vorher Arbeit mit Dateien (Handle) gelesen haben. Das Einlesen erfolgt von Handle = 0 (Standardeingabe).

Datei durchsuchen und von 1000 nach 8000 kopieren[Bearbeiten]

In diesem Programmabschnitt wird der ab Adresse 1000 eingelesene Text Byte für Byte analysiert und in den Speicherbereich ab 8000 umkopiert, wobei Tabulatoren sonderbehandelt werden. Im wesentlichen sind es dieselben Befehle wie im Kapitel 09-SP-V1.

Datei schreiben[Bearbeiten]

Handle = 1 wird für die Standardausgabe verwendet.

Programm erzeugen und ausprobieren[Bearbeiten]

IP Code
0100 90
0101 90
0102 90
0103 90
0104 90
0105 B80000
0108 89C3
010A BA0010
010D B90070
0110 B43F
0112 CD21
0114 7305
0116 B8024C
0119 CD21
011B 3D0000
011E 7445
0120 89C1
0122 BE0010
0125 BF0080
0128 AC
0129 49
012A 3C09
012C 7502
012E B020
0130 AA
0131 E31D
0133 EBF3
0135 90
0136 90
0137 90
0138 90
0139 90
013A 90
013B 90
013C 90
013D 90
013E 90
013F 90
0140 90
0141 90
0142 90
0143 90
0144 90
0145 90
0146 90
0147 90
0148 90
0149 90
014A 90
014B 90
014C 90
014D 90
014E 90
014F 90
0150 89F9
0152 BB0100
0155 B440
0157 BA0080
015A 29D1
015C CD21
015E 7305
0160 B8024C
0163 CD21
0165 B80000
0168 CD21
Befehl
NOP
NOP
NOP
NOP
NOP
MOV AX,0000
MOV BX,AX
MOV DX,1000
MOV CX,7000
MOV AH,3F
INT 21
JNB 011B
MOV AX,4C02
INT 21
CMP AX,0
jz 0165
MOV CX,AX
MOV SI,1000
MOV DI,8000
LODSB 
DEC CX
CMP AL,09
JNZ 0130
MOV AL,20
STOSB
JCXZ 0150
JMP 0128
NOP
NOP
NOP
NOP
NOP
NOP
NOP
NOP
NOP
NOP
NOP
NOP
NOP
NOP
NOP
NOP
NOP
NOP
NOP
NOP
NOP
NOP
NOP
NOP
NOP
NOP
NOP
MOV CX,DI
MOV BX,0001
MOV AH,40
MOV DX,8000
SUB CX,DX
INT 21
JNB 0165
MOV AX,4C02
INT 21
MOV AX,0000
INT 21
Manuell hinzugefügter Kommentar
; Einige NOP für Testzwecke
;
;
;
;
; Handle der Standardeingabe = 0
; AX = BX = Handle der Quelldatei
; AA Bereich zum Einlesen
; 7000 Byte von 1000 bis vor 8000)
; DOS-Funktion "Datei lesen"
;
; wenn CY dann Fehler
; Dateifehler beim Einlesen
; Abbruch mit ERRORLEVEL = 2
; gelesene Bytezahl = 0?
; wenn ja, reguläres Programmende
; Bytezahl der eingelesenen Datei
; AA Quelle
; AA Ziel
; Byte lesen
;
; Vergleich mit TAB
; Sprung wenn kein TAB
; durch SP ersetzen
; Speichern
; Textende erreicht wenn CX=0
; nächstes Zeichen untersuchen
; Dieser und die folgenden
; NOP-Befehle sind Lückenfüller.
;
;
;
;
;
;
;
;
;
;
;
;
;
;
;
;
;
;
;
;
;
;
;
;
;
; EA des Ziels
; Handle der Standardausgabe
; Funktionscode für Datei schreiben
; AA Ziel
; Bytezahl = EA - AA
; Datei schreiben
; Sprung wenn Schreiben fehlerfrei
; Fehler beim Schreiben
; Abbruch mit ERRORLEVEL 2
;
; reguläres Programmende


  • Tippen Sie "debug" ein und drücken Sie Enter
  • Tippen Sie jetzt den Befehl "a 100" ein und Enter. Der Debugger erwartet jetzt, dass Sie die Befehle eintippen (die blaue Spalte). Mit einem Trick können Sie sich die mühsame, fehlerträchtige Tipperei sparen.
    • Markieren Sie in der Tabelle den gesamten blauen Text, nicht mehr und nicht weniger.
    • Wechseln Sie in das DOS-Fenster, wo der Debugger auf die Befehlseingabe wartet. Der Cursor blinkt hinter dem Minuszeichen-Prompt.
    • Klicken Sie mit der rechten Taste in die blaue Titelleiste (in der Eingabeaufforderung - debug steht).
    • Rollen Sie im aufklappenden Menü auf „Bearbeiten“ und klicken Sie auf „Einfügen“. Fertig ist die Eingabe!
  • Geben Sie den Befehl "u 100" zur Kontrolle ein (aber eigentlich ist die Kontrolle überflüssig).
  • Speichern vor dem Testen nicht vergessen! Das geht mit den folgenden drei Befehlen
-n 09-sp.com
-r cx
: 6a
-w

Probieren Sie das Programm mit dem folgenden Befehl aus

09-sp <quelle.txt 

Der umgewandelte Text erscheint auf dem Bildschirm. Mit

09-sp <quelle.txt >ziel.txt

wird der umgewandelte Text in die Datei ziel.txt geschrieben.

Ein Programmtest mit schrittweiser Abarbeitung ist unmöglich[Bearbeiten]

Ein Test mit schrittweiser Abarbeitung ist leider völlig unmöglich. Wieso?

Wenn es möglich wäre, müsste der Befehl zum Testen des Filters so aussehen:

debug 09-sp.com <quelle.txt 

Das Problem: Das Programm DEBUG nimmt die Inputdatei entgegen, als ob es sich um Quelltext handeln würde. Die Datei gelangt nicht bis zu dem zu testenden Programm. DEBUG erwartet allerdings Befehle und nicht irgendeinen Text. Im Ergebnis produziert DEBUG eine gewaltige Menge an Fehlermeldungen und hängt sich zum Schluss auf (außer Ihr Text endet mit "Neue Zeile, Buchstabe Q, Neue Zeile").

Wenn Ihr Programm die Standardeingabe einliest, sind also schrittweise Tests nicht möglich. Es bleibt Ihnen also nur eins übrig: Schreiben Sie auf Anhieb fehlerfreie Programme! :-) Wenn trotz dieses löblichen Vorsatzes in Ihrem Programm ein Fehler sein sollte, können Sie ihn nur durch Analyse der Bildschirmausgabe bzw. der Datei „ziel.txt“ und scharfes Nachdenken finden, vorausgesetzt, es wird eine Datei „ziel.txt“ erzeugt, die man analysieren könnte.

Die hier blau markierte Befehlsfolge ist getestet, Sie können diese problemlos zur Erstellung eines Filterprogrammes benutzen.

Programmtest mit schrittweiser Abarbeitung - wie es trotzdem geht[Bearbeiten]

Halten Sie es prinzipiell für möglich, dass Ihnen beim Programmieren ein Fehler unterlaufen könnte? Falls Sie innerlich bereit sind, das zuzugeben, gibt es eine Möglichkeit. Sie müssen allerdings die Voraussetzungen für die später (möglicherweise) notwendige Fehlersuche schaffen, noch bevor Sie den Code des Programms beginnen einzutippen.

Die nachfolgend beschriebene Methode geht von der Voraussetzung aus, dass das Einlesen der Standardeingabe (Befehle von 0105 bis 011B) so einfach ist, dass es nicht getestet werden muss.

  • Wir nehmen an, dass Ihr Mustertext "quelle.txt" nicht länger als 200 Byte (dezimal 512 Byte) ist bzw. nicht mehr davon gebraucht wird, um das Programm schrittweise zu testen.
  • Tippen Sie den Befehl "debug quelle.txt" ein. Mit dem Befehl "d 100" können Sie sich überzeugen, dass Ihr Quelltext eingelesen wurde und ab Adresse 100 beginnt.
  • Verschieben Sie den Text in den Speicherbereich ab 1000, wohin die Standardeingabe eingelesen werden würde. Verwenden Sie den Befehl "m 100 300 1000". Überzeugen Sie sich mit "d 1000", dass Ihr Quelltext nun ab Adresse 1000 steht.
  • Den Bereich, wohin anschließend der Programmcode eingegeben werden soll, können Sie mit "NOP"-Befehlen füllen, damit es hübsch und übersichtlich aussieht. Verwenden Sie "f 100 fff 90".
  • Beginnen Sie jetzt erst damit, die Befehlsfolgen einzutippen.
  • Abweichend vom Programmlisting ersetzen Sie die fünf "NOP" ab Adresse 100 zeitweilig mit folgenden Befehlen:
mov ax,0200
jmp 0120
  • Geben Sie dem Programm einen Namen (z.B. "09sptest.com").
  • Schreiben Sie ins CX-Register die Programmlänge. Diese beträgt nicht 6A, sondern 300, weil der Mustertext zusammen mit dem Programm gespeichert werden muss. Mit "w" können Sie die Datei schreiben.
Sie halten das für Speicherplatzverschwendung? Ist es aber nicht. Falls Ihre Festplattenpartition größer als zwei Gigabyte ist, beträgt die Clustergröße Ihrer Festplatte 4k oder mehr. Das bedeutet: Ob eine Dateien nur 1 Byte lang ist oder 768 Byte (unser Programm) oder 4095 Byte, belegt sie gleich viel Platz auf der Festplatte, nämlich genau eine Zuordnungseinheit.

Om Ihr Programm nun schrittweise zu testen, tippen Sie ein

debug 09sptest.com
-g 120

Damit überspringen Sie das Einlesen der Quelldatei. Im AX-Register steht die Dateilänge. Testen Sie nun das Programm schrittweise. Wenn Sie die Programmtests beendet haben, müssen Sie nur an den Anfang des Programms fünf "NOP"-Befehle schreiben und es mit der echten Länge von 6A und unter dem endgültigen Namen speichern.

Ein Tipp: Falls Sie mal für einen längeren Text die ASCII-Kodes ermitteln müssen und keine Lust haben, das mit der ASCII-Tabelle von Hand zu tun, können Sie dieses Verfahren ebenfalls benutzen.