Re-Assembler REASS zu ERNA1 |
(Re- oder Dis-Assembler ist gebräuchlich)
Es kann schon vorkommen, dass nur noch das Maschinenprogramm vorhanden ist, man aber gern wieder ein Assemblerprogramm hätte! Solche Forderungen sind realisierbar.
Es gibt jedoch Probleme, die nur der Mensch lösen kann. Der
Re-Assembler beginnt an der ihm angewiesenen Adresse und
interpretiert den Wert, der dort steht. Da die
Zahlen in unserem Fall nur Werte von 0 bis 15 annehmen können,
gibt es immer eine Befehlsinterpretation.
Werte auf Speicherplätzen,
z.B. mit kon
vereinbart, werden als Befehle erkannt. Die Aufgabe des Menschen ist es,
aus dem Zusammenhang zu entscheiden, was Zahlenwerte und was Befehle sein
könnten. Das ist
bei jedem Re-Assembler ein Problem und keine Eigenart unseres Systems.
Der Unterschied ist nur, dass es bei 16 Bit Systemen sehr
schwierig ist, diese Entscheidung zu treffen.
Unser System hat nur 16 Befehle, die man leicht übersehen
kann.
Wir nehmen folgende Speicherbelegung als Beispiel:
0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | A | B | C | D | E | F | |
0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 |
1 | 4 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 |
2 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 |
3 | 1 | 3 | 4 | 0 | 1 | E | 0 | 4 | C | 0 | 3 | 0 | 0 | 0 | 0 | 0 |
4 | C | 2 | 3 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 |
5 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 |
6 | A | 0 | 7 | C | 0 | 3 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 |
7 | B | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 |
8 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 |
9 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 |
A | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 |
B | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 |
C | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 |
D | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 |
E | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 |
F | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 6 |
Beginnt man vom Speicher-Anfang, so gibt es bei <10>
den ersten Eintrag. Eine 4 bedeutet, dass eine
Subtraktion durchgeführt werden soll. Das ist ein 3-Wort-Befehl, auf den
folgenden Speicherplätzen steht die Adresse des Operanden,
die wäre <00>. Die weitere Folge sieht
nicht so aus, als wären es sinnvolle Befehle, wir lassen diesen Teil zunächst weg.
Die nächste Folge von Befehlen scheint bei <30> zu
beginnen und endet bei <3A>. Auf <30> steht eine 1, das könnte
wie folgt interpretiert werden:
Der Re-Assembler kann das in gleicher Weise, er braucht aber
zum Arbeiten genau wie wir oben immer eine Anfangs- und Endadresse,
also den Bereich der rückübersetzt werden soll.
Schaut man die Zeile ab <30> an, so scheint sie bei
<3A> zu Ende zu sein. mit diesen Angaben lassen wir den Re-Assembler
arbeiten. Wir erhalten folgendes Ergebnis:
ORG | 30 | ||
;--------------------------------- | |||
m2: | LDK | 3 | ;30 1 3 |
SUB | 10 | ;32 4 0 1 | |
SPN | m1 | ;35 E 9 4 | |
SP | m2 | ;38 C 0 3 |
Aus dem Speicherbelegungsplan und an Befehl 3 ist zu sehen, dass ab Adresse <40> eine Interpretation vorgenommen werden muss. Endadresse ist <42>:
ORG | 40 | ||
;--------------------------------- | |||
SP | m1 | ;40 C 2 3 |
Der Speicher zeigt jedoch weitere Einträge, wir re-assemblieren sie einfach:
ORG | 60 | ||
;--------------------------------- | |||
SUP | m1 | ;60 A 0 7 | |
SP | m2 | ;63 C 0 3 |
Ab Adresse <70> steht nur ein Rücksprung ins Hauptprogramm:
ORG | 70 | ||
;--------------------------------- | |||
RUP | ;70 B |
Das umgeformte Programm könnte folgendes Aussehen haben:
ORG | 10 | ||
kon | 4 | ||
ORG | 70 | ||
;--- UP ------------------------------ | |||
m1: | RUP | 70 | |
ORG | 60 | ||
;--- HP ------------------------------ | |||
SUP | m1 | ;60 A 0 7 | |
SP | m2 | ;63 C 0 3 | |
ORG | 30 | ||
;------------------------------------- | |||
m2: | LDK | 3 | ;30 1 3 |
m4: | SUB | 10 | ;32 4 0 1 |
SPN | m3 | ;35 E 0 4 | |
SP | m2 | ;38 C 0 3 | |
ORG | 40 | ||
;------------------------------------- | |||
m3: | SP | m4 | ;40 C 2 3 |
ORG | FF | ||
kon | 6 |
ORG | 02 | |||
;------------------------------------- | ||||
LDA | 00 | ;02 0 0 0 | ||
LDA | 00 | ;05 0 0 0 | ||
LDA | 00 | ;08 0 0 0 | ||
LDA | 00 | ;0B 0 0 0 | ||
LDA | 40 | ;0E 0 0 4 | <-? | |
LDA | 00 | ;11 0 0 0 | ||
LDA | 00 | ;14 0 0 0 | ||
LDA | 00 | ;17 0 0 0 | ||
LDA | 00 | ;1D 0 0 0 | ||
LDA | 00 | ;20 0 0 0 | ||
LDA | 00 | ;23 0 0 0 | ||
LDA | 00 | ;26 0 0 0 | ||
LDA | 00 | ;29 0 0 0 | ||
LDA | 00 | ;2C 0 0 0 | ||
LDA | 31 | ;2F 0 1 3 | <-? | |
SUB | 10 | ;32 4 0 1 | <-0k | |
SPN | m1 | ;35 E 0 4 | <-0k | |
SP | m2 | ;38 C 0 3 | <-0k | |
LDA | 00 | ;3B 0 0 0 | ||
LDA | C0 | ;3E 0 0 C | <-? | |
SPA | 03 | ;41 2 3 0 | <-? | |
LDA | 00 | ;44 0 0 0 | ||
LDA | 00 | ;47 0 0 0 | ||
LDA | 00 | ;4A 0 0 0 | ||
LDA | 00 | ;4D 0 0 0 | ||
LDA | 00 | ;50 0 0 0 | ||
LDA | 00 | ;53 0 0 0 | ||
LDA | 00 | ;56 0 0 0 | ||
LDA | 00 | ;59 0 0 0 | ||
LDA | 00 | ;5C 0 0 0 | ||
LDA | 0A | ;5F 0 A 0 | <-? | |
XOR | 0C | ;62 7 C 0 | <-? | |
ADD | C0 | ;65 3 0 0 | <-? | |
LDA | 00 | ;68 0 0 0 | ||
LDA | 00 | ;6B 0 0 0 | ||
LDA | B0 | ;6E 0 0 B | <-? |
Nutzung des Re-Assemblers
--------------------------------------------
Nach dem Start des Re-Assemblers erscheint folgendes Bild:
Als erster Schritt muss mit <L>oad das Maschinenprogramm "name.SIM" geladen werden. In der linken oberen Bildschirmhälfte erscheint nun der Speicherbelegungsplan:
Als Beispiel dient wieder das oben genutzte Programm.
Nun können mit <A>dressen Anfangs und Endadresse eingegeben werden. Sollte die Eingabe falsch sein, so kann dieser Vorgang wiederholt werden.
Mit <R>eassembler wird nun
das Re-Assemblieren in den angegebenen Adressen vorgenommen. Mit
"fertig" meldet das System die Beendigung des Vorgangs.
Die Anzeige der ermittelten Befehle erfolgt in der
Arbeitsart <D>arst.-BS. Zeile für Zeile (Enter-Taste) wird
das Ergebnis in der rechten oberen Bildschirmhälfte ausgegeben. Mit
<ET> quittiert der Nutzer jede Zeile. Wenn alle Zeilen angezeigt
wurden, kommt wieder die Mitteilung
"fertig":
Jede neue Re-Assemblierung
beseitigt das vorhergehende Ergebnis, so dass beliebig oft probiert werden
kann.
Hat man eine richtige Lösung (Teil-Lösung), so wird sie mit
<S>ave abgespeichert. Wird nun das nächste
Teilstück re-assembliert (siehe oben), kann
dies ebenfalls sofort gespeichert werden. Wird der gleiche Namen gewählt,
so kann man entscheiden, ob dieser Teil das bisherige
überschreiben oder an den vorhandenen angefügt werden soll.
So entstand die oben beschriebene Gesamtdatei zum Programm.
Die Datei sollte die Erweiterung ".ASI" erhalten, sie ist nun Quelldatei.
zurück zur Start-Seite |