Está en la página 1de 10

Compiladores, Guía 11 1

Facultad : Ingeniería
Escuela : Computación
Asignatura: Compiladores

Tema: “GENERACION DE CODIGO”.

Objetivo

• Conocer las diferentes instrucciones para la generación de código.


• Demostrar por medio de un ejemplo la declaración de variables.

Introducción
Generación de código.

Aspectos Generales:

Entrada al generador de código:

La entrada para el generador de código consta de la representación intermedia del


programa fuente producida por la etapa inicial junto con la información de la tabla de
símbolos que se utilizan para determinar las direcciones de los objetos de datos durante
la ejecución denotados por los hombres de la representación intermedia.

• Representaciones lineales:

◦ Tercetos
◦ Cuartetos.
◦ Máquinas a pila.

• Representaciones arborescentes:

◦ Árboles de análisis sintácticos.


◦ Grafos dirigidos a cíclicos.
Compiladores, Guía 11 2

• Programas objeto:

La salida del generador de código es un código preparado y adaptado para ser ejecutado,
directa, o indirectamente, en una arquitectura específica. La adaptación consiste en
aprovechar al máximo las características de la máquina para optimizar la ejecución en
tiempo y en memoria.

• Lenguaje de máquina absoluto:


El programa se coloca en una posición fija de memoria y se ejecuta inmediatamente. Un
programa pequeño se puede compilar y ejecutar rápidamente pero demanda ubicaciones
específicas de memoria.

• Lenguaje de máquina reubicable:

Un programa reubicable permite que los subprogramas se compilen por separado. Los
módulos se cargan y enlazan mediante un montador o enlazador. Se gana flexibilidad al
poder compilar subrutinas por separado y llamarlas desde otros módulos. Si la máquina
objeto no maneja reubicación automática el compilador debe proporcionar al montador
información para que enlace los segmentos del programa.

• Lenguaje Ensamblador:

El lenguaje ensamblador facilita el proceso de generación de código (se utilizan


instrucciones simbólicas y macros). A cambio debe producirse un ensamblado tras la
generación de código. Esto es útil en arquitecturas con poca memoria.

Administración de la Memoria:

Uno de los propósitos de la generación de código final es la traducir la representación


simbólica en código intermedio de etiquetas y objetos de datos (variables, temporales,
parámetros, etc.) a direcciones reales en el mapa físico de memoria.
Compiladores. Guía 11 3

Asignación de Registros:

Las instrucciones que operan con registros son más cortas y rápidas. Realizar un uso
eficiente de los registros es fundamental para generar buen código.

Selección de instrucciones:

La generación de código intermedio debe tener en cuenta el juego de instrucciones de la


máquina destino. Las traducciones a código objeto debe ser, además de correcta,
eficiente.
Compiladores, Guía 11 4

Materiales y equipo

• Guía de Laboratorio Nº 11.


• Computadora con programa.
o Dev – C++.
o Visual Studio 2005.
• Dispositivo de Almacenamiento (USB).

Procedimiento

Declaración de variables:

Modificación de la gramática.

• Una lista de identificadores de variables en ASPLE tiene la forma:


idlist: TOK_ID
| TOK_ID ‘,’ idlist

• Cada vez que se declara una variable hay que guardarla en la tabla de símbolos,
por lo tanto dicha acción hay que realizarla en las posiciones marcadas con el
símbolo :
idlist: TOK_ID
| TOK_ID ‘,’ idlist

• Como las acciones semánticas se ejecutan cuando se reduce la regla, para poder
guardar una variable en la tabla de símbolos cuando se declara, es necesario
modificar la gramática de la siguiente manera:
idlist: idv
| idv ‘,’ idlist
idv: TOK_ID
Compiladores. Guía 11 5

Deducción del tipo y del número de referencias (I)

• Una declaración de variables en ASPLE puede ser, por ejemplo:

int X, Y, Z;

La producción de la gramática:

declaration: mode idlist ‘;’

indica que lo primero que se identifica es el modo, en este caso int, y después la lista de
variables, en este caso X, Y, Z. Hay que encontrar un mecanismo para recordar que el
tipo int afecta a las tres variables X, Y, Z.

• Sugerencia:
• declarar una variable global global_tipo que se actualice con el valor
correspondiente cada vez que se reduzca una de las dos primeras producciones
de mode.
• declarar una variable global global_nrefs que se inicialice a 1 cada vez que se
reduzca una de las dos primeras producciones de mode y se incremente en 1
cada vez que se reduzca la última producción de mode.
Compiladores, Guía 11 6

Deducción del tipo y del número de referencias (II)

Deducción del tipo y del número de referencias (III)


Compiladores. Guía 11 7

Generación de Código (I).

• Cuando termina la sección de declaraciones de un programa APSLE, las variables


declaradas están almacenadas en la tabla de símbolos. En ese punto es posible
generar el código ensamblador correspondiente a la declaración de las variables.

program: TOK_BEGIN dcl_train subroutines stm_train TOK_END

• Como las acciones semánticas se ejecutan cuando se reduce la regla, para poder
generar código cuando se termina la sección de declaraciones, es necesario
modificar la gramática de la siguiente manera:

program: declaraciones subroutines stm_train TOK_END


declaraciones: TOK_BEGIN dcl_train

Generación de Código (II).


Compiladores, Guía 11 8

Aclaraciones previas a la generación de código de sentencias.

• El código que vamos a generar es para una máquina a pila.


• Cuando se apile una variable, se apilará siempre su dirección, no su contenido
(en NASM es el nombre de la variable)
• Cuando se apile una constante, se apilará su valor.
• Es necesario un mecanismo que asegure que las etiquetas que se utilicen en el
programa ensamblador sean únicas.
• Un posible mecanismo es utilizar una variable entera global, etiqueta, que se
incremente cada vez que se utiliza.

Análisis de resultados

• Tomando como base la generación de código para la declaración de variables en


la parte de procedimiento y tomando estas ideas básicas:
o Hacer comprobación de tipos (en los puntos adecuados), por ejemplo, no
se pueden sumar variables de distinto tipo.
o Hacer otras comprobaciones semánticas si es necesario, por ejemplo,
comprobar si una variable ha sido declarada.
o Generar código haciendo uso de pila, desapilando los operadores y
apilando los resultados de las operaciones.

exp : exp + exp


| exp - exp
| exp * exp
| - exp
| TOK_ID
| constant
| ( exp )
| ( compare )
| dereference
compare : exp = exp
| exp <= exp
| exp > exp
constant : bool_constant
| int_constant
bool_constant : TOK_TRUE
| TOK_FALSE
int_constant : TOK_NUM
Compiladores. Guía 11 9

Investigación complementaria.

• Generación de código para sentencias condicionales


• Generación de código para bucles while.
• Generación de código para funciones.

Referencia.

• http://www.lsi.uned.es/procleng/apuntes/2006-
2007/GeneracionCodigoFinal.pdf

• http://en.wikipedia.org/wiki/Code_generation_(compiler)
Compiladores, Guía 11 10

Hoja de cotejo: 11
1
Guía 11: Generación de
Código.

Alumno: Máquina No:

Docente: GL: Fecha:

EVALUACION

% 1-4 5-7 8-10 Nota

CONOCIMIENTO 40

APLICACIÓN
DEL 40
CONOCIMIENTO

ACTITUD
20

TOTAL
100%