Gibt es einen Unterschied zwischen den beiden? Gemäß Ullmans Buch konvertieren Compiler eine Sprache in eine andere (normalerweise niedrige) Sprache, und ein Assembler auch. Wie unterscheiden sich die beiden?
Gibt es einen Unterschied zwischen den beiden? Gemäß Ullmans Buch konvertieren Compiler eine Sprache in eine andere (normalerweise niedrige) Sprache, und ein Assembler auch. Wie unterscheiden sich die beiden?
Antworten:
Ein Assembler übersetzt Assembler-Code in Maschinencode. Die Übersetzung ist mechanisch und kann nur auf eine Weise erfolgen. Im Gegensatz dazu hat ein Compiler mehr Freiheit, wenn er die entsprechende Programmiersprache kompiliert - er kann zum Beispiel optimieren und selbst nicht optimierende Compiler produzieren unterschiedlichen Code. Außerdem können Compiler so geschrieben werden, dass das "Front-End" (entsprechend der Programmiersprache) und das "Back-End" (entsprechend der Computerarchitektur) getrennt werden, wohingegen bei Assemblern die beiden immer gleich sind.
Unterm Strich macht es mehr Spaß , einen Compiler zu schreiben als einen Assembler. Assemblersprachen sind in der Regel so konzipiert, dass sie für das Parsen und die Typprüfung nahezu trivial sind und eine Vielzahl tabellengesteuerter Generatoren umfassen ("der Opcode für das Hinzufügen ist 01110", "für Ladeanweisungen wird das Zieloperandenregister durch die Bits 17 bis 21 angegeben "). Normalerweise ist der interessanteste Teil eines Assemblers der Teil, der symbolische Beschriftungen in Zahlen auflöst.
Die meisten Assembler können jedoch eine kleine Menge an Arithmetik ausführen (z. B. symbolische Beschriftungen mit kleinen Konstanten addieren), und die meisten Assembler verfügen über eine Makroverarbeitungseinrichtung oder sind in diese integriert. (Auf den meisten Unix-Systemen wird die Makrofunktion tatsächlich bereitgestellt, indem der C-Pre-Prozessor über die Assembly ausgeführt wird, bevor er an den Assembler übergeben wird.)
Der MIPS-Assembler musste noch einen Schritt weiter gehen, einige interessante Entscheidungen zur Codegenerierung treffen und einige Optimierungen vornehmen. Die MIPS-Maschinensprache erfordert unterschiedliche Codesequenzen, um beispielsweise unterschiedliche Konstanten zu laden, und so musste der Assembler die Codesequenz nach dem Erstellen der Konstante auswählen . Ferner war der MIPS-Maschinencode mit Verzögerungsschlitzen behaftet , aber es lag in der Verantwortung des Assemblers, diese zu abstrahieren und dem Compiler eine "normalere" abstrakte Assemblersprache zu präsentieren. Daher muss der MIPS-Assembler eine lokale Anweisungsplanung durchführen.
Die Unterscheidung wird durch einige Arbeiten von Norman Ramsey weiter verwischt , insbesondere durch seine C - portable Assemblersprache. (Das relevante Papier ist Ramsey und Peyton Jones, "Eine einzelne Zwischensprache, die mehrere Implementierungen von Ausnahmen unterstützt", Prog. Lang. Impl. Und Dsgn. , (PLDI-21): 285–298, 2000. ) Und schließlich ist auch eine typisierte Assemblersprache von David Walker und Greg Morrisett mit einem Assembler, der die Speichersicherheit gewährleisten kann.
Hier ist die Realität etwas komplizierter. Ich würde erwarten, dass der Unterschied zwischen einem Assembler (A) und einem Compiler (C) unter anderem ist:
Wir neigen dazu, die Assemblersprache "Low Level" und die Quellsprache, die ein Compiler versteht, "High Level" zu nennen (dies ist eine grobe Vereinfachung, aber immer noch).
In der Assemblersprache können Sie beispielsweise eine Additionsoperation ausführen, indem Sie sagen:
In einer höheren Sprache könnten Sie schreiben:
Und dies kann in Abhängigkeit von einer Reihe von Umständen zu einer Anweisung oder zu Hunderten von Anweisungen führen. Eine davon ist die CPU, für die der Compiler Anweisungen erstellt.
Wie Sie sehen, ist die Assembler-Quellsprache am häufigsten: (A) Eine Zeile Quellcode gibt eine Zeile CPU-Opcodes an, und dies hängt sehr stark von der CPU ab, auf die Sie abzielen. Ein C-Compiler (High Level Language) verarbeitet all diese Details für Sie - eine Zeile Quellcode kann Null werden, ein oder mehrere CPU-Opcodes, und der Compiler verarbeitet die Details dessen, was die CPU tun kann.
Ein Compiler besteht heute oft aus mehreren verschiedenen Phasen. Sie könnten als Frontend / Backend oder als andere Dinge bezeichnet werden. Ich sehe sie normalerweise als vier Stufen:
Gute Compiler zu schreiben, ist ein hochqualifizierter Beruf - ein Toy Language Compiler kann an einem Nachmittag von einem Amateur erstellt werden (oder auch etwas länger).