Fortsetzung Story: Pascals eigener Compiler für Windows von Grund auf neu

Der unerwartet herzliche Empfang der Habr-Öffentlichkeit zu meinem Beitrag über den hausgemachten XD Pascal-Compiler für MS-DOS hat mich zum Nachdenken gebracht. Ist es nicht ärgerlich, dass das Amateurprojekt, für das ich viel Energie aufgewendet habe, für mich ein totes Gewicht war, seit die virtuelle DOS-Maschine vollständig von Windows verschwunden ist? Das Ergebnis der Überlegungen war der XD Pascal-Compiler für Windows . Vielleicht hat er etwas von dem nostalgischen Charme verloren und die Möglichkeit einer naiven Arbeit mit Grafiken durch BIOS-Unterbrechungen verloren. Der Übergang zu Windows hauchte dem Projekt jedoch neues Leben ein und eröffnete den Weg zu einem langjährigen Traum - der Selbstzusammenstellung.

Nach wie vor habe ich keine Hilfstools für die automatische Compilergenerierung verwendet. Eine solche Sturheit mag seltsam aussehen, aber das Projekt hatte einen einzigen Zweck - mein eigenes Vergnügen, und zusätzliche Werkzeuge würden nur als Hindernis dienen. In diesem Sinne wurde der Compiler von Grund auf neu entwickelt.



Fünf Schritte zum Selbstkompilieren unter Windows


Es lohnt sich, ein paar Worte zu den Hauptaufgaben zu sagen, die auf dem Weg von DOS zu Windows gelöst werden mussten:

Bildung von Headern und Abschnitten der ausführbaren Datei. Neben der offiziellen Beschreibung des Portable Executable-Formats wurde der Artikel Erstellen der kleinstmöglichen ausführbaren PE-Datei in dieser Phase zu einer hervorragenden Hilfe. Da die Header und Abschnitte genaue Adressen von Prozeduren und Variablen erfordern und erst nach Berechnung der Codegröße und der globalen Daten gefunden werden können, musste die Kompilierung in drei Durchgängen erfolgen. Beim ersten Durchgang wird ein Diagramm mit Prozeduraufrufen erstellt und "tote" Prozeduren werden markiert. im zweiten werden Adressen, Code und Datengröße berechnet, Header werden ausgefüllt; im dritten wird ein Code generiert. Ein solcher Kunshtuk ist sehr unerschöpflich, insbesondere wenn man bedenkt, dass bei jedem Durchgang alle Phasen der Zusammenstellung neu wiederholt werden, beginnend mit der lexikalischen Analyse. Dies führt jedoch zu einem sehr präzisen Quellcode für den Compiler und erfordert keine Zwischendarstellung des Programms. Nachtrag: Die Generierung von verschiebbarem Code ist derzeit implementiert, die Kompilierung erfolgt in einem Durchgang.

Neuer Codegenerator. Für die Kompilierung für Windows mussten Paare von Segment-Offset-Registern durch 32-Bit-Offset-Register ersetzt sowie Präfixe zum Ändern der Länge des Operanden (66h) und der Adresslänge (67h) entfernt (und stellenweise hinzugefügt) werden.

Anweisung zum Deklarieren externer Funktionen der Windows-API. Alle mit der external Direktive deklarierten Funktionsnamen werden in die Tabellen des Importabschnitts der ausführbaren Datei eingetragen. Da für diese Funktionen Argumente von rechts nach links übergeben werden müssen, mussten wir die Reihenfolge der Argumente in der Deklaration und den Aufrufen aller dieser Funktionen manuell umkehren. Somit ist die Notwendigkeit einer Inversion mittels des Compilers nicht mehr erforderlich. Der Einfachheit halber werden alle Argumente für Prozeduren und Funktionen in XD Pascal als 32-Bit-Werte übergeben. Glücklicherweise gilt diese Regel auch für Windows-API-Funktionen, sodass die Interaktion mit Systembibliotheken den Mechanismus zum Übergeben von Argumenten nicht erschwerte. Hinzufügung: Die Umkehrung der Reihenfolge der Argumente importierter Funktionen wird jetzt automatisch durchgeführt.

Entfernen von Sets und Infix-String-Operationen aus dem Quellcode. Diese Anforderung bezieht sich auf die Aufgabe der Selbstzusammenstellung. Die Berechnung von Ausdrücken in XD Pascal ist so konzipiert, dass alle Zwischenergebnisse 32 Bit lang sind und auf dem Stapel gespeichert werden. Für Pascal-Strings und -Sets ist dieser Ansatz nicht akzeptabel. Genauer gesagt hätte es Mengen mit einer Größe von bis zu 32 Elementen ermöglicht, aber solche Mengen wären praktisch nutzlos gewesen. Ergänzung: Die Unterstützung für Zeichenfolgenoperationen und das Einrichten von bis zu 256 Elementen ist jetzt implementiert.

Wrapper für einige Verfahren. Die Idee der Selbstkompilierung führte dazu, dass Aufrufe einiger Routinen in der Standardbibliothek eingeschlossen wurden. Die Wrapper-Signatur ist für Fälle der Kompilierung durch einen externen Compiler (Delphi / Free Pascal) und der Selbstkompilierung identisch. Die verpackten Verfahren variieren. Somit sind alle Besonderheiten der Kompilierungsmethode in mehreren Wrappern lokalisiert. Pascal ist voll von Verfahren, die bei näherer Betrachtung nach den Regeln von Pascal selbst nicht implementiert werden können: Read , Write , Move usw. Für die gängigsten Verfahren, einschließlich Read und Write , habe ich eine Ausnahme gemacht und sie für die Grammatik der Sprache untypisch implementiert, aber jedem Kenner von Pascal vertraut. Für die meisten anderen nicht typischen Verfahren wurden Wrapper benötigt. Daher ist XD Pascal nicht vollständig mit Delphi oder Free Pascal kompatibel, aber dies ist keine große Sache, da selbst Free Pascal selbst im Kompatibilitätsmodus mit Delphi tatsächlich nicht kompatibel bleibt. Ergänzung: Die Unterstützung für untypisierte formale Variablenargumente ist jetzt implementiert. Dies ermöglichte es, die Prozeduren BlockRead , BlockWrite , Move , FillChar mit Delphi und Free Pascal kompatibel zu machen, wodurch die Anzahl der erforderlichen Wrapper radikal reduziert wurde.

Kompilieren von Programmen mit einer GUI


Die Aufgabe der Selbstkompilierung bleibt trotz ihrer symbolischen Bedeutung begrenzt: Der Compiler ist ein Konsolenprogramm und sieht daher nicht wie ein vollwertiger Bewohner der Windows-Welt aus. Auf dem Weg zum Kompilieren von Programmen mit einer Fensteroberfläche waren einige weitere Innovationen erforderlich:

Anweisung an den Compiler, den Schnittstellentyp festzulegen. Der Schnittstellentyp (Konsole oder Grafik) muss in einem separaten Headerfeld der ausführbaren Datei angegeben werden. Wie Sie wissen, gibt es in Delphi und Free Pascal dafür eine Direktive $APPTYPE . Eine ähnliche $A Direktive erschien in XD Pascal.

Die Operation der Adressierung von Prozeduren und Funktionen. Im klassischen Pascal gibt es keine vollwertigen Zeiger auf Prozeduren und Funktionen - sie werden teilweise durch einen prozeduralen Typ ersetzt. Dieser Typ ist in XD Pascal nicht implementiert. Wie dem auch sei, die Anwendung der @ -Operation auf die Prozeduren in meinem bescheidenen Projekt schien mir nutzlos. Die Verarbeitung von Windows-API-Ereignissen basiert jedoch auf Rückrufen, und hier wurde die Übertragung der Adresse der aufgerufenen Handlerprozedur plötzlich zu einem dringenden Bedarf. Ergänzung: XD Pascal bietet jetzt volle Unterstützung für den Prozedurtyp.

Explizite Angabe der Namen der verknüpften Bibliotheken. Für Konsolenprogramme war der Import der Windows-API-Funktionen aus der KERNEL32.DLL Bibliothek ausreichend. Programme mit einer GUI, die USER32.DLL , GDI32.DLL usw. enthält. Es war notwendig, die Syntax der external Direktive zu erweitern, indem der Name der Bibliothek dort hinzugefügt wurde.


GUI-Demo

Was ist das Ergebnis?


Das Ergebnis ist ein sehr einfacher selbstkompilierender Compiler für Windows. Es ist unwahrscheinlich, dass es mit leistungsstarken kollektiven Projekten wie Free Pascal richtig verglichen wird. Vielmehr fällt er in die Gewichtsklasse des berühmten Amateurs BeRo Tiny Pascal . Im Vergleich dazu hat XD Pascal spürbare Vorteile: Die Grammatik von Pascal wird strenger eingehalten und Fehler werden kontrolliert, es gibt eine vollwertige Dateieingabe / -ausgabe, die Arithmetik von Gleitkommazahlen wird unterstützt, es besteht keine Abhängigkeit vom externen Assembler, die Kompilierung von Programmen mit einer Fensterschnittstelle ist zulässig.

Als nächstes muss ich mich mit den Fehlalarmen einiger Antivirenprogramme befassen - ein neues Problem, an das ich in der kleinen, gemütlichen Welt von MS-DOS nicht gedacht habe. Wenn Sie Glück haben, wird XD Pascal zusammen mit BeRo Tiny Pascal in einem Laborworkshop zum Kurs des Compilerdesigns an der MSTU vorgestellt. N.E. Bauman.

Source: https://habr.com/ru/post/de462889/


All Articles