Geração de Código
aula-12-geração-de-código.pdf
Geração de código objeto

A geração de código compreende a última fase do modelo de
compilador que está sendo estudado.

Essa etapa recebe como entrada uma representação
intermediaria e junto com a tabela de símbolos produz um código
de saída semanticamente equivalente a entrada e que será
executado por um processador.

Em princípio a máquina que gera o código não precisa ser
necessariamente a máquina que irá executar o código, por
exemplo os compiladores que geram código nativo para
dispositivos móveis ou software embutidos.
Geração de código objeto
Geração de código objeto

Os principais requisitos para geração de código objeto são os
seguintes.

O código gerado deve ser de alta qualidade;

O código gerado deve fazer uso efetivos de recursos de máquina;

O código gerado deve executar eficientemente;
Geração de código objeto

Pelo fato dos compiladores terem que produzir código eficiente é
importante destacar a importância da etapa de otimização de
código nesse processo.

Um dos critérios mais importantes para um gerador de código é
que ele produza um código correto.
Geração de código objeto

O gerador de código é composto por três tarefas principais:

Seleção de instruções: Escolhe instruções apropriadas da arquitetura
alvo.

Alocação e atribuição de registradores: Define os valores dos
registrados e quais registradores devem ser utilizados.

Escalonamento de instrução: Decida a ordem em que as instruções
devem ser escalonadas.
Geração de código objeto

A arquitetura da máquina alvo tem um impacto significativo na
construção de geradores de código.

Entre as arquiteturas mais comuns temos a RISC, CISC, e baseadas
em pilha.

RISC (reduced intruction set computer): possui muitos registradores e
instruções simples.

CISC (complex intruction set comulter) : Possui menos registradores e
instruções complexas.

Baseadas em pilha: As operações são feitas colocando os operandos
em pilha e efetuando as operações com base no topo da pilha.
Geração de código objeto

Formas de produzir um código objeto:

Linguagem de máquina absoluta: A saída é um código objeto que é
alocado e executado diretamente na memória logo após a sua
compilação. Compiladores que implementam esse tipo de código são
conhecidos com load and go compilers e são utilizados em ambientes
acadêmicos.

Linguagem de máquina realocável: Permite a compilação separada
em subprogramas ou módulos, um programa separado faz a ligação
dos módulos compilados. Isso permite que a compilação seja feita por
módulos realocáveis.

Linguagem assembly: são geradas instruções simbólicas, para que um
montador auxilie a geração do código objeto.
Tarefa principais da geração de código objeto
Seleção de instruções

O gerador de código precisa mapear as instruções geradas na
representação intermediaria para uma sequência de código que a
arquitetura alvo possa entender.

A complexidade desse processo é determinada por três fatores:

Nível da representação intermediaria.

Natureza da arquitetura de instruções.

Qualidade do código gerado.
Tarefa principais da geração de código objeto
Seleção de instruções

A natureza da arquitetura de instruções tem um fator primordial na
geração de código pois se a máquina alvo não prover uma
instrução para cada tipo de dados podem ocorrer exceções a
regra o que exigira tratamentos especiais,

Outro fator crítico e a velocidade de execução que as instruções
oferecem.
Tarefa principais da geração de código objeto
Seleção de instruções
Código
Código Gerado
intermediário
x := y + z
LD
R0,
y // carrega y ao registrador R0
ADD R0, R0, z // soma z a R0 (R0 = R0 + 0 )
ST
x, R0
// armazena R0 em x ( x = R0 )
Tarefa principais da geração de código objeto
Seleção de instruções

Na maioria das máquinas uma sequência de código intermediário
pode ser gerar diversas formas de código objeto.

Exemplo: Nesse caso uma família de processadores pode possuir o
registrador chamado INC que faz o incremento de um valor, porem
outros processadores podem não ter esse registrador, nesse caso
temos uma exceção que deve ser tratada pelo gerador de
código.
Tarefa principais da geração de código objeto
Seleção de instruções
Código intermediário
a := a + 1
Processador família x45
Processador família 8455
INC a, #1
LD R0, a
ADD
R0, R0, #1
ST a, R0
Tarefa principais da geração de código objeto
Seleção de instruções

Essas informações de arquitetura devem estar disponíveis para que
o algoritmo de geração de código tenha condições de efetuar a
escolha correta de instrução para obter um melhor resultado.
Tarefa principais da geração de código objeto
Alocação de registradores

Outro desafio na geração de código é a correta seleção dos
valores que irão residir nos registradores.

O registrador é uma área dos processadores que armazém valores
e permitem realizador operações de forma rápida, os valores
utilizados pelos registradores devem residir na memória do
computador.

A alocação e atribuição de registradores ocorre com seleção de
um registrador especifico para qual uma variável será armazenada.
Tarefa principais da geração de código objeto
Ordem de avaliação

Trata-se da ordem em que as operações são efetuadas, a correta
avaliação das dependências, manter resultados intermediários e
execução de várias operações ao mesmo tempo.
Montadores
Texto baseado no material disponde em http://www.dca.fee.unicamp.br/~eleri/ea876/04/cap10.pdf.

Em muitos casos o resultado do processo de compilação é um
arquivo contendo um programa em assembly correspondente ao
programa de alto nível.

Esse programa em linguagem assembly, ou linguagem simbólica,
possui todas as instruções de máquina para gerar o programa
executável na arquitetura alvo.

O montador (assembler) é o programa do responsável por traduzir
o código assembly em linguagem de máquina, traduzindo cada
instrução do programa para a sequência de bits que codifica a
instrução de máquina
Montadores
Texto baseado no material disponde em http://www.dca.fee.unicamp.br/~eleri/ea876/04/cap10.pdf.

Como cada processador tem sua própria linguagem, montadores
são específicos para processadores.

O processo de montagem recebe como entrada um arquivo texto
com o código fonte do programa em assembly e gera como saída
um arquivo binário, o módulo objeto, contendo o código de
máquina e outras informações relevantes para a execução do
código gerado.
Carregadores e Ligadores
Texto baseado no material disponde em http://www.dca.fee.unicamp.br/~eleri/ea876/04/cap11.pdf.

Os montadores geram um arquivo de conteúdo binário, contendo
o código objeto associado ao arquivo-fonte de entrada.

O arquivo com o código objeto contém parte da informação
necessária à sua execução, para que ocorra a execução é preciso
que esse código seja transferido para a memória principal. Se,
ainda, o código faz referências a elementos (dados ou rotinas)
externas, será preciso integrar essas referências ao código
executável.
Carregadores e Ligadores
Texto baseado no material disponde em http://www.dca.fee.unicamp.br/~eleri/ea876/04/cap11.pdf.

A ligação, que resolve as referências que tenham sido feitas a
dados e rotinas em outros programas, e o carregamento, que
transfere o programa montado para a memória principal e dá
início à sua execução.
Carregadores e Ligadores
Texto baseado no material disponde em http://www.dca.fee.unicamp.br/~eleri/ea876/04/cap11.pdf.

O formato do módulo objeto ou arquivo executável conte as seguintes
informações.

Cabeçalho: contém a identificação do tipo de arquivo e dados sobre o
tamanho do código e eventualmente o arquivo que deu origem ao
arquivo objeto;

Código gerado: contém as instruções e dados em formato binário,
apropriado ao carregamento;

Relocação: contém as posições no código onde deverá ocorrer mudanças
de conteúdo quando for definida a posição de carregamento;

Símbolos: contém os símbolos globais definidos no módulo e símbolos cujas
definições virão de outros módulos;

Depuração: contém referências para o código fonte, tais como o número
de linha, nomes originais dos símbolos locais e estruturas de dados definidas.
Exercícios
Download

Slides - Compiladores