Quel assembleur utiliser pour un compilateur

a marqué ce sujet comme résolu.

Bonjour,

Je compte écrire un tuto sur la compilation. J'en ai déjà créé plusieurs (en projets perso ou pour mes études) et après les quelques expériences que j'ai pu avoir, aucun des langage de destination me satisfait.

Jusqu'à présent, j'ai pu tester :

  • Le langage machine : ça fonctionne bien, pas de problème rétro-compatibilité. Seulement, ça nécessite aussi de connaître le format d'exécutable du système (ELF ou PE) et puis c'est quand même plus complexe à gérer que du x86.
  • x86 : c'est celui que j'ai le moins testé (pour ne pas dire que je l'ai pas testé du tout), du coup, je suis un peu moins chaud pour celui-là. D'autant qu'il y a beaucoup de variantes différentes, ce qui aide pas en terme de choix.
  • LLVM : le plus sympa à utiliser à mon sens, d'autant qu'il permet de faire plus que tous les autres (optimiser pas mal le code produit, traduire le code dans d'autres langages). Le gros point noir, c'est qu'il a tendance à casser la rétro-compatibilité assez facilement. Je me rappelle avoir eu des problèmes parce que je regardais la doc de la dernière version (3.7) alors que j'avais la version précédente (3.6) et que la syntaxe avait en partie changée.
  • Assembleur custom à exécuter sur une VM custom : ça peut être très simple à générer et on peut simplifier les points non triviaux (entrées-sorties ou gestion des registres). Le problème, c'est qu'il faut le créer aussi et que ça permet pas de linker avec des librairies externes.

Du coup, si vous avez des avis, des conseils ou d'autres propositions, je suis preneur.

+0 -0

Pour ma part, j'ai utilisé MIPS dans un projet de compilation. C'est assez simple d'avoir quelque chose d'efficace sans pour autant s'embêter dans les détails avec la sélection d'instructions par exemple.

Je viens de voir le IR de LLVM si c'est bien ce dont tu parles, et ça semble intéressant. Mais ce problème de rétro-compatibilité demandera de faire des mise à jours. Mais après ça dépend ce que tu comptes faire dans ce tutoriel.

As-tu une idée de ce que tu comptes parler dans ton tutoriel de Compilation ? Tu pourrais donner un plan (par curiosité) ?

Tu peux aussi regarder du côté du bytecode Java. La JVM est rétro-compatible (on peut y rouler des vieilles versions du bytecode), le format est bien documenté, assez simple, et c'est portable. Par contre, c'est assez "haut niveau" et même si plusieurs langages avec des paradigmes très différents l'utilisent comme cible, c'est plus adapté à des langages "orientés objets". Pour un tutoriel, ça a aussi l'inconvénient d'abstraire des trucs intéressants d'un point de vue pédagogique (par exemple l'allocation de registres).

Pour mes études, on avait utilisé Jasmin comme assembleur. C'était plus simple (et beaucoup plus facile à déboguer) que de générer le bytecode directement.

Étant donné que j'ai une (forte) aversion pour le Java et ce qui s'en rapproche, je vais éviter la JVM.

Après réflexion, je me dis qu'il pourrait en fait être intéressant de montrer plusieurs assembleurs. Comme tu l'as dit, l'allocation des registres est quelque chose d'assez intéressant et qui mérite bien sa place dans un tuto sur la compilation. En parallèle, LLVM apporte aussi son lot d'intérêts : typage fort (ce qui est rare), possibilité de l'utiliser comme langage intermédiaire pour transformer un langage dans un autre (le plus remarquable étant javascript avec Emscripten).

Saroupille : je n'ai pas vraiment de plan à l'heure actuelle, mais je pensais faire une première introduction pour montrer rapidement toutes les étapes de la compilation avec un exemple simple (brainfuck) avant de rentrer vraiment dans les détails, les subtilités et autres points non triviaux. En terme de contenu, je pense aborder de près ou de loin à tout ce qui touche à la compilation : grammaire, parser, type-checker, AST, optimisations, génération de code, entre autre. Et potentiellement aussi : interpréteur, JIT, interprétation abstraite et édition de liens.

Je pense qu'en tant que lecteur potentiel, déjà que l'assembleur me fait un peu peur et que j'y comprends pas grand chose, si m'en montrais plusieurs différents je serais vraiment perdu et je mélangerais un peu tout. Après, si tu ne fais pas ça en parallèle, peut-être, mais c'est possible aussi que je n'adhère pas forcément au moment où tu changes d'assembleur.

Surtout si tu veux traiter tous les sujets dont tu parles, honnêtement, ça me paraît être énorme, surtout que tout ça n'est pas trivial du tout. À mon avis, tu devrais déjà te limiter dans un premier temps (enfin, si tu veux faire un cours d'introduction), à l'analyse grammaticale et syntaxique (et la construction de l'arbre ofc), et à générer du code à partir de ça, avec éventuellement une réflexion sur les optimisations que tu peux faire à partir là. Si j'étais toi, je ne me lancerais vraiment dans la vérification des types, ça me semble être vraiment trop pour un cours d'introduction, surtout que ça devient vite complexe à mettre en place et que ce n'est pas toujours décidable.

Je peux pas trop t'aider sinon pour te dire quel assembleur utiliser, j'aurais tendance à te dire de faire du LLVM, c'est certainement la chose la plus facile à comprendre pour ton lecteur, quitte à mentionner clairement qu'il est important de faire attention à la version de LLVM utilisée.

C'est un travail ambitieux et tu peux déjà le découper en 2 parties : compilation haut niveau (analyse syntaxique, lexicale, grammaticale…) et bas niveau (génération de code).

Et la première partie n'a pas besoin d'assembleur… Pour la seconde, pourquoi se cantonner à un seul langage ? Tu peux envisager d'en aborder plusieurs : une VM custom pour pas se faire chier avec des aspects chiants lors que tu traites de la partie génération de code et passer vers d'autres quand les besoins se font sentir (genre allocation des registres). D'autant que ca peut être bien pour le lecteur d'aborder plusieurs assembleurs.

Sur les options en elles mêmes, je pense qu'il faut mieux essayer d'utiliser quelque chose d'agnostique vis à vis de la machine réelle et se concentrer sur les concepts, ce que permet de faire une VM ou LLVM.

Pour les histoires de récomptabilité LLVM, est ce que c'est vraiment grave si jamais une nouvelle version casse le codé généré ? Le lecteur peut toujours se renseigner et mettre à jour les morceaux impactés.

+0 -0

Il est évident que le but principal sera que le lecteur puisse écrire un compilateur complet rapidement, c'est-à-dire avoir l'analyse syntaxique, la construction de l'AST (qui se fait en même temps), une vérification de type et une génération de code. D'ailleurs, sur un langage impératif de base (type C), la vérification de typage est presque triviale. Par contre, je suis d'accord que s'il y a de l'inférence, de la généricité, des templates, de la surcharge ou autre, ça peut clairement se compliquer.

Le reste, ce sera des améliorations possible du compilateur. Il serait même possible que tout ces chapitres supplémentaires soient totalement indépendants, même si ça risque d'être un poil plus compliqué à faire. Mais ça reste à mon sens la partie la plus intéressante, celle qui différencie les compilateurs.

Connectez-vous pour pouvoir poster un message.
Connexion

Pas encore membre ?

Créez un compte en une minute pour profiter pleinement de toutes les fonctionnalités de Zeste de Savoir. Ici, tout est gratuit et sans publicité.
Créer un compte