home *** CD-ROM | disk | FTP | other *** search
-
- ■══════════════════════════════════■
- ║ ║
- ║ R86 Reassembler Version 1.00 ║
- ║ ║
- ■══════════════════════════════════■
-
-
- Copyright (c) 1992 Stefan Bion
-
- Bruktererstraße 2
- 5000 Köln 21
- Tel. 0221/881825
- Germany
-
-
-
- Dieses Programm ist "Freeware" (nicht Public Domain!), d.h. es darf
- frei kopiert und in unmodifizierter Form weitergegeben werden. Eine
- Registrierungsgebühr ist für die private Nutzung nicht erforderlich.
- Alle Rechte vorbehalten.
-
-
-
- R86 ist ein Reassembler, der 80x86/80x87-Assembler-Quelltext aus
- ausführbaren Programmdateien vom Typ .COM produziert. Im Einzeln
- werden folgende Prozessoren unterstützt:
-
-
- - 8088/86, 80186, 80286, NEC V20, NEC V30
- - 8087, 80287, 80387, IIT-2C87
-
-
- Die Syntax des generierten Quelltextes ist kompatibel zu der des
- Shareware-Assemblers A86 von Eric Isaacson. Dabei werden die Verein-
- fachungen verschiedener Assembleranweisungen des A86 berücksichtigt,
- wie Mehrfachoperanden bei PUSH, POP, INC und DEC, oder B, W und D
- statt BYTE PTR, WORD PTR und DWORD PTR. MASM oder TASM können ohne
- Änderungen mit dem Quelltext nichts anfangen. Aber für diese Assembler
- existieren bereits Disassembler - für A86 nicht.
-
-
-
- Inhalt
- ======
-
-
- 1. Aufruf des Reassemblers ....................................... 2
- 2. Analysieren des Programmcodes ................................. 3
- 3. Aufbereiten des Assembler-Quelltextes ......................... 5
- 4. Floatingpoint-Anweisungen ..................................... 6
- 5. Sonderfälle ................................................... 7
- 6. Kapazitätsgrenzen von R86 ..................................... 9
- 7. Bug in A86 .................................................... 9
- 8. Literaturhinweise ............................................ 10
-
-
-
-
-
-
-
-
-
-
- Dokumentation zu R86 Seite 1
- 1. Aufruf des Reassemblers
- ==========================
-
-
- Die zum Betrieb des Reassemblers notwendigen Parameter und Schalter
- werden in der Kommandozeile übergeben. Erfolgt der Aufruf des
- Programms ohne Kommandozeilenparameter, dann wird ein Hilfstext in
- englischer Sprache ausgegeben.
-
-
- Der Reassembler wird folgendermaßen aufgerufen:
-
-
- R86 [-d] [-s] infile[.COM] [outfile[.ASM]]
-
-
- Dabei steht infile für den Namen der zu reassemblierenden Programm-
- datei, wobei die Erweiterung .COM voreingestellt ist und nicht
- explizit angegeben werden muß. Durch Angabe einer Erweiterung können
- Sie diesen voreingestellten Wert überschreiben. Der Parameter infile
- muß in jedem Fall immer angegeben werden. Die Programmdatei darf
- maximal 64 KByte groß sein.
-
- Der Name der zu produzierenden Quelldatei outfile ist standardmäßig
- derselbe wie der der Programmdatei, jedoch mit der Endung .ASM. Durch
- Angabe eines anderen Namens oder einer anderen Erweiterung können Sie
- auch hier die voreingestellten Werte überschrieben werden.
-
- Ebenfalls optional können Sie noch zwei Schalter mit angeben:
-
- Durch Angabe des Schalters -d wird die zu reassemblierende Programm-
- datei in einen Hex/ASCII-Editor geladen, der es Ihnen auf komfortable
- Weise ermöglicht, die Code- und Datenbereiche zu bestimmen. Dazu
- später mehr.
-
- Der Schalter -s ist dann nützlich, wenn die produzierte .ASM-Datei
- größer als 64 KByte ist. Dann nämlich kann diese von A86 nicht mehr
- in einem Stück verarbeitet werden und muß in mehrere Stücke aufgeteilt
- werden. Im Allgemeinen kann man sagen, daß die .ASM-Datei die rund
- zehnfache Größe der .COM-Datei erreicht. Durch Angabe des Schalters
- -s werden statt einer großen Quelltext-Datei mehrere kleine Dateien zu
- jeweils ca. 60 kByte erzeugt, deren Erweiterungen dann mit .001, .002,
- usw. fortlaufend durchnumeriert werden. Um die einzelnen Quelltext-
- Teile zu assemblieren, ist A86 folgendermaßen aufzurufen:
-
-
- A86 outfile.00*
-
-
- In der Regel werden Sie den generierten Quelltext jedoch erst mit
- einem Texteditor nachbearbeiten wollen (müssen). Damit sich Änderungen
- durch die Suchen/Ersetzen-Funktion des Editors auf den gesamten Text
- auswirken, sollte dieser zunächst an einem Stück abgespeichert und
- erst nachher in kleinere Häppchen aufgeteilt werden.
-
-
-
-
-
-
-
-
-
-
-
- Dokumentation zu R86 Seite 2
- 2. Analysieren des Programmcodes
- ================================
-
-
- Voraussetzung für das Generieren von sinnvollem Assembler-Quelltext
- ist die richtige Interpretation des Programmcodes. Bevor Sie ein
- Programm mit R86 reassemblieren, müssen Sie daher bestimmen, welche
- Teile der Programmdatei ausführbare Anweisungen und welche Daten
- enthalten. Ohne diese Differenzierung wurden fälschlicherweise als
- Programmcode interpretierte Daten unsinnigen Chaos-Code ergeben. Zwar
- mögen diese Anweisungen beim Assemblieren wieder in die ursprünglichen
- Bytes zurückverwandelt werden können, aber das ist in der Praxis
- meistens nicht der Fall, weil nämlich für ein und dieselbe Assembler-
- anweisung mehrere Codierungsmöglichkeiten bestehen. Das Ergebnis wären
- falsche Daten.
-
- Um R86 mitzuteilen, an welchen Adressen Datenbereiche welchen Typs
- beginnen, und welche Bereiche als ausführbare Anweisungen interpre-
- tiert werden sollen, wird eine zusätzliche Textdatei benötigt, die
- nacheinander die hexadezimalen Adressen, gefolgt vom Datentyp, ent-
- hält. Die Datei hat immer denselben Namen wie die zu disassemblierende
- Programmdatei (infile), allerdings mit der Endung .R86. Es folgt ein
- Beispiel für den Aufbau der Datei:
-
-
- 103 a ; ASCII-Daten beginnen bei Offset 103h
- 1BE w ; Word-Daten beginnen bei Offset 1BEh
- 1F0 b ; Byte-Daten beginnen bei Offset 1F0h
- 200 c ; Ausführbarer Code beginnt bei Offset 200h
-
-
- In der Datei selbst dürfen keine Kommentare enthalten sein.
-
- Die hexadezimalen Adressen in der Datei müssen aufsteigend sortiert
- sein. Außerdem dürfen maximal 2048 Bereiche definiert werden (maximal
- 2048 Zeilen), was allerdings völlig ausreicht.
-
-
- Um die einzelnen Bereiche bestimmen zu können, benötigen Sie einen
- Datei-Betrachter, der den Inhalt der Programmdatei in hexadezimaler
- Form und als ASCII-Zeichen darstellt. Wenn Sie geübt sind, dann wird
- es für Sie nicht schwer sein, festzustellen, welche Teile der Datei
- ausführbaren Programmcode enthalten und welche Daten. Textbereiche
- sind an ihrem Klartext ja noch eindeutig auszumachen, ebenso mit 0
- initialisierte Datenbereiche und Puffer.
-
- Nun wäre es ja mühsam, sich den Inhalt der Datei anzusehen und dabei
- die Adressen und den dazugehörigen Datentyp auf irgendeinen Zettel
- aufzuschreiben, um diese dann nachher mit einem Texteditor abzutippen
- und so die .R86-Datei zu erstellen. Deshalb besitzt R86 einen einge-
- bauten Hex/ASCII-Dateibetrachter mit speziellen Funktionen zum bild-
- schirmorientierten Bearbeiten der Datei. Sie aktivieren diesen Editor,
- indem Sie beim Aufruf des Reassemblers den Schalter -d, gefolgt vom
- Programmnamen, angeben.
-
- Mit den Tasten <PgUp> und <PgDn> können Sie in der Datei bildschirm-
- weise blättern (± 256 Bytes), mit <Home> und <End> gelangen Sie an den
- Anfang bzw. an das Ende der Datei. Die Datei beginnt immer bei Offset
- 100h, da dies die Startadresse bei .COM-Programmen ist. Mit den
- Cursortasten können Sie den Cursor auf eine bestimmte Byteposition
- innerhalb der Datei, an der z.B. ein Datenbereich beginnt, setzen und
- diese dann mit der Funktionstaste <F1> markieren. Anschließend setzen
- Sie den Cursor auf das letzte Byte dieses Bereiches und markieren die
- Endadresse mit Funktionstaste <F2>.
-
- Dokumentation zu R86 Seite 3
- Die Anfangs- und Endadresse des so markierten Bereiches wird in der
- untersten Zeile angezeigt. Anschließend können Sie durch Eingabe des
- Anfangsbuchstabens den Datentyp des markierten Bereiches bestimmen,
- der dann auch farblich dargestellt wird:
-
-
- a ASCII-Daten (gelb)
- b Byte-Daten (grün)
- c Ausführbarer Code (rot)
- w Word-Daten (blau)
-
-
- Falls Sie keinen Farbmonitor besitzen, können Sie sich auch an den in
- der untersten Zeile angezeigten Werten (hinter "Current area:") orien-
- tieren. Hier werden Anfangs- und Endadresse sowie der Datentyp des
- aktuellen Bereiches angezeigt, in dem sich der Cursor gerade befindet.
- Allerdings ist die farbige Anzeige wesentlich schöner, da man hier den
- jeweiligen Datentyp auf einen Blick erkennt, ohne mit dem Cursor durch
- die Gegend wandern zu müssen und dabei die Anzeige zu beobachten.
-
-
- Haben Sie alle Bereiche bestimmt, dann können Sie den Editor mit der
- <ESC>-Taste verlassen. Sie werden daraufhin gefragt, ob Sie die
- eingegebenen Daten sichern wollen. Mit 'Y' oder <CR> können Sie dies
- bestätigen oder aber mit 'N' oder <ESC> ablehnen. Die Daten werden in
- eine Datei mit der Endung .R86 geschrieben. Bei einem erneuten Aufruf
- des Reassemblers mit dem Schalter -d werden die Daten auch wieder aus
- dieser Datei gelesen, so daß Sie hier Änderungen vornehmen können.
- Die nächste Frage lautet, ob nun mit der Disassemblierung begonnen
- werden soll oder nicht.
-
- Wenn Sie beim ersten Analysieren nicht gleich alles identifizieren
- können, dann machen Sie einfach eine Probe-Disassemblierung und sehen
- sich den Quelltext in einem Texteditor an. Wenn Sie evtl. sinnlose
- Anweisungen entdecken, dann haben Sie möglicherweise noch
- Datenbereiche übersehen. Falls ein Label davorsteht, können Sie die
- Adresse und den Datentyp direkt in die Datei infile.R86 einfügen,
- ansonsten rufen Sie R86 noch einmal mit dem Schalter -d auf.
-
- In der Regel läßt sich der Quelltext dann ohne Fehler von A86
- assemblieren und funktioniert sogar, auch wenn ein byteweiser
- Vergleich Unterschiede ergibt. Letzteres ist meistens dann der Fall,
- wenn die Original-Programmdatei von MASM oder TASM erzeugt wurde, und
- nicht von A86 selbst. In Verbindung mit dem sogenannten ModRM-Byte,
- welches die Adressierungsart eines Assemblerbefehls festlegt, kann ein
- und derselbe Befehl nämlich mit unterschiedlichen Opcodes codiert
- werden. Eric Isaacson benutzt bei seinem A86 ein eigenes System, die
- Befehle zu codieren, um daran erkennen, ob ein beliebiges Programm von
- seinem Assembler übersetzt worden ist, oder nicht ("footprint").
-
- Die Größe der ursprünglichen und der neu übersetzten Programmdatei muß
- allerdings dieselbe sein, sonst brauchen Sie das Programm gar nicht
- erst zu starten. Dann nämlich sind bestimmte Bereiche des Programms
- verschoben, und durch falsche Referenzierung kommt es dann zu Fehlern.
- Bevor Sie in einem solchen Fall mit dem im Folgenden beschriebenen
- Aufbereiten des Assembler-Quelltextes weitermachen, untersuchen Sie
- den Quelltext noch einmal auf Datenbereiche, die Sie vielleicht
- übersehen haben, oder auf zweideutige Anweisungen (Kapitel "Sonder-
- fälle").
-
-
-
-
-
-
- Dokumentation zu R86 Seite 4
- 3. Aufbereiten des Assembler-Quelltextes
- ========================================
-
-
- Haben Sie alle Datenbereiche des Programms richtig bestimmt und dann
- eine .ASM-Datei erzeugt, die auch fehlerlos assembliert wird und sogar
- lauffähig ist, dann beginnt erst die eigentliche Arbeit, die Ihnen
- kein Programm abnehmen kann: Das Verstehen des Programmablaufes und
- möglichst das Einfügen von erklärenden Kommentaren. Kommentieren Sie
- jedes Unterprogramm, beginnen Sie dabei mit den am einfachsten zu
- erkennenden Teilen. Wenn Sie einmal eine Anweisung oder einen MS-DOS-
- Funktionsaufruf nicht verstehen, dann sehen Sie in entsprechender
- Literatur nach. Ersetzen Sie dann das Label jedes identifizierten
- Unterprogramms und von Variablen, deren Funktion durch die Verwendung
- im Unterprogramm offensichtlich geworden ist, mit der Suchen/Ersetzen-
- Funktion Ihres Texteditors durch aussagekräftige Namen. Diese Namen
- erscheinen dann auch an den Programmstellen, von denen aus sie
- referenziert werden und erleichtern so die Identifizierung weiterer
- Programmteile.
-
-
- Wollen Sie außerdem selbst Änderungen und Erweiterungen an dem
- Programm vornehmen, dann ist es unerläßlich, den Quelltext zuvor
- entsprechend aufzubereiten. Eine Hauptaufgabe dabei ist es, Symbole
- durch Festwerte zu ersetzen, wo dies nötig ist. Hierzu zunächst
- einige Erläuterungen:
-
-
- Beim Generieren von Assembler-Quelltext geht R86 in zwei Schritten
- vor: Beim ersten Durchgang werden alle Word-Referenzen in einer
- internen Tabelle gespeichert. Anschließend wird im zweiten Durchgang
- der Quelltext in die Ausgabedatei geschrieben und die Referenzen dabei
- durch Symbole bzw. Labels ersetzt. Als Referenzen werden alle Sprung-
- ziele (bedingte Sprünge, JMP, CALL, LOOP) und alle 16-Bit-Direkt-
- operanden (falls größer als 0FFh) angesehen. Bei den Direktoperanden
- kann R86 allerdings nicht wissen, ob der Programmierer damit einen
- festen Wert oder eine Offsetadresse innerhalb des Programms gemeint
- hat. Beispiel:
-
-
- mov ax,offset l2523h
- mov dx,offset l0653h
- int 21h
-
-
- Der geübte Assembler-Programmierer wird sofort erkennen, daß l2523h
- ein Festwert ist (DOS-Funktion 25h, Interruptvektor 23h setzen), und
- l0653h eine Referenz (Offsetadresse des Int-23h-Handlers). Beim
- nachträglichen Bearbeiten des Quelltextes mit einem Editor gilt es
- nun, alle Symbole, die eigentlich Festwerte sind, zu entfernen. Im
- obigen Beispiel würden Sie die erste Zeile also ändern in:
-
-
- mov ax,2523h
-
-
- Das Label l2523h, das irgendwo im Programm definiert ist, kann dann
- gelöscht werden. Erst dann, wenn kein Festwert mehr als vermeintliche
- Referenzadresse angegeben ist und deren Werte somit nicht mehr von der
- Adresse der Labels im Programm abhängen, dürfen Sie Ergänzungen am
- Programm vornehmen. Denn würden Sie beispielsweise hinter den obigen
- drei Quelltextzeilen einige Anweisungen einfügen, dann würden sich
- auch die Offsetadressen aller nachfolgenden Symbole verschieben.
-
-
- Dokumentation zu R86 Seite 5
- Auch Festwerte, die als Symbol angegeben sind, bekämen einen anderen
- Wert zugewiesen. Bei einer Verschiebung um 3 Bytes würde das Symbol
- l2523h z.B. den Wert 2526h repräsentieren, so daß nun nicht mehr Int
- 23h, sondern Int 26h verbogen werden würde. Aus diesem Grund ist es
- auch nicht ratsam, das Programm zu starten, wenn sich dessen Größe von
- der Größe der ursprünglichen Programmdatei unterscheidet und der von
- R86 erzeugte Quelltext noch nicht dahingehend geändert wurde.
-
- Normalerweise jedoch ist die Größe der ursprünglichen und der neu
- übersetzten Programmdatei dieselbe. Nur in Sonderfällen dürften sich
- Unterschiede ergeben - doch dazu mehr im Kapitel "Sonderfälle".
-
-
-
- 4. Floatingpoint-Anweisungen
- ============================
-
-
- Assembleranweisungen für den mathematischen Coprozessor bis hin zum
- 80387 werden von R86 ebenfalls disassembliert. Außerdem wird der IIT-
- 2C87 unterstützt (dies entspricht exakt dem Sprachumfang von A86 in
- der Version 3.22). Wenn R86 eine Coprozessor-Anweisung in der
- Programmdatei entdeckt, wird zu Beginn des Quelltextes die .287-
- Direktive ausgegeben.
-
- Beim Coprozessor 8087 mußte noch vor jede Anweisung ein FWAIT-Befehl
- geschrieben werden (ein Byte, 9Bh). Bei den neueren Prozessoren ab dem
- 80287 ist dies nicht mehr erforderlich. MASM, TASM und A86 codieren
- implizit vor jede Coprozessor-Anweisung dieses FWAIT-Byte. Bei A86
- läßt sich dies aber durch Angeben der Direktive .287 oder durch Aufruf
- mit dem Schalter +F abschalten.
-
- Wenn in der von R86 disassemblierten Programmdatei FWAIT-Anweisungen
- enthalten sind, dann werden diese immer explizit ausgegeben. Durch die
- .287-Direktive wird bewirkt, daß A86 die FWAITs bei den Floatingpoint-
- Befehlen nicht nochmal codiert. Sie können die Direktive und alle
- FWAITS, die direkt vor Coprozessor-Anweisungen stehen, auch entfernen.
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- Dokumentation zu R86 Seite 6
- 5. Sonderfälle
- ==============
-
-
- Das Rückübersetzen von Maschinencode in Assembleranweisungen kann
- manchmal eine knifflige Angelegenheit sein. Es existieren theoretisch
- einige Sonderfälle, in denen der Assembler die Anweisungen anders
- interpretiert, als sie gemeint sind, so daß sich der vom Assembler
- produzierte Code vom Original unterscheidet.
-
-
- Häufig benutzte Anweisungen des 8086-Prozessors existieren z.B. zu-
- sätzlich zur Normalform auch in einer Kurzform. Dazu gehören u.a. die
- Anweisungen "MOV Register,Direktoperand" (Opcodes B0...BF), welche
- auch mit den Opcodes C6 und C7 codiert werden können, was aber wegen
- des zusätzlichen ModRM-Bytes um 1 Byte länger und außerdem langsamer
- wäre. Für Befehle, die das Register AX bzw. AL als Operand haben,
- existiert vielfach neben der Langform auch ein extra Opcode ohne das
- ModRM-Byte zum Auswählen der Adressierungsart. Manchmal ist es pro-
- grammtechnisch jedoch erforderlich, die Langform zu verwenden. Da
- beide Formen dieselbe Schreibweise besitzen, können sie bei einem
- disassemblierten Quelltext äußerlich nicht mehr unterschieden werden.
- Um explizit die Langform eines Befehls zu codieren, müssen die Opcodes
- in Form von Bytes mit der DB-Anweisung oder mit Hilfe eines Macros
- angegeben werden. A86 und auch die anderen Assembler versuchen immer,
- eine Anweisung mit so wenigen Bytes wie möglich zu codieren.
- Langformen von Anweisungen werden von R86 kommentiert, wobei der
- tatsächlich verwendete Opcode angegeben wird. Falls die Verwendung der
- Langform für den Programmablauf wichtig ist und beibehalten werden
- muß, dann sollten Sie die entsprechenden Bytes von Opcode und Operand
- als Datenbereich definieren (DB- oder DW-Anweisung). Ansonsten können
- Sie nach der betreffenden Anweisung ein NOP einfügen, um eine
- Verschiebung der nachfolgenden referenzierten Offsetadressen zu
- vermeiden. Letzteres kann jedoch entfallen, falls Sie bei Festwerten
- als Direktoperanden die Symbole entfernt haben, so daß deren Werte
- nicht mehr von der Adresse der Labels im Programm abhängen.
-
-
- Auch effektive Adressen als Operanden einer Anweisung, bei denen das
- Displacement 0 beträgt, werden vom Assembler in die kürzere Form ohne
- Displacement übersetzt. Die Anweisung "mov al,b[bx+di+0]" wird also
- beispielsweise zu "mov al,b[bx+di]" (Ausnahme: Eine Kurzform von
- "[bp]" existiert nicht und wird daher immer als "[bp+0]" codiert.
- Falls es sich um ein 16-Bit-Displacement handelt, das jedoch kleiner
- als 100h ist und somit in 8 Bit passen würde, dann wird vom Assembler
- auch automatisch ein 8-Bit-Displacement codiert, womit sich schon
- wieder Unterschiede in der Codelänge ergeben. Die beiden zuletzt
- geschilderten Fälle sind mir jedoch in der Praxis noch nicht begegnet.
-
-
- Bei Direktoperanden gibt es noch eine Besonderheit, die beachtet
- werden muß: A86 interpretiert diese als vorzeichenbehaftete Integer-
- werte, was manchmal zu überraschenden Ergebnissen führen kann. Dazu
- ein Beispiel: Ein Programm enthält die Anweisung
-
-
- cmp bx,0FFF7h
-
-
-
-
-
-
-
-
- Dokumentation zu R86 Seite 7
- Assembliert man diese Anweisung, dann codiert A86 daraus die drei
- Bytes 83 FB F7, was jedoch wieder disassembliert die Anweisung
-
-
- cmp bx,0F7h
-
-
- ergeben würde. Diese Anweisung wiederum assembliert ergibt jedoch
- diesmal vier Bytes, und zwar 81 FB F7 00. Der Grund ist, daß A86 die
- Zahl 0FFF7h als vorzeichenbehaftete Integerzahl mit dem Wert -9 be-
- trachtet. Den Wert -9 kann man aber auch als 8-Bit-Integer darstellen
- (0F7h). Der 80x86 kennt zudem für verschiedene Anweisungen, die als
- ersten Parameter einen Word-Operanden haben, zwei unterschiedliche
- Opcodes: Opcode 81h mit einem 16-Bit-Direktoperanden als zweitem
- Parameter und Opcode 83h mit einem 8-Bit-Direktoperanden als zweitem
- Parameter. Da -9 gleich -9 ist, codiert A86 die kürzere beider
- Sequenzen. Der Ausdruck "0F7h" ist für A86 allerdings eine positive
- Zahl und wird daher in 16 Bit (1 Word) dargestellt (der *Wert* 0F7h
- wäre ja -9). Statt mit negativen Zahlen zu hantieren, gibt R86 in
- solchen Fällen einfach zwei hexadezimale Fs vor der betreffenden Zahl
- aus, was in vielen Fällen übersichtlicher ist.
-
-
- Die folgende Tabelle faßt die Interpretation von vorzeichenbehafteten
- Bytes (XX) bzw. Words (XXXX) durch A86 noch einmal zusammen:
-
-
- | Schreibweise | Interpretation | Codierung | Opcode
- ----+-----------------+-------------------+--------------+--------
- | | | |
- 1.) | 00...7F | 0...7F | 00...7F | 83
- 2.) | 80...FF | 80...FF | 0080...00FF | 81
- | | | |
- 3.) | 0000...007F | 0...7F | 00...7F | 83
- 4.) | 0080...FF7F | 80...FF7F | 0080...FF7F | 81
- 5.) | FF80...FFFF | -80...-1 | 80...FF | 83
-
-
- Im Fall 3.) in der Tabelle fügt R86 direkt hinter dem betreffenden
- Befehl den Aufruf eines Makros "patch83" ein, welches bei Auftreten
- dieses Falles am Anfang der .ASM-Datei definiert wird. Dieses Makro
- sorgt dafür, daß statt des Opcodes 83h, den der Assembler aufgrund
- seiner Interpretation des Operanden nehmen würde, der richtige Opcode
- 81h verwendet wird, wie es auch im Originalprogramm der Fall war.
- Falls es für den Programmablauf nicht wichtig ist, können Sie dieses
- Makro auch wieder entfernen.
-
- Im Fall 5.) wird der Operand als Symbol definiert sein - aufgrund
- seines hohen Wertes vermutlich irgendwo am Schluß des .ASM-Listings,
- also erst nach der Verwendung dieses Symbols. Da A86 ein 1-Pass-
- Assembler ist, kann er zum Zeitpunkt der Verwendung des Symbols noch
- nicht wissen, welcher Wert ihm zugewiesen werden wird (Vorwärts-
- referenz) und reserviert daher vorsichtshalber 1 Word für den
- Operanden. A86 codiert also 5.) mit Opcode 81h, so wie es dem
- Original-Programm entspricht. Ändern Sie das Symbol jedoch in einen
- Festwert um, dann verwendet A86 Opcode 83h. Falls dies programm-
- technisch irrelevant ist, kann Ihnen das egal sein. Ansonsten müßten
- Sie entweder den Befehl byteweise mit der DB-Anweisung codieren, oder
- Sie verwenden ein Makro, ähnlich patch83.
-
- Zum Glück sind dies aber alles äußerst seltene Fälle, die eigentlich
- nur dann auftreten, wenn der Programmierer mit fiesen Tricks
- gearbeitet hat.
-
-
- Dokumentation zu R86 Seite 8
- 6. Kapazitätsgrenzen von R86
- ============================
-
-
- Die von R86 zu reassemblierende .COM-Datei darf eine maximale Größe
- von 65280 (FF00h) Bytes haben und entspricht damit auch der Maximal-
- größe einer .COM-Datei unter DOS. Dateien vom Typ .EXE werden von R86
- nicht unterstützt, zumal auch A86 mit Multisegmentprogrammen nichts
- anfangen kann.
-
-
- R86 liest den gesamten Inhalt der .R86-Datei in den Hauptspeicher ein.
- Dort ist Platz für 2048 Einträge reserviert - in der Datei dürfen also
- maximal 2048 Adressen mit Datendefinitionen angegeben werden, was
- normalerweise mehr als ausreicht.
-
-
- Eine weitere Einschränkung betrifft die maximale Anzahl von Symbolen
- bzw. Referenzadressen. Diese liegt bei 8192 und stellt somit ungefähr
- das Doppelte von der in der Praxis benötigten Kapazität bei einer
- 64 KByte großen .COM-Datei dar. Außerdem ist dies mehr, als A86
- verkraften kann. Eine ca. 50 KByte große .COM-Datei ergab reassem-
- bliert mit dem Schalter -s beispielsweise 7½ einzelne Quelltextteile
- zu je 60 KByte. A86 brach die Übersetzung bei der letzten Datei mit
- der Fehlermeldung ~99 Symbol Table Overflow~ ab. Hier müßte man die
- Quelltextteile dann einzeln in .OBJ-Module übersetzen lassen und zu
- einer ausführbaren Datei linken.
-
-
-
- 7. Bug in A86
- =============
-
-
- Zum Schluß noch ein Hinweis auf einen Fehler von A86, der mir beim
- Entwickeln von R86 aufgefallen ist. Bei den Datentypen Byte und Word
- faßt R86 gleiche aufeinanderfolgende Werte mit dem DUP-Operator
- zusammen. Bei Word-Daten werden ebenso wie bei Direktoperanden von
- Assemblerbefehlen statt Festwerten Labels verwendet, sofern die Werte
- größer als 100h sind, da sie Offsetadressen auf andere Programmteile
- darstellen könnten. Ist der Wert größer als die Offsetadresse, an der
- dieses Word definiert ist, dann ist das entsprechende Label erst
- hinter dieser Offsetadresse definiert (Vorwärtsreferenz). Wenn nun ein
- solches Symbol hinter einem DUP-Operator steht, dann wird nur das
- erste Element dieses Feldes von A86 mit diesem Wert initialisiert und
- der Rest mit 0 aufgefüllt:
-
-
- dw 8 dup symbol ; => dw 1234h,0,0,0,0,0,0,0
- symbol equ 1234h
- dw 8 dup symbol ; => dw 1234h,1234h,1234h,1234h,
- ; 1234h,1234h,1234h,1234h
-
-
- Aus diesem Grunde verwendet R86 den DUP-Operator außer bei Bytes nur
- bei solchen Words, die kleiner als 100h sind und somit nicht durch
- Symbole dargestellt werden.
-
- Dasselbe Phänomen zeigt sich zwar auch bei Bytes, wenn ein Label
- verwendet wird, das erst nach der Verwendung definiert wird. Bei
- Byte-Daten setzt R86 allerdings keine Symbole ein.
-
-
-
-
- Dokumentation zu R86 Seite 9
- 8. Literaturhinweise
- ====================
-
-
- Die Informationen für die Entwicklung von R86 wurden aus folgenden
- Quellen bezogen:
-
-
- 1.) DOS Extra Nr. 8/1989, DMV-Verlag
- (Seite 64ff, "Die Assemblerbefehle des 8086/8088")
-
- 2.) Dokumentation zum A86/D86-Assembler/Debugger-Paket V3.22
- von Eric Isaacson (Shareware)
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- Dokumentation zu R86 Seite 10