1 00:00:07,200 --> 00:00:09,100 [Powered by Google Translate] ROB BOWDEN: Parliamo di compilatori. 2 00:00:09,100 --> 00:00:11,490 Fino a questo punto, si è appena digitato il tuo codice sorgente in 3 00:00:11,490 --> 00:00:14,260 alcuni file, inviato loro attraverso questa grande scatola nera che è 4 00:00:14,260 --> 00:00:16,890 Clang, e viene fuori il file eseguibile che fa 5 00:00:16,890 --> 00:00:19,430 esattamente quello che hai scritto nel codice sorgente. 6 00:00:19,430 --> 00:00:22,170 Per quanto magico che è stato, stiamo andando a prendere una più stretta 7 00:00:22,170 --> 00:00:23,590 guardare a ciò che succede 8 00:00:23,590 --> 00:00:25,220 quando si compila un file. 9 00:00:25,220 --> 00:00:28,580 Quindi, che cosa significa per compilare qualcosa? 10 00:00:28,580 --> 00:00:31,150 >> Beh, in senso più generale, significa solo 11 00:00:31,150 --> 00:00:32,580 trasformando codice scritto in uno 12 00:00:32,580 --> 00:00:34,680 linguaggio di programmazione ad un altro. 13 00:00:34,680 --> 00:00:37,550 Ma di solito quando le persone dicono di compilare qualcosa, 14 00:00:37,550 --> 00:00:39,660 significa che stanno prendendo da una programmazione di livello superiore 15 00:00:39,660 --> 00:00:42,460 lingua per un linguaggio di programmazione di livello inferiore. 16 00:00:42,460 --> 00:00:44,960 Possono sembrare termini molto soggettivi. 17 00:00:44,960 --> 00:00:48,090 Per esempio, probabilmente non pensare a C come un alto 18 00:00:48,090 --> 00:00:51,440 livello di linguaggio di programmazione, ma non lo compila. 19 00:00:51,440 --> 00:00:52,730 Ma è tutto relativo. 20 00:00:52,730 --> 00:00:55,790 Come vedremo, il codice assembly e, infine, della macchina 21 00:00:55,790 --> 00:00:59,270 codice che si compila fino a è senza dubbio un livello inferiore 22 00:00:59,270 --> 00:01:00,700 di C. 23 00:01:00,700 --> 00:01:03,310 Anche se useremo Clang in manifestazione di oggi, un 24 00:01:03,310 --> 00:01:06,360 molte delle idee qui riporto ad altri compilatori. 25 00:01:06,360 --> 00:01:09,160 >> Per Clang, ci sono quattro passaggi importanti nella generale 26 00:01:09,160 --> 00:01:10,200 compilazione. 27 00:01:10,200 --> 00:01:15,430 Si tratta di uno, pre-elaborazione effettuata dal preprocessore, due, 28 00:01:15,430 --> 00:01:19,530 compilazione fatta dal compilatore, tre, assemblaggio 29 00:01:19,530 --> 00:01:22,010 svolto dal assemblatore e quattro, 30 00:01:22,010 --> 00:01:24,640 collegamento fatto dal linker. 31 00:01:24,640 --> 00:01:27,600 Si può confondere che una delle sottofasi del complessivo 32 00:01:27,600 --> 00:01:30,980 Compilatori Clang è chiamato compilatore, ma 33 00:01:30,980 --> 00:01:32,530 ci arriveremo. 34 00:01:32,530 --> 00:01:35,050 Useremo un semplice programma ciao mondo come il nostro esempio 35 00:01:35,050 --> 00:01:36,270 tutto questo video. 36 00:01:36,270 --> 00:01:38,380 Diamo uno sguardo. 37 00:01:38,380 --> 00:01:40,330 >> Il primo passo è preelaborazione. 38 00:01:40,330 --> 00:01:42,520 Che cosa fa il preprocessore fare? 39 00:01:42,520 --> 00:01:45,560 In quasi ogni programma C che tu abbia mai letto o scritto, 40 00:01:45,560 --> 00:01:48,310 hai utilizzato linee di codice che iniziano con un hash. 41 00:01:48,310 --> 00:01:51,730 Lo chiamerò hash, ma si può anche chiamare sterline, il numero 42 00:01:51,730 --> 00:01:53,280 firmare, o taglienti. 43 00:01:53,280 --> 00:01:56,840 Ogni tale linea è una direttiva del preprocessore. 44 00:01:56,840 --> 00:02:00,650 Avete probabilmente visto # define e # include prima, ma non ci 45 00:02:00,650 --> 00:02:03,690 sono molti di più che il preprocessore riconosce. 46 00:02:03,690 --> 00:02:07,340 Proviamo ad aggiungere un # define al nostro esempio ciao mondo. 47 00:02:07,340 --> 00:02:11,690 Ora eseguire solo il preprocessore su questo file. 48 00:02:11,690 --> 00:02:16,150 Passando clage bandiera-E, si sta istruendo l'esecuzione 49 00:02:16,150 --> 00:02:17,880 solo il preprocessore. 50 00:02:17,880 --> 00:02:19,130 Vediamo cosa succede. 51 00:02:22,250 --> 00:02:24,020 Sembra Clang sputa appena fuori tutto 52 00:02:24,020 --> 00:02:25,200 dalla riga di comando. 53 00:02:25,200 --> 00:02:27,800 Al fine di salvare tutto questo output in un nuovo file chiamato 54 00:02:27,800 --> 00:02:33,850 hello2.c, faremo aggiungere> hello2.c al nostro comando. 55 00:02:33,850 --> 00:02:37,800 Ora diamo uno sguardo al nostro file pre-elaborato. 56 00:02:37,800 --> 00:02:40,810 >> Ehi, che fine ha fatto il nostro programma po 'corto? 57 00:02:40,810 --> 00:02:43,890 Se andiamo fino in fondo di questo file, vedremo 58 00:02:43,890 --> 00:02:46,070 parte del codice che in realtà abbiamo scritto. 59 00:02:46,070 --> 00:02:49,800 Si noti che il # define è andato e tutte le istanze del nome 60 00:02:49,800 --> 00:02:51,950 sono stati sostituiti con esattamente quello specificato 61 00:02:51,950 --> 00:02:53,590 la riga # define. 62 00:02:53,590 --> 00:02:56,530 Così che cosa sono tutti questi typedef e le dichiarazioni di funzione 63 00:02:56,530 --> 00:02:58,140 all'inizio del file? 64 00:02:58,140 --> 00:03:00,820 Si noti che il # define non era l'unico preprocessore 65 00:03:00,820 --> 00:03:02,390 direttiva che abbiamo specificato. 66 00:03:02,390 --> 00:03:05,280 Abbiamo anche # include stdio.h. 67 00:03:05,280 --> 00:03:09,560 Quindi, tutte le linee sono in realtà solo pazzi stdio.h copiato 68 00:03:09,560 --> 00:03:11,810 e incollato nella parte superiore di questo file. 69 00:03:11,810 --> 00:03:14,110 È per questo che i file header sono così utili per la funzione 70 00:03:14,110 --> 00:03:15,160 dichiarazioni. 71 00:03:15,160 --> 00:03:17,740 Invece di dover copiare e incollare tutte le funzioni 72 00:03:17,740 --> 00:03:21,050 dichiarazioni si prevede di utilizzare nella parte superiore del file, le 73 00:03:21,050 --> 00:03:22,990 preprocessore copia e incolla dalla testata 74 00:03:22,990 --> 00:03:24,140 il file per te. 75 00:03:24,140 --> 00:03:26,480 >> Ora che abbiamo finito di pre-elaborazione, passiamo 76 00:03:26,480 --> 00:03:27,680 compilazione. 77 00:03:27,680 --> 00:03:30,725 Il motivo per cui chiamiamo questa compilation passo è perché questo è 78 00:03:30,725 --> 00:03:34,130 il passaggio in cui in realtà si Clang sua compilazione da C a 79 00:03:34,130 --> 00:03:35,370 assembly di codice. 80 00:03:35,370 --> 00:03:38,280 Al fine di avere Clang compilare un file verso assembly, ma 81 00:03:38,280 --> 00:03:42,030 proseguire oltre, passare il flag-S 82 00:03:42,030 --> 00:03:43,560 dalla riga di comando. 83 00:03:43,560 --> 00:03:44,790 Diamo uno sguardo al gruppo 84 00:03:44,790 --> 00:03:47,390 file che è stato emesso. 85 00:03:47,390 --> 00:03:49,740 Sembra piuttosto una lingua diversa. 86 00:03:49,740 --> 00:03:52,660 Il montaggio è molto codice specifico processore. 87 00:03:52,660 --> 00:03:55,440 In questo caso, poiché il CS50 apparecchio è in esecuzione su un 88 00:03:55,440 --> 00:04:00,470 virtuale processore x86, questo è il codice assembly x86. 89 00:04:00,470 --> 00:04:03,450 Pochissime persone scrivere direttamente in codice assembly in questi giorni, 90 00:04:03,450 --> 00:04:06,490 ma ogni programma C che mai scrivere si trasforma in giù 91 00:04:06,490 --> 00:04:07,940 nel montaggio. 92 00:04:07,940 --> 00:04:11,440 Anche in questo caso, si chiama questo passo la compilazione del C in assembly 93 00:04:11,440 --> 00:04:14,170 dal momento che stiamo passando da un livello più alto a un livello inferiore 94 00:04:14,170 --> 00:04:15,480 linguaggio di programmazione. 95 00:04:15,480 --> 00:04:17,880 >> Ciò che rende il livello di montaggio inferiore a C? 96 00:04:17,880 --> 00:04:21,660 Beh, in assemblea, siamo molto limitati in ciò che possiamo fare. 97 00:04:21,660 --> 00:04:25,120 Non ci sono se, mentre, per, o anelli di qualsiasi tipo. 98 00:04:25,120 --> 00:04:27,560 Ma è possibile eseguire le stesse cose che questi controlli 99 00:04:27,560 --> 00:04:30,270 strutture offrono utilizzando le operazioni limitate che 100 00:04:30,270 --> 00:04:32,350 montaggio non fornire. 101 00:04:32,350 --> 00:04:35,960 Ma per vedere come assieme di livello basso è davvero, andiamo 102 00:04:35,960 --> 00:04:39,320 un ulteriore passo avanti nella nostra compilation, assemblaggio. 103 00:04:39,320 --> 00:04:41,890 E 'il lavoro del montatore di trasformare il codice assembly 104 00:04:41,890 --> 00:04:44,740 in oggetto o codice macchina. 105 00:04:44,740 --> 00:04:47,610 Ricordate che l'assembler non assembly di output; 106 00:04:47,610 --> 00:04:51,080 piuttosto, ci vuole in assemblea e la macchina uscite codice. 107 00:04:51,080 --> 00:04:54,040 Codice macchina è l'attuale 1 e 0 che una CPU può 108 00:04:54,040 --> 00:04:57,290 capire, anche se abbiamo ancora un po 'di lavoro a sinistra 109 00:04:57,290 --> 00:04:59,380 prima di poter eseguire il nostro programma. 110 00:04:59,380 --> 00:05:01,400 Facciamo assemblare il nostro codice assembly passando 111 00:05:01,400 --> 00:05:04,080 Clang il flag-c. 112 00:05:04,080 --> 00:05:06,410 Vediamo ora cosa c'è nel file montato. 113 00:05:06,410 --> 00:05:09,220 >> Beh, questo non ci aiuta molto. 114 00:05:09,220 --> 00:05:11,340 Ricordate che il codice macchina è il uno e zero che 115 00:05:11,340 --> 00:05:13,240 il computer può capire. 116 00:05:13,240 --> 00:05:16,080 Questo non significa che sia facile per noi da capire. 117 00:05:16,080 --> 00:05:19,160 Quindi, esattamente come a basso livello è l'Assemblea? 118 00:05:19,160 --> 00:05:21,480 E 'quasi identico al codice oggetto. 119 00:05:21,480 --> 00:05:24,300 Passando da assembly a codice oggetto è molto più di un 120 00:05:24,300 --> 00:05:27,540 traduzione di una trasformazione, ed è per questo 121 00:05:27,540 --> 00:05:29,310 non si potrebbe prendere in considerazione l'assemblatore di 122 00:05:29,310 --> 00:05:31,400 fare qualsiasi effettiva compilazione. 123 00:05:31,400 --> 00:05:34,110 In realtà, è abbastanza facile da tradurre manualmente da 124 00:05:34,110 --> 00:05:36,050 assembly in codice macchina. 125 00:05:36,050 --> 00:05:39,040 Guardando il gruppo per una funzione principale, che la prima linea 126 00:05:39,040 --> 00:05:42,100 succede a corrispondere a 0x55 esadecimali. 127 00:05:42,100 --> 00:05:45,470 In binario, che è 1010101. 128 00:05:45,470 --> 00:05:49,300 La seconda riga succede a corrispondere 0x895 esadecimale. 129 00:05:49,300 --> 00:05:51,290 E la successiva, 0x56. 130 00:05:51,290 --> 00:05:53,730 Data una tabella relativamente semplice, si potrebbe tradurre 131 00:05:53,730 --> 00:05:57,130 assembly nel codice che le macchine in grado di capire troppo. 132 00:05:57,130 --> 00:05:58,810 >> Quindi c'è un passo rimanente in 133 00:05:58,810 --> 00:06:01,150 compilazione, che è il collegamento. 134 00:06:01,150 --> 00:06:04,530 Collegamento unisce un gruppo di file oggetto in un unico file 135 00:06:04,530 --> 00:06:06,380 che si può effettivamente eseguire. 136 00:06:06,380 --> 00:06:08,570 Il collegamento è molto dipende dal sistema. 137 00:06:08,570 --> 00:06:11,030 Quindi il modo più semplice per collegare Clang solo oggetto 138 00:06:11,030 --> 00:06:13,920 file insieme è quella di chiamare Clang su tutti i file che 139 00:06:13,920 --> 00:06:15,190 si vuole abbinare. 140 00:06:15,190 --> 00:06:18,740 Se si specifica. File o, allora non avrà bisogno di rielaborare, 141 00:06:18,740 --> 00:06:21,680 compilare e assemblare tutto il codice sorgente. 142 00:06:21,680 --> 00:06:23,960 Buttiamo una funzione matematica nel nostro file, così abbiamo 143 00:06:23,960 --> 00:06:25,210 qualcosa da collegare trovi 144 00:06:34,220 --> 00:06:37,010 Ora compilarlo indietro al codice oggetto e 145 00:06:37,010 --> 00:06:38,260 Clang chiamano su di esso. 146 00:06:40,560 --> 00:06:41,420 Oops. 147 00:06:41,420 --> 00:06:43,790 Dal momento che abbiamo inserito una funzione matematica, abbiamo bisogno di collegare in 148 00:06:43,790 --> 00:06:46,610 la libreria matematica con-lm. 149 00:06:46,610 --> 00:06:48,990 >> Se volessimo collegare insieme o gruppo di file. Che 150 00:06:48,990 --> 00:06:51,420 ha scritto il nostro, che avevamo appena specificare tutti al 151 00:06:51,420 --> 00:06:52,460 riga di comando. 152 00:06:52,460 --> 00:06:55,320 La limitazione è che uno solo di questi file devono essere 153 00:06:55,320 --> 00:06:57,790 effettivamente specificare una funzione principale, oppure il 154 00:06:57,790 --> 00:06:59,930 eseguibile risultante non saprei da dove cominciare 155 00:06:59,930 --> 00:07:00,910 esegue il codice. 156 00:07:00,910 --> 00:07:03,360 Qual è la differenza tra la specifica di un file da collegare in 157 00:07:03,360 --> 00:07:06,600 con-l e solo specificando un file direttamente? 158 00:07:06,600 --> 00:07:07,440 Niente. 159 00:07:07,440 --> 00:07:09,850 E 'solo che Clang capita di sapere esattamente cosa del file 160 00:07:09,850 --> 00:07:12,560 qualcosa di simile accade-lm di riferimento. 161 00:07:12,560 --> 00:07:14,700 Se si sapeva che file manualmente, è possibile specificarlo 162 00:07:14,700 --> 00:07:15,930 esplicitamente. 163 00:07:15,930 --> 00:07:18,990 Basta ricordare che tutto l bandiere venire alla fine 164 00:07:18,990 --> 00:07:20,770 della richiesta del cliente. 165 00:07:20,770 --> 00:07:22,300 >> E questo è tutto ciò che devi fare. 166 00:07:22,300 --> 00:07:24,940 Quando si basta eseguire Clang su determinati file, questo è ciò che è 167 00:07:24,940 --> 00:07:26,350 effettivamente facendo. 168 00:07:26,350 --> 00:07:29,490 Il mio nome è Rob Bowden, e questo è CS50.