Wie wird ein 2-pass-assembler unterscheidet sich von einer one-pass-assembler in die Lösung der Zukunft-Symbole?
Dies sind 2 Fragen, die ich nicht verstehe:
-
Wie funktioniert das One-Pass-Assembler lösen, die Zukunft symbol problem?
-
Wie ist Zwei-Pass-Assembler unterscheidet sich von dem one-pass-assembler in dieser Hinsicht?
Tut es beheben es im ersten Durchgang oder zweiten Durchgang? Wenn Sie es tut in den zweiten Durchgang,wo geht es eigentlich unterscheiden sich von der one-pass-assembler? Wenn es tut, in der zweiten-pass, warum nicht tun Sie es im ersten Durchgang?
Du musst angemeldet sein, um einen Kommentar abzugeben.
Lesen Sie diese PDF. Es erklärt Schritt für Schritt, wie single-und multi-pass-Assembler arbeiten. Es erklärt auch die vor-und Nachteile der beiden und die Unterschiede zwischen den beiden.
Was ist ein single-pass-assembler?
Es ist eine Art von Load-and-go - Art von assembler, die in der Regel generiert den Objektcode direkt im Speicher für die sofortige Ausführung! Es analysiert durch Ihren source-code nur einmal und fertig. Vroom...
Cool, wenn es nicht diese Magie, warum brauchen wir multi-pass-Assembler überhaupt?
Vorwärts-Referenzen! dh, während der one-pass assembler ist trodding entlang der source-code, es trifft auf einige fremden in form von undefinierten Daten-Symbole und undefiniert Etiketten(Sprung-Adressen). Ihre assembler fragt diese fremden, wer sind Sie? Die fremden sagen, " erzählen Wir Euch später!" (Forward reference) Dein assembler wird wütend und sagt, dass Sie völlig zu beseitigen, diese fremden. Aber diese fremden sind Ihre Freunde und Sie nicht beseitigen Sie völlig. , So dass Sie einen Kompromiß einzugehen befassen sich mit der assembler -. Sie Versprechen, definieren Sie alle Variablen vor der Verwendung. Der assembler konnte sich nicht auf diese Kompromisse, weil es nicht selbst behalten temp-Speicher für die undefinierten Daten-Symbole, da Sie nicht wissen, Ihre Größe. Daten können in unterschiedlichen Größen
Wenn Ihr etwas wie
Ihrerseits Ihre assembler stimmt Kompromiss auf Undefinierte Sprungmarken. Als Sprungmarken sind nichts anderes als Adressen und Adresse, können Größen bekannt sein apriori so, dass assembler vorbehalten kann, bestimmte Platz für die undefined symbol.
Wenn Ihr wie diese
Assembler übersetzt
jump AHEAD
als0x45 **0x00 0x00**
.0x45
ist der opcode vonjump
und 4 bytes reserviert fürAHEAD
AdresseOK, jetzt sagen Sie mir, wie genau ein pass assembler funktioniert
Einfach, während auf Ihrem Weg, wenn der assembler trifft auf ein nicht definiertes label wurde, legt er es in eine symbol-Tabelle zusammen mit der Adresse, wo das undefined symbol den Wert hat, platziert werden, wenn das symbol gefunden wird, in Zukunft. Es macht das gleiche für alle undefined labels und wie und Wann sieht es die Definitionen dieser undefinierten Symbole, es fügt den Wert der beiden in der Tabelle ( und somit die das label definiert ) und den Speicherort, wo Sie reserviert hatten, temp-Lagerung früher.
Nun am Ende der Analyse, wenn es noch mehr Arme Seelen noch im undefinierten Zustand, der assembler schreit foul und Fehler aus 🙁 Wenn es nicht irgendwelche undefinierten Bezeichnungen, dann Los gehts!
Eine Sekunde vergaß ich, warum müssen wir ein 2-oder multi-pass-assembler? Und wie funktionieren Sie?
Erläutert, one-pass assembler nicht beheben können vorwärtsreferenzen der Daten-Symbole. Es müssen alle Daten Symbole definiert werden, bevor Sie verwendet werden. Ein zwei-pass-assembler löst dieses dilemma, indem widmet ein pass, ausschließlich lösen Sie alle (Daten/label) vorwärts-Referenzen und generieren von Objekt-code ohne Probleme in den nächsten Durchgang.
Wenn ein Daten-symbol von einem anderen abhängt und das andere hängt noch ein anderer, der assembler gelöst rekursiv. Wenn ich versuche zu erklären, auch, dass in diesem Beitrag, der Beitrag zu groß geworden. Lesen Sie diese ppt für mehr details
Hmm.. Interessant. Funktioniert die zwei-pass-assembler noch weitere Vorteile?
Ja. Er kann erkennen, neudefinitionen und Dinge wie, dass.
PS: ich kann nicht 100% richtig hier. Ich würde gerne Anregungen zu hören, so dass es ein besseres post.
Einer one-pass-assembler-code generiert und für jede nicht definierte Symbole, hinterlässt einen slot gefüllt wird, und speichert es in einer Tabelle oder einer anderen Datenstruktur. Dann, wo das symbol definiert ist, füllt es in seinem Wert am rechten Ort oder die Orte, über die Informationen aus der Tabelle.
Den Grund für die Verwendung eines zwei-pass-assembler traditionell wurde, dass das Ziel-Programm nicht in den Speicher passt, lassen Sie allein die Quelle. Die gigantische source-Programm ist zu Lesen, Zeile für Zeile, von der Lochstreifen-Leser, und die Tabelle des labels bleibt im internen Speicher.
(Ich habe es tatsächlich getan, auf ISIS, die ersten Entwicklungssystem von Intel, mit einem 8080.)
Das zweite mal, um die ursprüngliche Band wieder Lesen, von Anfang an, aber der Wert aller Etiketten bekannt ist, und da jede Zeile gelesen wird, das Ziel-Programm ist gelocht und auf Band. Auf einem Speicher verhungert 16-bit-Intel-8086-Systems war dies noch eine nützliche Technik zu haben ein stark dokumentierte source-Datei, kann viel größer sein als 64 Kbyte, mit Festplatte oder Diskette ersetzt Papier-Klebeband.
Heutzutage gibt es keine Notwendigkeit zu tun, zwei Pässe, aber diese Architektur ist immer noch in Gebrauch. Es ist ein bisschen einfacher, auf Kosten der I/O.
Einer Art und Weise zu denken über Assembler ist vorstellbar, dass Sie berechnen den Wert einer Reihe von Ausdrücken zugewiesen zunehmenden Speicherplätze. Die Ausdrücke, die konventionell aus dem Wert des symbols, einige arithmetische getan, auf Symbole, Konstanten und spezielle Variablen wie die "aktuelle Lage-Zähler" (oft geschrieben mit einem lustigen Namen wie "$"), oder wirklich eigenartige Ausdrücke, deren syntax ist, dass der Maschinen-Anweisungen.
Beachten Sie, dass ein Ausdruck kann produzieren ein Wert, der füllt mehrere sequentielle Speicherplätze; computeranweisungen, neigen dazu, dies zu tun, aber es ist nützlich um Ausdrücke für string-Literale, multiprecision-zahlen, initialisiert, structs, etc. Dies betrifft nur die Buchhaltung details, aber nicht zu ändern, was Assembler zu tun in der Zusammenfassung.
Zur Berechnung der endgültige Wert jedes Ausdrucks, der assembler muss zu schätzen wissen, dass alle Symbole, die beteiligt sein könnten. Es entdeckt, symbol Werte in nur ein paar Möglichkeiten. Erstens, die symbol-Wert kann definiert werden als das Ergebnis eines Ausdrucks. Zweitens, ist das symbol Wert kann zugewiesen werden, den Wert der aktuellen Position, counter; in der Regel Monteure dies tun, wenn ein symbol ist geschrieben in der "label" - position. Auf eine solche Entdeckung, die assembler-Aufzeichnungen den Namen des symbols und seinen Wert in der Symboltabelle zu benutzen, in der Auswertung von Ausdrücken.
Ein zentrales problem einer assembler-Gesichter ist die Herstellung der Wert eines Ausdrucks, weil Sie noch keine aufgetreten, alle Definitionen der Symbole. Die Annahme ist, dass, wenn ein symbol nicht definiert ist, in einer bestimmten Zeile wird festgelegt, in einigen späteren Zeile, die der assembler wird schließlich Prozess.
Einen zwei-pass-assembler versucht zu berechnen, der Wert jedes Ausdrucks, wie es trifft es, in zwei Durchgängen, genannt "erste" und "zweite" geht. Während des ersten Durchlaufs, wenn es Undefinierte Symbole (vermutet vorwärts-Referenzen) in den Ausdruck, der assembler einfach ersetzt einen dummy-Wert (Häufig null); in jedem Fall berechnet einen Wert für den Ausdruck. Wenn ein Maschinenbefehl oder Konstante Daten verarbeitet werden, die Ergebnisse werden ignoriert, aber die Größe wird verwendet, um vorab die Lage Zähler zum aktivieren der label-Wert-Zuordnung. Wenn ein label gefunden wird, wird der Wert auf die aktuelle Lage Zähler. Wenn ein symbol-Zuordnung "EIN EQU" festgestellt wird, wird der symbol-Wert das Ergebnis des Ausdrucks; wenn der Ausdruck enthielt einen undefined symbol der assembler wird emittieren ein Fehler. Wenn eine origin-Anweisung gefunden wird "ORG ", er wird behandelt, als wenn einer schrieb "$ EQU ". Am Ende des ersten Durchlaufs, alle Etiketten wurden Werte zugewiesen; alle Symbole, die nicht Werte sind gekennzeichnet als "undefined" in die Symboltabelle ein. Der zweite Durchgang wiederholt die Auswertung eines Ausdrucks der ersten, aber nicht (re -) definieren Sie beliebige Symbole; da alle Symbole sind (voraussichtlich) definiert, der Ausdruck Werte korrekt sind und emittiert, um den Ausgabe-stream. Alle undefinierten Symbole in einem Ausdruck die Ursache für ein "undefined symbol" Beschwerde.
Ein-pass-assembler versucht zu berechnen, der Wert jedes Ausdrucks, wie es auf dem Ausdruck. Wenn der Ausdruck enthält nur Symbole, die assembler können es bewerten und produzieren, der den endgültigen Wert, und schreiben, dass Informationen an die Ausgabe-stream. (Eine andere Antwort, die hier vorgeschlagen, dass einige one-pass-Assembler schreiben Sie Ihre Antwort zum Speicher. Das ist nur ein spezieller Fall). Wenn der Ausdruck enthält ein Undefiniertes symbol assembler speichert ein paar (Standort,Ausdruck) aufbereitet werden später, wenn das symbol wird definiert, oder am Ende der Versammlung. Einige Ausdrücke, wie diejenigen, die die location counter nicht haben kann undefinierten Symbole; der Monteur wird sich beschweren, in diesem Fall.
So der schwierige Teil ist die Speicherung der ungelösten Ausdruck, und die Entscheidung, Wann um neu zu bewerten, es. Eine Möglichkeit zum speichern der Ausdruck ist zu einfach, halten Sie den text, ein anderer ist es, zu bauen, was beläuft sich auf ein (reverse -) polnische Schreibweise für den Ausdruck. Um zu bestimmen, wenn der Ausdruck muss neu bewertet werden, zu assoziieren es mit der undefinierten Symbole, die es enthält; dann, wenn ein symbol wird definiert, die entsprechenden ungelöste Ausdrücke werden neu bewertet, mit abgeschlossener emittiert werden, und ungelöste diejenigen, die Links wieder aufbereitet. Alternativ kann der assembler könnte speichern Sie einfach alle Ausdrücke, bis es trifft auf das Ende der Eingabe; an diesem Punkt werden alle Symbole definiert werden sollte, und so sollte es in der Lage sein, um festzustellen, die endgültigen Werte für jeden Ausdruck. Man wählt zwischen diesen beiden Techniken, basierend auf wie viel Speicher man sich leisten kann, zu speichern, weiter Referenz-Ausdrücke.
In einem früheren Jahrhundert, baute ich eine one-pass-assembler, die lief auf einem 8k-byte computer, der die polnische Repräsentation von Ausdrücken. Wie Symbole definiert wurden, ist der polnische Ausdruck, der ausgewertet wurde und alle Teilausdrücke, die waren berechnet wurden, berechnet wird, ist die Vereinfachung der entstehenden polnischen entweder auf einen endgültigen Wert oder einen kleineren polnischen Ausdruck, die nur die Operatoren, die auf undefinierten Symbole. Symbol-Tabelle Einträge für Undefinierte Werte hatte eine verkettete Liste von allen polnischen Ausdruck slots entsprechend undefinierten Symbole; als symbol-Definitionen, die aufgetreten sind, alle Elemente der verketteten Liste wurden aktualisiert und polnische Ausdrücke wurden re-evaluiert, der aufgetreten ist. Das hält den polnischen Ausdruck Größen so klein wie möglich entledigt und Sie in dem moment alle Ihre Symbole sind definiert. Dieser assembler verarbeitet hunderttausend Linie Programme, die einfach gut in der kleinen Maschine. Der Grund für eine one-pass-assembler in eine so kleine Maschine ist der source-code kam von Papier-Klebeband (Teletype, für diejenigen von Euch alt genug, sich daran zu erinnern) und Lesen, das Papier, Band noch einmal ist ziemlich schmerzhaft und langsam; ein zweites mal war nicht eine gute Idee, so ein zwei-pass-assembler war nicht eine geeignete Wahl.
Einer meiner Mitstreiter sehr viel später gebaut, ein Interessantes zwei-pass-assembler. Anstatt Verarbeitung text zweimal, er tokenisiert den text (Speicherung im Hauptspeicher) auf den ersten Durchgang, als auch als Sammel-symbol-Werte. An zwei verarbeitet die Token-text.
Dies war eine sehr schnelle assembler für zwei Pässe. Er hatte viel mehr Speicher zur Verfügung steht.
Zukunft Symbol Probleam Bedeutet Das Symbol Zu Verwenden Ist, Bevor Es Ist Zu Definieren.
Es Ist Möglich, Weil In Assembly-Sprache-Programm, Programmierer Können Festlegen, Symbol Anywere Also, Wenn Symbol Ist zu Verwenden, Bevor Es zu Definieren, Es heißt "forward reference"
Also In Einer Zeit Konvertieren Es In die Maschine(Binär), Assembler Holen Opcode-Reg-X2-B2, Aber Es Diden nicht Bekommen D2(Verschiebung) Eintrag in der Symboltabelle, So Ist Es Nicht Möglich, eine Umwandlung In Maschinensprache(Binär) Und Es heißt "Vorwärts-Referenz-Problem".
Zur Lösung Dieses 2-Pass-Assembler Definieren.
**Im Ersten Durchgang(First Scan), Die Es Machen, Die Einträge Der Symbole(Labels) In Der Symbol-Tabelle.
**Und Im Zweiten Pass(Zweite Zeit-Scan), Assembler Umwandeln In Maschinensprache(Binär). Es ist Ganz Einfach 🙂