1 00:00:07,200 --> 00:00:09,100 [Powered by Google Translate] ROB BOWDEN: Parlons de compilateurs. 2 00:00:09,100 --> 00:00:11,490 Jusqu'à ce point, vous venez de saisir votre code source en 3 00:00:11,490 --> 00:00:14,260 certains fichiers, les envoyer à travers cette grosse boîte noire qui est 4 00:00:14,260 --> 00:00:16,890 Clang, et sort de votre fichier exécutable qui ne 5 00:00:16,890 --> 00:00:19,430 exactement ce que vous avez écrit dans votre code source. 6 00:00:19,430 --> 00:00:22,170 Aussi magique que cela a été, nous allons un peu plus près 7 00:00:22,170 --> 00:00:23,590 Regardez ce qui se passe réellement 8 00:00:23,590 --> 00:00:25,220 quand on compile un fichier. 9 00:00:25,220 --> 00:00:28,580 Alors qu'est-ce que cela signifie pour compiler quelque chose? 10 00:00:28,580 --> 00:00:31,150 >> Eh bien, dans le sens le plus général, cela signifie juste 11 00:00:31,150 --> 00:00:32,580 transformation de code écrit dans une 12 00:00:32,580 --> 00:00:34,680 le langage de programmation à l'autre. 13 00:00:34,680 --> 00:00:37,550 Mais généralement, quand les gens disent qu'ils compiler quelque chose, ils 14 00:00:37,550 --> 00:00:39,660 dire qu'ils le prendre à partir d'une programmation de niveau supérieur 15 00:00:39,660 --> 00:00:42,460 langue pour un langage de programmation de niveau inférieur. 16 00:00:42,460 --> 00:00:44,960 Ils semblent être des termes très subjectifs. 17 00:00:44,960 --> 00:00:48,090 Par exemple, vous ne pensez probablement pas de C en haut 18 00:00:48,090 --> 00:00:51,440 langage de programmation évolué, mais vous ne le compiler. 19 00:00:51,440 --> 00:00:52,730 Mais tout est relatif. 20 00:00:52,730 --> 00:00:55,790 Comme nous le verrons, le code assembleur et, finalement, la machine 21 00:00:55,790 --> 00:00:59,270 code qui nous compilons jusqu'à constitue indéniablement un niveau inférieur 22 00:00:59,270 --> 00:01:00,700 que C. 23 00:01:00,700 --> 00:01:03,310 Bien que nous allons utiliser Clang dans la manifestation d'aujourd'hui, un 24 00:01:03,310 --> 00:01:06,360 beaucoup des idées ici reporter sur d'autres compilateurs. 25 00:01:06,360 --> 00:01:09,160 >> Pour Clang, il ya quatre étapes majeures dans l'ensemble 26 00:01:09,160 --> 00:01:10,200 compilation. 27 00:01:10,200 --> 00:01:15,430 Ce sont l'un, le prétraitement effectué par le préprocesseur, deux, 28 00:01:15,430 --> 00:01:19,530 compilation effectuée par le compilateur; trois, l'assemblage 29 00:01:19,530 --> 00:01:22,010 effectué par l'assembleur, et quatre, 30 00:01:22,010 --> 00:01:24,640 reliant réalisé par l'éditeur de liens. 31 00:01:24,640 --> 00:01:27,600 Il peut être déroutant que l'un des sous-étapes de l'ensemble 32 00:01:27,600 --> 00:01:30,980 Compilateurs Clang est appelé le compilateur, mais 33 00:01:30,980 --> 00:01:32,530 nous y reviendrons. 34 00:01:32,530 --> 00:01:35,050 Nous allons utiliser un programme mondial bonjour simple comme notre exemple 35 00:01:35,050 --> 00:01:36,270 tout au long de cette vidéo. 36 00:01:36,270 --> 00:01:38,380 Jetons un coup d'oeil. 37 00:01:38,380 --> 00:01:40,330 >> La première étape est de pré-traitement. 38 00:01:40,330 --> 00:01:42,520 Qu'est-ce que le préprocesseur faire? 39 00:01:42,520 --> 00:01:45,560 Dans presque tous les programme C vous avez déjà lu ou écrit, 40 00:01:45,560 --> 00:01:48,310 vous avez utilisé des lignes de code qui commencent par un dièse. 41 00:01:48,310 --> 00:01:51,730 Je vais l'appeler hachage, mais vous pouvez aussi l'appeler livres, le nombre 42 00:01:51,730 --> 00:01:53,280 signer ou pointu. 43 00:01:53,280 --> 00:01:56,840 Toute ligne telle est une directive de préprocesseur. 44 00:01:56,840 --> 00:02:00,650 Vous avez probablement vu # define et # include avant, mais il 45 00:02:00,650 --> 00:02:03,690 existe plusieurs autres que le préprocesseur reconnaît. 46 00:02:03,690 --> 00:02:07,340 Ajoutons un # define pour notre exemple Bonjour tout le monde. 47 00:02:07,340 --> 00:02:11,690 Maintenant, nous allons courir tout le préprocesseur dans ce dossier. 48 00:02:11,690 --> 00:02:16,150 En passant CLAGE le drapeau de l'E-, vous lui ordonnant d'exécuter 49 00:02:16,150 --> 00:02:17,880 tout le préprocesseur. 50 00:02:17,880 --> 00:02:19,130 Voyons voir ce qui se passe. 51 00:02:22,250 --> 00:02:24,020 Il ressemble à Clang crache juste hors tout 52 00:02:24,020 --> 00:02:25,200 à la ligne de commande. 53 00:02:25,200 --> 00:02:27,800 Afin de sauver l'ensemble de cette sortie vers un nouveau fichier appelé 54 00:02:27,800 --> 00:02:33,850 hello2.c, nous allons ajouter> hello2.c à notre commande. 55 00:02:33,850 --> 00:02:37,800 Maintenant, nous allons jeter un oeil à notre fichier prétraité. 56 00:02:37,800 --> 00:02:40,810 >> Waouh, qu'est-ce qui est arrivé à notre petit programme court? 57 00:02:40,810 --> 00:02:43,890 Si nous aller tout le chemin vers le bas de ce fichier, nous allons voir 58 00:02:43,890 --> 00:02:46,070 une partie du code que nous avons effectivement écrit. 59 00:02:46,070 --> 00:02:49,800 Notez que le # define a disparu et toutes les instances de nom 60 00:02:49,800 --> 00:02:51,950 ont été remplacés par exactement ce que nous avons spécifié dans 61 00:02:51,950 --> 00:02:53,590 la ligne # define. 62 00:02:53,590 --> 00:02:56,530 Alors, quels sont tous ces redéfinitions et des déclarations de fonctions 63 00:02:56,530 --> 00:02:58,140 au début du fichier? 64 00:02:58,140 --> 00:03:00,820 Notez que le # define n'était pas seulement le préprocesseur 65 00:03:00,820 --> 00:03:02,390 directive que nous avons spécifié. 66 00:03:02,390 --> 00:03:05,280 Nous avons également # include stdio.h. 67 00:03:05,280 --> 00:03:09,560 Donc, toutes les lignes folles sont en fait juste copié stdio.h 68 00:03:09,560 --> 00:03:11,810 et collé dans le haut de ce fichier. 69 00:03:11,810 --> 00:03:14,110 C'est pourquoi les fichiers d'en-tête sont si utiles pour la fonction 70 00:03:14,110 --> 00:03:15,160 déclarations. 71 00:03:15,160 --> 00:03:17,740 Au lieu d'avoir à copier et coller l'ensemble de la fonction 72 00:03:17,740 --> 00:03:21,050 déclarations que vous prévoyez d'utiliser en haut de votre fichier, les 73 00:03:21,050 --> 00:03:22,990 préprocesseur copiez et collez-les à partir de l'en-tête 74 00:03:22,990 --> 00:03:24,140 déposer pour vous. 75 00:03:24,140 --> 00:03:26,480 >> Maintenant que nous avons terminé le prétraitement, nous passons 76 00:03:26,480 --> 00:03:27,680 compilation. 77 00:03:27,680 --> 00:03:30,725 La raison pour laquelle nous appelons cette compilation étape est parce que c'est 78 00:03:30,725 --> 00:03:34,130 l'étape où Clang ne fait sa compilation de C à 79 00:03:34,130 --> 00:03:35,370 code assembleur. 80 00:03:35,370 --> 00:03:38,280 Afin d'avoir Clang compiler un fichier vers le bas pour l'assemblage, mais 81 00:03:38,280 --> 00:03:42,030 continuera pas plus loin, passer le drapeau S- 82 00:03:42,030 --> 00:03:43,560 à la ligne de commande. 83 00:03:43,560 --> 00:03:44,790 Jetons un coup d'oeil à l'assemblée 84 00:03:44,790 --> 00:03:47,390 fichier qui a été émis. 85 00:03:47,390 --> 00:03:49,740 Il ressemble à un tout autre langage. 86 00:03:49,740 --> 00:03:52,660 Code assembleur est très spécifique au processeur. 87 00:03:52,660 --> 00:03:55,440 Dans ce cas, puisque l'appareil CS50 est exécuté sur un 88 00:03:55,440 --> 00:04:00,470 virtuelle des processeurs x86, il s'agit du code assembleur x86. 89 00:04:00,470 --> 00:04:03,450 Très peu de gens écrire directement dans le code assembleur de nos jours, 90 00:04:03,450 --> 00:04:06,490 mais chaque programme C vous écrit se transforme vers le bas 91 00:04:06,490 --> 00:04:07,940 dans l'assemblage. 92 00:04:07,940 --> 00:04:11,440 Encore une fois, nous appelons cette étape compiler du C dans l'assemblage 93 00:04:11,440 --> 00:04:14,170 puisque nous allons partir d'un niveau supérieur à un niveau inférieur 94 00:04:14,170 --> 00:04:15,480 le langage de programmation. 95 00:04:15,480 --> 00:04:17,880 >> Ce qui rend niveau de l'assemblage inférieure à C? 96 00:04:17,880 --> 00:04:21,660 Eh bien, dans l'assemblage, nous sommes très limités dans ce que nous pouvons faire. 97 00:04:21,660 --> 00:04:25,120 Il n'ya pas de cas, tandis que, pour les boucles, ou de toute sorte. 98 00:04:25,120 --> 00:04:27,560 Mais vous pouvez accomplir les mêmes choses que celles-ci contrôle 99 00:04:27,560 --> 00:04:30,270 structures offrent l'aide des opérations limitées 100 00:04:30,270 --> 00:04:32,350 assemblage fournit. 101 00:04:32,350 --> 00:04:35,960 Mais de voir à quel assemblage de niveau bas est vraiment, allons-y 102 00:04:35,960 --> 00:04:39,320 un pas de plus dans notre compilation, l'assemblage. 103 00:04:39,320 --> 00:04:41,890 C'est le travail de l'assembleur pour transformer le code assembleur 104 00:04:41,890 --> 00:04:44,740 en objet ou code machine. 105 00:04:44,740 --> 00:04:47,610 Rappelez-vous que l'assembleur ne assembly de sortie; 106 00:04:47,610 --> 00:04:51,080 au contraire, elle prend dans l'assemblage et le code machine sorties. 107 00:04:51,080 --> 00:04:54,040 Code machine est la réelle 1 et de 0 qu'une CPU peut 108 00:04:54,040 --> 00:04:57,290 comprendre, même si nous avons encore un petit peu de travail à gauche 109 00:04:57,290 --> 00:04:59,380 avant que nous puissions lancer notre programme. 110 00:04:59,380 --> 00:05:01,400 Nous allons monter notre code assembleur en passant 111 00:05:01,400 --> 00:05:04,080 Clang c-drapeau. 112 00:05:04,080 --> 00:05:06,410 Maintenant, nous allons voir ce qu'il ya dans le dossier constitué. 113 00:05:06,410 --> 00:05:09,220 >> Eh bien, cela ne nous aide pas beaucoup. 114 00:05:09,220 --> 00:05:11,340 Rappelez-vous que le code machine sont les uns et de zéros que 115 00:05:11,340 --> 00:05:13,240 votre ordinateur peut comprendre. 116 00:05:13,240 --> 00:05:16,080 Cela ne signifie pas que c'est facile pour nous de comprendre. 117 00:05:16,080 --> 00:05:19,160 Donc exactement comment le faible niveau est l'Assemblée? 118 00:05:19,160 --> 00:05:21,480 Il est presque identique au code objet. 119 00:05:21,480 --> 00:05:24,300 Aller de l'assemblage à code objet est beaucoup plus d'un 120 00:05:24,300 --> 00:05:27,540 Traduction qu'une transformation, ce qui explique pourquoi 121 00:05:27,540 --> 00:05:29,310 on peut pas considérer l'assembleur 122 00:05:29,310 --> 00:05:31,400 faire une réelle compilation. 123 00:05:31,400 --> 00:05:34,110 En fait, il est assez facile de traduire manuellement à partir 124 00:05:34,110 --> 00:05:36,050 assembly en code machine. 125 00:05:36,050 --> 00:05:39,040 En regardant l'assemblée pour une fonction principale, cette première ligne 126 00:05:39,040 --> 00:05:42,100 arrive à correspondre à 0x55 en hexadécimal. 127 00:05:42,100 --> 00:05:45,470 En binaire, c'est 1010101. 128 00:05:45,470 --> 00:05:49,300 La deuxième ligne qui arrive à correspondre 0x895 hexadécimal. 129 00:05:49,300 --> 00:05:51,290 Et l'autre, 0x56. 130 00:05:51,290 --> 00:05:53,730 Étant donné un tableau relativement simple, vous pourriez traduire 131 00:05:53,730 --> 00:05:57,130 ensemble dans le code que les machines peuvent comprendre aussi. 132 00:05:57,130 --> 00:05:58,810 >> Donc, il ya une étape restante de 133 00:05:58,810 --> 00:06:01,150 compilation, qui relie. 134 00:06:01,150 --> 00:06:04,530 Lier combine un ensemble de fichiers objets dans un grand dossier 135 00:06:04,530 --> 00:06:06,380 que vous pouvez réellement exécuter. 136 00:06:06,380 --> 00:06:08,570 Cette liaison est très dépendant du système. 137 00:06:08,570 --> 00:06:11,030 Donc, la meilleure façon d'obtenir Clang juste un lien à l'objet 138 00:06:11,030 --> 00:06:13,920 fichiers ensemble est d'appeler Clang sur tous les fichiers que 139 00:06:13,920 --> 00:06:15,190 vous voulez relier. 140 00:06:15,190 --> 00:06:18,740 Si vous spécifiez. Fichiers o, alors il ne sera pas nécessaire de retraiter, 141 00:06:18,740 --> 00:06:21,680 compiler et assembler l'ensemble de votre code source. 142 00:06:21,680 --> 00:06:23,960 Jetons une fonction mathématique dans notre fichier, nous avons donc 143 00:06:23,960 --> 00:06:25,210 quelque chose à relier po 144 00:06:34,220 --> 00:06:37,010 Maintenant, nous allons compiler retour en code objet et 145 00:06:37,010 --> 00:06:38,260 Clang appeler sur elle. 146 00:06:40,560 --> 00:06:41,420 Oops. 147 00:06:41,420 --> 00:06:43,790 Depuis, nous avons inclus une fonction mathématique, nous devons lier dans 148 00:06:43,790 --> 00:06:46,610 la bibliothèque mathématique avec-lm. 149 00:06:46,610 --> 00:06:48,990 >> Si nous voulions relier tas de fichiers. O que nous 150 00:06:48,990 --> 00:06:51,420 écrit par nous-mêmes, nous venions de les préciser tout à l' 151 00:06:51,420 --> 00:06:52,460 ligne de commande. 152 00:06:52,460 --> 00:06:55,320 La restriction est que seul de ces fichiers doit 153 00:06:55,320 --> 00:06:57,790 fait de spécifier une fonction principale, sinon la 154 00:06:57,790 --> 00:06:59,930 exécutable qui en résulte ne saurais pas par où commencer 155 00:06:59,930 --> 00:07:00,910 l'exécution de votre code. 156 00:07:00,910 --> 00:07:03,360 Quelle est la différence entre la spécification d'un fichier à lier dans 157 00:07:03,360 --> 00:07:06,600 avec-l et juste spécifier un fichier directement? 158 00:07:06,600 --> 00:07:07,440 Rien. 159 00:07:07,440 --> 00:07:09,850 C'est juste que Clang arrive à savoir exactement ce fichier 160 00:07:09,850 --> 00:07:12,560 quelque chose comme-lm arrive à se référer. 161 00:07:12,560 --> 00:07:14,700 Si vous saviez ce fichier vous-même, vous pouvez le spécifier 162 00:07:14,700 --> 00:07:15,930 explicitement. 163 00:07:15,930 --> 00:07:18,990 N'oubliez pas que tout l drapeaux doivent venir à la fin 164 00:07:18,990 --> 00:07:20,770 de votre demande de ses clients. 165 00:07:20,770 --> 00:07:22,300 >> Et c'est tout ce qu'il ya à faire. 166 00:07:22,300 --> 00:07:24,940 Lorsque vous lancez simplement Clang sur certains fichiers, c'est ce que c'est 167 00:07:24,940 --> 00:07:26,350 en train de faire. 168 00:07:26,350 --> 00:07:29,490 Mon nom est Rob Bowden, et c'est CS50.