[Powered by Google Translate] ROB BOWDEN: Vamos falar sobre compiladores.
Até este ponto, que você acabou de digitar o seu código-fonte em
alguns arquivos, enviou-os por este grande caixa preta que é
Clang, e vem para fora o seu arquivo executável que faz
exatamente o que você escreveu em seu código fonte.
Tão mágico como que tem sido, vamos ver mais de perto
olhar para o que está realmente acontecendo
quando compilar um arquivo.
Então, o que isso significa para compilar alguma coisa?
>> Bem, no sentido mais geral, significa apenas que
transformando código escrito numa
linguagem de programação para outra.
Mas, geralmente, quando as pessoas dizem que compilar algo, eles
quer dizer que eles estão tendo a partir de uma programação de nível superior
linguagem a um menor nível de linguagem de programação.
Estas podem parecer termos muito subjetivos.
Por exemplo, você provavelmente não pensa de C como uma alta
linguagem de nível de programação, mas você compilá-lo.
Mas é tudo relativo.
Como veremos, o código de montagem e, eventualmente, máquina
código que nós compilamos para baixo é, inegavelmente, um nível mais baixo
que C.
Embora nós vamos usar Clang em demonstração de hoje, um
Muitas das idéias aqui transitar para outros compiladores.
>> Para Clang, há quatro passos importantes no global
compilação.
Estes são um, pré-processamento feito pelo pré-processador, dois,
de compilação feito pelo compilador, três, montagem
feito pelo montador, e quatro,
ligando feito pelo linker.
Pode ser confuso que um dos sub-passos de a global
Compiladores Clang é chamado o compilador, mas
nós vamos chegar a isso.
Nós estaremos usando um programa simples Olá mundo como o nosso exemplo
durante este vídeo.
Vamos dar uma olhada.
>> O primeiro passo é o pré-processamento.
O que faz o pré-processador de fazer?
Em praticamente todos os programas C que você já leu ou escrita,
você já usou linhas de código que começam com um hash.
Eu vou chamá-lo de hash, mas você também pode chamá-lo de libras número,
assinar, ou cortantes.
Qualquer linha tal é uma directiva de pré-processamento.
Você provavelmente já viu # define e # include antes, mas há
são vários outros que o pré-processador reconhece.
Vamos adicionar um # define para o nosso exemplo Olá mundo.
Agora vamos executar apenas o pré-processador neste arquivo.
Ao passar a bandeira do E-CLAGE, você está instruindo-o a correr
apenas o pré-processador.
Vamos ver o que acontece.
Parece que Clang apenas cospe tudo
na linha de comando.
A fim de salvar toda essa saída para um novo arquivo chamado
hello2.c, vamos anexar> hello2.c ao nosso comando.
Agora vamos dar uma olhada no nosso arquivo pré-processado.
>> Whoa, o que aconteceu com o nosso programa curto pouco?
Se percorrer todo o caminho até o fundo desse arquivo, vamos ver
parte do código que realmente escreveu.
Observe que o # define se foi e todas as instâncias do nome
foram substituídos por exactamente o que especificado em
a linha # define.
Então, o que são todas essas typedefs e declarações de função
no topo do ficheiro?
Note-se que a definição # não foi apenas o pré-processador
directiva que especificado.
Temos também # include stdio.h.
Assim, todas as linhas de loucos são realmente apenas stdio.h copiado
e colado na parte superior do arquivo.
É por isso que os arquivos de cabeçalho são tão úteis para a função
declarações.
Em vez de precisar copiar e colar todas as funções
declarações que planeja utilizar no topo de seu arquivo, o
pré-processador irá copiar e colá-los a partir do cabeçalho
arquivo para você.
>> Agora que estamos a fazer o pré-processamento, passamos
compilação.
A razão que nós chamamos esta compilação passo é porque este é
o passo onde Clang realmente faz a sua compilação de C para
código de montagem.
A fim de ter Clang de apresentar um processo para baixo para a montagem, mas
continuar sem mais, passar a bandeira do S-
na linha de comando.
Vamos dar uma olhada na montagem
arquivo que foi emitido.
Parece muito uma língua diferente.
Código de montagem é muito processador específico.
Neste caso, uma vez que o aparelho CS50 é executado em um
processador x86 virtual, este é o código de montagem x86.
Muito poucas pessoas escrever diretamente no código de montagem nos dias de hoje,
mas cada programa em C você escreve sempre se transforma para baixo
em conjunto.
Mais uma vez, chamamos esta etapa de compilar o C em assembly
uma vez que vamos a partir de um nível mais elevado para um nível inferior
linguagem de programação.
>> O que torna o nível de montagem inferior C?
Bem, em assembléia, estamos muito limitados no que podemos fazer.
Não há, se, enquanto, por, ou laços de qualquer tipo.
Mas você pode fazer as mesmas coisas que esses controles
estruturas oferecer usando as operações limitadas que
montagem faz prever.
Mas para ver como montagem de nível baixo realmente é, vamos
um passo a mais em nossa compilação, montagem.
É o trabalho do montador de transformar o código de montagem
em objeto ou código de máquina.
Lembre-se que o montador não faz conjunto de saída;
ao contrário, ela leva na montagem e código saídas máquina.
Código de máquina é o actual 1 e 0 que a CPU uma lata
compreender, mas ainda temos um pouco de trabalho deixaram
antes que possamos executar o nosso programa.
Vamos montar nosso código de montagem, passando
Clang bandeira do c.
Agora vamos ver o que está no arquivo montado.
>> Bem, isso não nos ajuda muito.
Lembre-se que o código de máquina é os uns e zeros que
o computador possa entender.
Isso não significa que é fácil para nós entendermos.
Assim, exatamente como baixo nível é montagem?
É quase idêntico ao código objeto.
Indo de montagem para código objeto é muito mais de um
tradução do que uma transformação, é por isso que
não se pode considerar que o montador
fazer qualquer compilação real.
Na verdade, é muito fácil de traduzir manualmente a partir de
montagem para código de máquina.
Olhando para a montagem de uma função principal, que a primeira linha
passa a corresponder a 0x55 hexadecimais.
No sistema binário, que é 1010101.
A segunda linha passa a corresponder 0x895 hexadecimal.
E o seguinte, 0x56.
Dada uma tabela relativamente simples, você poderia traduzir
montagem no código que as máquinas podem entender também.
>> Portanto, há uma etapa restante em
de compilação, que está ligando.
Ligando combina um monte de arquivos objeto em um arquivo grande
que você pode realmente executar.
Vinculação é muito dependente do sistema.
Então, a maneira mais fácil de obter Clang para apenas um link objeto
arquivos juntos é chamar Clang em todos os arquivos que
você deseja vincular juntos.
Se você especificar. O arquivos, então não será necessário reprocessar,
compilar e montar todo o seu código-fonte.
Vamos jogar uma função matemática em nosso arquivo, por isso temos
algo de vincular pol
Agora vamos compilá-lo de volta para o código objeto e
chamar Clang sobre ele.
Oops.
Desde que incluiu uma função matemática, precisamos vincular em
a biblioteca de matemática com lm.
>> Se quisermos unir monte de arquivos. Ø que
escreveu em nosso próprio, nós apenas especificá-los todos ao
linha de comando.
A restrição é que apenas um desses arquivos deve
realmente especificar uma função principal, ou então o
executável resultante não saberia por onde começar
executar o seu código.
Qual é a diferença entre especificar um arquivo para vincular em
com l-e apenas especificar um arquivo diretamente?
Nada.
É que acontece Clang saber exatamente o arquivo
algo como-lm acontece a referir.
Se você soubesse que o arquivo, você pode especificá-lo
explicitamente.
Basta lembrar que todos os l bandeiras tem que vir no final
de sua demanda do cliente.
>> E isso é tudo que existe para ela.
Quando você apenas executar Clang em alguns arquivos, este é o que é
realmente fazendo.
Meu nome é Rob Bowden, e este é o CS50.