Continuation Story: le propre compilateur de Pascal pour Windows à partir de zéro

L'accueil chaleureux et inattendu fourni par le public Habr à mon article sur le compilateur XD Pascal fait maison pour MS-DOS m'a fait réfléchir. N'est-ce pas gênant que le projet amateur, auquel j'ai donné beaucoup d'énergie, soit un poids mort pour moi depuis l'époque où la machine virtuelle DOS a complètement disparu de Windows? Le résultat des réflexions a été le compilateur XD Pascal pour Windows . Peut-être qu'il a perdu une partie du charme nostalgique et a perdu la capacité de travailler naïvement avec les graphiques via des interruptions du BIOS. Cependant, la transition vers Windows a insufflé une nouvelle vie au projet et a ouvert la voie à un rêve de longue date - l'auto-compilation.

Comme auparavant, je n'ai utilisé aucun outil auxiliaire pour la génération automatique de compilateur. Une telle obstination peut sembler étrange, mais le projet n'avait qu'un seul objectif - mon propre plaisir, et des outils supplémentaires ne serviraient que d'obstacle. En ce sens, le compilateur a été développé à partir de zéro.



Cinq étapes pour l'auto-compilation sur Windows


Il vaut la peine de dire quelques mots sur les principales tâches qui ont dû être résolues sur le chemin de DOS à Windows:

Formation des en-têtes et des sections du fichier exécutable. En plus de la description officielle du format Portable Executable, l'article Création du plus petit exécutable PE possible est devenu une excellente aide à ce stade. Étant donné que les en-têtes et les sections nécessitent des adresses exactes de procédures et de variables, et qu'ils ne peuvent être trouvés qu'après avoir calculé la taille du code et les données globales, la compilation a dû être effectuée en trois passes. Lors de la première passe, un graphique des appels de procédure est construit et les procédures «mortes» sont marquées; dans le second, les adresses, le code et la taille des données sont calculés, les en-têtes sont remplis; dans le troisième, un code est généré. Un tel kunshtuk est très inépuisable, d'autant plus qu'à chaque passage, toutes les étapes de la compilation sont répétées à nouveau, en commençant par l'analyse lexicale. Cependant, cela conduit à un code source très concis pour le compilateur et ne nécessite aucune représentation intermédiaire du programme. Addendum: la génération de code déplaçable est actuellement implémentée, la compilation se fait en un seul passage.

Nouveau générateur de code. La compilation pour Windows a nécessité le remplacement de paires de registres de décalage de segment par des registres de décalage 32 bits, ainsi que la suppression (et l'ajout par endroits) de préfixes pour modifier la longueur de l'opérande (66h) et la longueur de l'adresse (67h).

Directive pour déclarer les fonctions externes de l'API Windows. Tous les noms de fonctions déclarés avec la directive external sont entrés dans les tables de la section import du fichier exécutable. Étant donné que ces fonctions nécessitent de passer des arguments de droite à gauche, nous avons dû inverser manuellement l'ordre des arguments dans la déclaration et les appels de toutes ces fonctions. Ainsi, le besoin d'inversion au moyen du compilateur n'est plus nécessaire. Par souci de simplicité, tous les arguments des procédures et fonctions en XD Pascal sont passés en tant que valeurs 32 bits; heureusement, cette règle est également valable pour les fonctions de l'API Windows, donc l'interaction avec les bibliothèques système n'a pas compliqué le mécanisme de transmission des arguments. Addition: l' inversion de l'ordre des arguments des fonctions importées est désormais effectuée automatiquement.

Suppression des ensembles et des opérations de chaîne d'infixation du code source. Cette exigence est liée à la tâche d'auto-compilation. Le calcul de toute expression dans XD Pascal est conçu de sorte que tous les résultats intermédiaires aient une longueur de 32 bits et soient stockés dans la pile. Pour les chaînes et les ensembles Pascal, cette approche n'est pas acceptable. Plus précisément, cela aurait permis aux ensembles d'avoir jusqu'à 32 éléments, mais de tels ensembles auraient été pratiquement inutiles. Ajout: la prise en charge des opérations de chaîne et de la taille de 256 éléments est désormais implémentée.

Wrappers pour certaines procédures. L'idée de l'auto-compilation a conduit à encapsuler les appels à certaines routines dans la bibliothèque standard. La signature wrapper est la même pour les cas de compilation par un compilateur externe (Delphi / Free Pascal) et d'auto-compilation; les procédures enveloppées varient. Ainsi, toutes les spécificités de la méthode de compilation sont localisées dans plusieurs wrappers. Pascal regorge de procédures qui, à y regarder de plus près, s'avèrent impossibles à mettre en œuvre selon les règles de Pascal lui-même: Read , Write , Move , etc. Pour les procédures les plus courantes, y compris en Read et en Write , j'ai fait une exception et les ai implémentées atypiques pour la grammaire de la langue, mais familières à tout connaisseur de Pascal. Pour la plupart des autres procédures non typiques, des wrappers étaient nécessaires. Ainsi, XD Pascal n'est pas entièrement compatible avec Delphi ou Free Pascal, mais ce n'est pas un gros problème, car même Free Pascal lui-même en mode de compatibilité avec Delphi reste en fait incompatible. Ajout: la prise en charge des arguments de variables formelles non typées est désormais implémentée. Cela a permis de rendre les procédures BlockRead , BlockWrite , Move , FillChar compatibles avec Delphi et Free Pascal, réduisant ainsi radicalement le nombre de wrappers requis.

Compilation de programmes avec une interface graphique


La tâche d'auto-compilation, malgré sa signification symbolique, reste limitée: le compilateur est un programme console et ne ressemble donc pas à un habitant à part entière du monde Windows. Il a fallu quelques autres innovations sur la façon de compiler des programmes avec une interface de fenêtre:

Directive au compilateur pour définir le type d'interface. Le type d'interface (console ou graphique) doit être spécifié dans un champ d'en-tête distinct du fichier exécutable. Comme vous le savez, dans Delphi et Free Pascal, il existe une directive $APPTYPE . Une directive $A A similaire est apparue dans XD Pascal.

L'opération de prise de l'adresse des procédures et fonctions. Dans le Pascal classique, il n'y a pas de pointeurs à part entière vers les procédures et les fonctions - ils sont remplacés dans une certaine mesure par un type procédural. Ce type n'est pas implémenté dans XD Pascal. Quoi qu'il en soit, appliquer encore l'opération @ aux procédures de mon modeste projet me paraissait inutile. Cependant, le traitement des événements de l'API Windows est basé sur des rappels, et ici le transfert de l'adresse de la procédure de gestionnaire appelé est soudainement devenu un besoin urgent. Ajout: XD Pascal ajoute désormais une prise en charge complète du type procédural.

Spécification explicite des noms des bibliothèques liées. Pour les programmes de console, l'importation des fonctions de l'API Windows à partir de la bibliothèque KERNEL32.DLL était suffisante. Programmes avec une interface graphique tirée le USER32.DLL , GDI32.DLL , etc. Il a fallu étendre la syntaxe de la directive external en y ajoutant le nom de la bibliothèque.


Démo GUI

Quel est le résultat


Le résultat est un compilateur auto-compilateur très simple pour Windows. Il est peu probable de le comparer correctement avec de puissants projets collectifs tels que Free Pascal. Il tombe plutôt dans la catégorie de poids du célèbre amateur BeRo Tiny Pascal . Par rapport à cela, XD Pascal présente des avantages notables: la grammaire de Pascal est plus strictement observée et les erreurs sont contrôlées, il y a une entrée / sortie de fichier à part entière, l'arithmétique des nombres à virgule flottante est prise en charge, il n'y a pas de dépendance à l'assembleur externe, la compilation de programmes avec une interface de fenêtre est autorisée.

Ensuite, je dois faire face aux faux positifs de certains antivirus - un nouveau problème auquel je ne pensais pas dans le petit monde confortable de MS-DOS. Si vous avez de la chance, XD Pascal sera présenté, avec BeRo Tiny Pascal, dans un atelier de laboratoire sur le cours de conception de compilateurs au MSTU. N.E. Bauman.

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


All Articles