Introduction à la compilation Un compilateur est un programme qui traduit un au

Introduction à la compilation Un compilateur est un programme qui traduit un autre programme Premier compilateur : compilateur Fortran de J. Backus (1957) Langage source : langage de haut niveau (C, C++, Java, Pascal, Fortran...) Langage cible : langage de bas niveau (assembleur, langage machine) compilateur programme source messages d'erreur programme cible Bibliographie Aho, Sethi, Ullman, 1986/2007. Compilateurs. Principes, techniques et outils, Pearson Education France. http://igm.univ-mlv.fr/~laporte/compil/plan.html Ce support de cours est inspiré du manuel ci-dessus et du cours de Dominique Perrin Cousins des compilateurs Interpréteurs Diffèrent d'un compilateur par l'intégration de l'exécution et de la traduction. Utilisés pour les langages de commande Formateurs de texte Traduit le code source dans le langage de commande d'une imprimante Préprocesseurs Effectuent des substitutions de définitions, des transformations lexicales, des définitions de macros, etc. L'environnement d'un compilateur "squelette" de programme source programme cible en langage d'assemblage préprocesseur code relogeable programme source prétraité code machine absolu compilateur assembleur éditeur de liens Liens avec l'éditeur et le débogueur Les compilateurs industriels produisent directement du code relogeable bibliothèque chargeur code relogeable Les phases de la compilation programme cible gestion de la table des symboles programme source analyseur lexical gestion des erreurs analyseur syntaxique analyseur sémantique générateur de code intermédiaire "optimiseur" de code générateur de code cible Analyse lexicale Analyse du programme source en constituants minimaux, les lexèmes On passe de position = initial + vitesse * 60 à [id, 1] [=] [id, 2] [+] [id, 3] [*] [60] Les identificateurs rencontrés sont placés dans la table des symboles Les blancs et les commentaires sont éliminés Analyse syntaxique On reconstruit la structure syntaxique de la suite de lexèmes fournie par l'analyseur lexical instruction d'affectation expression expression expression expression identificateur position identificateur initial identificateur vitesse nombre 60 expression = + * Arbre de dérivation Génération de code intermédiaire Programme pour une machine abstraite Représentations utilisées - Code à trois adresses temp1 := inttoreal(60) temp2 := id3 * temp1 temp3 := id2 + temp2 id1 := temp3 - Arbres syntaxiques "Optimisation" de code Elimination des opérations inutiles pour produire du code plus efficace. temp1 := inttoreal(60) temp2 := id3 * temp1 temp3 := id2 + temp2 id1 := temp3 temp1 := id3 * 60.0 id1 := id2 + temp1 La constante est traduite en réel flottant à la compilation, et non à l'exécution La variable temp3 est éliminée Génération de code cible La dernière phase produit du code en langage d'assemblage Un point important est l'utilisation des registres temp1 := id3 * 60.0 MOVF id3, R2 id1 := id2 + temp1 MULF #60.0, R2 MOVF id2,R1 ADDF R2, R1 MOVF R1, id1 F = flottant. La première instruction transfère le contenu de id3 dans le registre R2 La seconde multiplie le contenu du registre R2 par la constante 60.0 position = initial + vitesse*60 analyseur lexical id1 := id2 + id3*60 analyseur syntaxique Table des symboles 1 position ... 2 initial ... 3 vitesse ... 4 5 ... = id1 + * id2 id3 60 analyseur sémantique id1 + * id2 id3 inttoreal 60 générateur de code intermédiaire temp1 := inttoreal(60) temp2 := id3 * temp1 temp3 := id2 + temp2 id1 := temp3 temp1 := id3 * 60.0 id1 := id2 + temp1 optimiseur de code générateur de code cible MOVF id3, R2 MULF #60.0, R2 MOVF id2,R1 ADDF R2, R1 MOVF R1, id1 Préprocesseurs Traitement des macros #define Inclusion de fichiers #include Extensions de langages #ifdef Les définitions de macros permettent l'utilisation de paramètres. Par exemple, en TEX, une définition de macro a la forme \define <nom> <modèle>{<corps>} Par exemple, si on définit : \define\JACM #1;#2;#3. {{\sl J.ACM} {\bf #1}:#2, pp. #3} et si on écrit \JACM 17;4;715-728 on doit voir J.ACM 17:4, pp. 715-728 Langages d’assemblage Les langages d’assemblage ou assembleurs sont des versions un peu plus lisibles du code machine avec des noms symboliques pour les opérations et pour les opérandes MOV a, R1 ADD #2, R1 MOV R1, b Chaque processeur a son langage d'assemblage Les langages d'assemblage d'un même constructeur se ressemblent Assemblage L’assemblage consiste à traduire ce code en code binaire La forme la plus simple est l’assemblage en deux passes Première passe On crée une table des symboles (distincte de celle du compilateur) pour associer des adresses mémoires aux identificateurs identificateur adresse a 0 b 4 Assemblage Deuxième passe On crée du code machine relogeable c’est-à-dire relatif à l’adresse mémoire L où il commence Les instructions précédentes peuvent être traduites en : 0001 01 00 00000000 * 0011 01 10 00000010 0010 01 00 00000100 * La table des symboles de l'asssembleur sert aussi à l'édition de liens Elle permet de remplacer les références à des noms externes Langages machines Chaque processeur a son langage Exemples d'instructions binaires 0001 01 00 00000000 * 0011 01 10 00000010 0010 01 00 00000100 * Les 4 premiers bits : code de l’instruction 0001 = charger 0011 = ajouter 0010 = sauvegarder Les 2 bits suivants : registre Langages machines Les 2 bits suivants : mode d’adressage 00 = mode adresse 10 = mode littéral L’étoile (bit de translation) indique que l’adresse L doit être ajoutée aux opérandes. Si L = 00001111, c’est-à-dire 15, a et b doivent être placés en 15 et 19 Code absolu obtenu : 0001 01 00 00001111 0011 01 10 00000010 0010 01 00 00010011 Groupement des phases Partie frontale (front end) Regroupe tout ce qui dépend du langage source plutôt que de la machine cible. On peut utiliser la même partie frontale sur une machine différente Partie arrière (back end) Regroupe le reste Passes Plusieurs phases peuvent être regroupées dans une même passe consistant à lire un fichier et en écrire un autre Analyse lexicale, syntaxique, sémantique et génération de code intermédiaire peuvent être regroupées en une seule passe La réduction du nombre de passes accélère le traitement Outils logiciels Outils d’aide à la construction de compilateurs Générateurs d’analyseurs lexicaux Engendrent un analyseur lexical (scanner, lexer) sous forme d’automate fini à partir d’une spécification sous forme d’expressions rationnelles Flex, Lex Générateurs d’analyseurs syntaxiques Engendrent un analyseur syntaxique (parser) à partir d’une grammaire Bison, Yacc Générateurs de traducteurs Engendrent un traducteur à partir d’un schéma de traduction (grammaire + règles sémantiques) Bison, Yacc Compilation d’un programme C Si on compile par gcc –S essai.c le fichier suivant : #include <stdio.h> int main(void) { printf("bonjour\n") ; } on obtient de l'assembleur 8086 avec - epb pour base pointer - esp pour stack pointer - pushl pour push long etc. .file "essai.c" .version "01.01" gcc2_compiled: .section .rodata .LCO: .string "bonjour\n" .text .align 16 .globl main .type main,@function main: pushl %ebp movl %esp, %ebp subl $8, %esp subl $12, %esp pushl $.LCO call printf addl $16, %esp movl %ebp, %esp popl %ebp ret .Lfe1: .size main,.Lfe1-main .ident "GCC: (GNU) 2.96 20000731 (Linux-Man uploads/S4/ intro-comp-il.pdf

  • 17
  • 0
  • 0
Afficher les détails des licences
Licence et utilisation
Gratuit pour un usage personnel Attribution requise
Partager
  • Détails
  • Publié le Jan 27, 2021
  • Catégorie Law / Droit
  • Langue French
  • Taille du fichier 0.1420MB