1 00:00:07,200 --> 00:00:09,100 [Powered by Google Translate] ROB BOWDEN: Vamos falar sobre compiladores. 2 00:00:09,100 --> 00:00:11,490 Até este ponto, que você acabou de digitar o seu código-fonte em 3 00:00:11,490 --> 00:00:14,260 alguns arquivos, enviou-os por este grande caixa preta que é 4 00:00:14,260 --> 00:00:16,890 Clang, e vem para fora o seu arquivo executável que faz 5 00:00:16,890 --> 00:00:19,430 exatamente o que você escreveu em seu código fonte. 6 00:00:19,430 --> 00:00:22,170 Tão mágico como que tem sido, vamos ver mais de perto 7 00:00:22,170 --> 00:00:23,590 olhar para o que está realmente acontecendo 8 00:00:23,590 --> 00:00:25,220 quando compilar um arquivo. 9 00:00:25,220 --> 00:00:28,580 Então, o que isso significa para compilar alguma coisa? 10 00:00:28,580 --> 00:00:31,150 >> Bem, no sentido mais geral, significa apenas que 11 00:00:31,150 --> 00:00:32,580 transformando código escrito numa 12 00:00:32,580 --> 00:00:34,680 linguagem de programação para outra. 13 00:00:34,680 --> 00:00:37,550 Mas, geralmente, quando as pessoas dizem que compilar algo, eles 14 00:00:37,550 --> 00:00:39,660 quer dizer que eles estão tendo a partir de uma programação de nível superior 15 00:00:39,660 --> 00:00:42,460 linguagem a um menor nível de linguagem de programação. 16 00:00:42,460 --> 00:00:44,960 Estas podem parecer termos muito subjetivos. 17 00:00:44,960 --> 00:00:48,090 Por exemplo, você provavelmente não pensa de C como uma alta 18 00:00:48,090 --> 00:00:51,440 linguagem de nível de programação, mas você compilá-lo. 19 00:00:51,440 --> 00:00:52,730 Mas é tudo relativo. 20 00:00:52,730 --> 00:00:55,790 Como veremos, o código de montagem e, eventualmente, máquina 21 00:00:55,790 --> 00:00:59,270 código que nós compilamos para baixo é, inegavelmente, um nível mais baixo 22 00:00:59,270 --> 00:01:00,700 que C. 23 00:01:00,700 --> 00:01:03,310 Embora nós vamos usar Clang em demonstração de hoje, um 24 00:01:03,310 --> 00:01:06,360 Muitas das idéias aqui transitar para outros compiladores. 25 00:01:06,360 --> 00:01:09,160 >> Para Clang, há quatro passos importantes no global 26 00:01:09,160 --> 00:01:10,200 compilação. 27 00:01:10,200 --> 00:01:15,430 Estes são um, pré-processamento feito pelo pré-processador, dois, 28 00:01:15,430 --> 00:01:19,530 de compilação feito pelo compilador, três, montagem 29 00:01:19,530 --> 00:01:22,010 feito pelo montador, e quatro, 30 00:01:22,010 --> 00:01:24,640 ligando feito pelo linker. 31 00:01:24,640 --> 00:01:27,600 Pode ser confuso que um dos sub-passos de a global 32 00:01:27,600 --> 00:01:30,980 Compiladores Clang é chamado o compilador, mas 33 00:01:30,980 --> 00:01:32,530 nós vamos chegar a isso. 34 00:01:32,530 --> 00:01:35,050 Nós estaremos usando um programa simples Olá mundo como o nosso exemplo 35 00:01:35,050 --> 00:01:36,270 durante este vídeo. 36 00:01:36,270 --> 00:01:38,380 Vamos dar uma olhada. 37 00:01:38,380 --> 00:01:40,330 >> O primeiro passo é o pré-processamento. 38 00:01:40,330 --> 00:01:42,520 O que faz o pré-processador de fazer? 39 00:01:42,520 --> 00:01:45,560 Em praticamente todos os programas C que você já leu ou escrita, 40 00:01:45,560 --> 00:01:48,310 você já usou linhas de código que começam com um hash. 41 00:01:48,310 --> 00:01:51,730 Eu vou chamá-lo de hash, mas você também pode chamá-lo de libras número, 42 00:01:51,730 --> 00:01:53,280 assinar, ou cortantes. 43 00:01:53,280 --> 00:01:56,840 Qualquer linha tal é uma directiva de pré-processamento. 44 00:01:56,840 --> 00:02:00,650 Você provavelmente já viu # define e # include antes, mas há 45 00:02:00,650 --> 00:02:03,690 são vários outros que o pré-processador reconhece. 46 00:02:03,690 --> 00:02:07,340 Vamos adicionar um # define para o nosso exemplo Olá mundo. 47 00:02:07,340 --> 00:02:11,690 Agora vamos executar apenas o pré-processador neste arquivo. 48 00:02:11,690 --> 00:02:16,150 Ao passar a bandeira do E-CLAGE, você está instruindo-o a correr 49 00:02:16,150 --> 00:02:17,880 apenas o pré-processador. 50 00:02:17,880 --> 00:02:19,130 Vamos ver o que acontece. 51 00:02:22,250 --> 00:02:24,020 Parece que Clang apenas cospe tudo 52 00:02:24,020 --> 00:02:25,200 na linha de comando. 53 00:02:25,200 --> 00:02:27,800 A fim de salvar toda essa saída para um novo arquivo chamado 54 00:02:27,800 --> 00:02:33,850 hello2.c, vamos anexar> hello2.c ao nosso comando. 55 00:02:33,850 --> 00:02:37,800 Agora vamos dar uma olhada no nosso arquivo pré-processado. 56 00:02:37,800 --> 00:02:40,810 >> Whoa, o que aconteceu com o nosso programa curto pouco? 57 00:02:40,810 --> 00:02:43,890 Se percorrer todo o caminho até o fundo desse arquivo, vamos ver 58 00:02:43,890 --> 00:02:46,070 parte do código que realmente escreveu. 59 00:02:46,070 --> 00:02:49,800 Observe que o # define se foi e todas as instâncias do nome 60 00:02:49,800 --> 00:02:51,950 foram substituídos por exactamente o que especificado em 61 00:02:51,950 --> 00:02:53,590 a linha # define. 62 00:02:53,590 --> 00:02:56,530 Então, o que são todas essas typedefs e declarações de função 63 00:02:56,530 --> 00:02:58,140 no topo do ficheiro? 64 00:02:58,140 --> 00:03:00,820 Note-se que a definição # não foi apenas o pré-processador 65 00:03:00,820 --> 00:03:02,390 directiva que especificado. 66 00:03:02,390 --> 00:03:05,280 Temos também # include stdio.h. 67 00:03:05,280 --> 00:03:09,560 Assim, todas as linhas de loucos são realmente apenas stdio.h copiado 68 00:03:09,560 --> 00:03:11,810 e colado na parte superior do arquivo. 69 00:03:11,810 --> 00:03:14,110 É por isso que os arquivos de cabeçalho são tão úteis para a função 70 00:03:14,110 --> 00:03:15,160 declarações. 71 00:03:15,160 --> 00:03:17,740 Em vez de precisar copiar e colar todas as funções 72 00:03:17,740 --> 00:03:21,050 declarações que planeja utilizar no topo de seu arquivo, o 73 00:03:21,050 --> 00:03:22,990 pré-processador irá copiar e colá-los a partir do cabeçalho 74 00:03:22,990 --> 00:03:24,140 arquivo para você. 75 00:03:24,140 --> 00:03:26,480 >> Agora que estamos a fazer o pré-processamento, passamos 76 00:03:26,480 --> 00:03:27,680 compilação. 77 00:03:27,680 --> 00:03:30,725 A razão que nós chamamos esta compilação passo é porque este é 78 00:03:30,725 --> 00:03:34,130 o passo onde Clang realmente faz a sua compilação de C para 79 00:03:34,130 --> 00:03:35,370 código de montagem. 80 00:03:35,370 --> 00:03:38,280 A fim de ter Clang de apresentar um processo para baixo para a montagem, mas 81 00:03:38,280 --> 00:03:42,030 continuar sem mais, passar a bandeira do S- 82 00:03:42,030 --> 00:03:43,560 na linha de comando. 83 00:03:43,560 --> 00:03:44,790 Vamos dar uma olhada na montagem 84 00:03:44,790 --> 00:03:47,390 arquivo que foi emitido. 85 00:03:47,390 --> 00:03:49,740 Parece muito uma língua diferente. 86 00:03:49,740 --> 00:03:52,660 Código de montagem é muito processador específico. 87 00:03:52,660 --> 00:03:55,440 Neste caso, uma vez que o aparelho CS50 é executado em um 88 00:03:55,440 --> 00:04:00,470 processador x86 virtual, este é o código de montagem x86. 89 00:04:00,470 --> 00:04:03,450 Muito poucas pessoas escrever diretamente no código de montagem nos dias de hoje, 90 00:04:03,450 --> 00:04:06,490 mas cada programa em C você escreve sempre se transforma para baixo 91 00:04:06,490 --> 00:04:07,940 em conjunto. 92 00:04:07,940 --> 00:04:11,440 Mais uma vez, chamamos esta etapa de compilar o C em assembly 93 00:04:11,440 --> 00:04:14,170 uma vez que vamos a partir de um nível mais elevado para um nível inferior 94 00:04:14,170 --> 00:04:15,480 linguagem de programação. 95 00:04:15,480 --> 00:04:17,880 >> O que torna o nível de montagem inferior C? 96 00:04:17,880 --> 00:04:21,660 Bem, em assembléia, estamos muito limitados no que podemos fazer. 97 00:04:21,660 --> 00:04:25,120 Não há, se, enquanto, por, ou laços de qualquer tipo. 98 00:04:25,120 --> 00:04:27,560 Mas você pode fazer as mesmas coisas que esses controles 99 00:04:27,560 --> 00:04:30,270 estruturas oferecer usando as operações limitadas que 100 00:04:30,270 --> 00:04:32,350 montagem faz prever. 101 00:04:32,350 --> 00:04:35,960 Mas para ver como montagem de nível baixo realmente é, vamos 102 00:04:35,960 --> 00:04:39,320 um passo a mais em nossa compilação, montagem. 103 00:04:39,320 --> 00:04:41,890 É o trabalho do montador de transformar o código de montagem 104 00:04:41,890 --> 00:04:44,740 em objeto ou código de máquina. 105 00:04:44,740 --> 00:04:47,610 Lembre-se que o montador não faz conjunto de saída; 106 00:04:47,610 --> 00:04:51,080 ao contrário, ela leva na montagem e código saídas máquina. 107 00:04:51,080 --> 00:04:54,040 Código de máquina é o actual 1 e 0 que a CPU uma lata 108 00:04:54,040 --> 00:04:57,290 compreender, mas ainda temos um pouco de trabalho deixaram 109 00:04:57,290 --> 00:04:59,380 antes que possamos executar o nosso programa. 110 00:04:59,380 --> 00:05:01,400 Vamos montar nosso código de montagem, passando 111 00:05:01,400 --> 00:05:04,080 Clang bandeira do c. 112 00:05:04,080 --> 00:05:06,410 Agora vamos ver o que está no arquivo montado. 113 00:05:06,410 --> 00:05:09,220 >> Bem, isso não nos ajuda muito. 114 00:05:09,220 --> 00:05:11,340 Lembre-se que o código de máquina é os uns e zeros que 115 00:05:11,340 --> 00:05:13,240 o computador possa entender. 116 00:05:13,240 --> 00:05:16,080 Isso não significa que é fácil para nós entendermos. 117 00:05:16,080 --> 00:05:19,160 Assim, exatamente como baixo nível é montagem? 118 00:05:19,160 --> 00:05:21,480 É quase idêntico ao código objeto. 119 00:05:21,480 --> 00:05:24,300 Indo de montagem para código objeto é muito mais de um 120 00:05:24,300 --> 00:05:27,540 tradução do que uma transformação, é por isso que 121 00:05:27,540 --> 00:05:29,310 não se pode considerar que o montador 122 00:05:29,310 --> 00:05:31,400 fazer qualquer compilação real. 123 00:05:31,400 --> 00:05:34,110 Na verdade, é muito fácil de traduzir manualmente a partir de 124 00:05:34,110 --> 00:05:36,050 montagem para código de máquina. 125 00:05:36,050 --> 00:05:39,040 Olhando para a montagem de uma função principal, que a primeira linha 126 00:05:39,040 --> 00:05:42,100 passa a corresponder a 0x55 hexadecimais. 127 00:05:42,100 --> 00:05:45,470 No sistema binário, que é 1010101. 128 00:05:45,470 --> 00:05:49,300 A segunda linha passa a corresponder 0x895 hexadecimal. 129 00:05:49,300 --> 00:05:51,290 E o seguinte, 0x56. 130 00:05:51,290 --> 00:05:53,730 Dada uma tabela relativamente simples, você poderia traduzir 131 00:05:53,730 --> 00:05:57,130 montagem no código que as máquinas podem entender também. 132 00:05:57,130 --> 00:05:58,810 >> Portanto, há uma etapa restante em 133 00:05:58,810 --> 00:06:01,150 de compilação, que está ligando. 134 00:06:01,150 --> 00:06:04,530 Ligando combina um monte de arquivos objeto em um arquivo grande 135 00:06:04,530 --> 00:06:06,380 que você pode realmente executar. 136 00:06:06,380 --> 00:06:08,570 Vinculação é muito dependente do sistema. 137 00:06:08,570 --> 00:06:11,030 Então, a maneira mais fácil de obter Clang para apenas um link objeto 138 00:06:11,030 --> 00:06:13,920 arquivos juntos é chamar Clang em todos os arquivos que 139 00:06:13,920 --> 00:06:15,190 você deseja vincular juntos. 140 00:06:15,190 --> 00:06:18,740 Se você especificar. O arquivos, então não será necessário reprocessar, 141 00:06:18,740 --> 00:06:21,680 compilar e montar todo o seu código-fonte. 142 00:06:21,680 --> 00:06:23,960 Vamos jogar uma função matemática em nosso arquivo, por isso temos 143 00:06:23,960 --> 00:06:25,210 algo de vincular pol 144 00:06:34,220 --> 00:06:37,010 Agora vamos compilá-lo de volta para o código objeto e 145 00:06:37,010 --> 00:06:38,260 chamar Clang sobre ele. 146 00:06:40,560 --> 00:06:41,420 Oops. 147 00:06:41,420 --> 00:06:43,790 Desde que incluiu uma função matemática, precisamos vincular em 148 00:06:43,790 --> 00:06:46,610 a biblioteca de matemática com lm. 149 00:06:46,610 --> 00:06:48,990 >> Se quisermos unir monte de arquivos. Ø que 150 00:06:48,990 --> 00:06:51,420 escreveu em nosso próprio, nós apenas especificá-los todos ao 151 00:06:51,420 --> 00:06:52,460 linha de comando. 152 00:06:52,460 --> 00:06:55,320 A restrição é que apenas um desses arquivos deve 153 00:06:55,320 --> 00:06:57,790 realmente especificar uma função principal, ou então o 154 00:06:57,790 --> 00:06:59,930 executável resultante não saberia por onde começar 155 00:06:59,930 --> 00:07:00,910 executar o seu código. 156 00:07:00,910 --> 00:07:03,360 Qual é a diferença entre especificar um arquivo para vincular em 157 00:07:03,360 --> 00:07:06,600 com l-e apenas especificar um arquivo diretamente? 158 00:07:06,600 --> 00:07:07,440 Nada. 159 00:07:07,440 --> 00:07:09,850 É que acontece Clang saber exatamente o arquivo 160 00:07:09,850 --> 00:07:12,560 algo como-lm acontece a referir. 161 00:07:12,560 --> 00:07:14,700 Se você soubesse que o arquivo, você pode especificá-lo 162 00:07:14,700 --> 00:07:15,930 explicitamente. 163 00:07:15,930 --> 00:07:18,990 Basta lembrar que todos os l bandeiras tem que vir no final 164 00:07:18,990 --> 00:07:20,770 de sua demanda do cliente. 165 00:07:20,770 --> 00:07:22,300 >> E isso é tudo que existe para ela. 166 00:07:22,300 --> 00:07:24,940 Quando você apenas executar Clang em alguns arquivos, este é o que é 167 00:07:24,940 --> 00:07:26,350 realmente fazendo. 168 00:07:26,350 --> 00:07:29,490 Meu nome é Rob Bowden, e este é o CS50.