Download - Generacion codigomaquina
Generación de código. Procesadores de Lenguaje II
Generación de Código Máquina
frontend
generadorde código
Códigointermedio
Programa fuente
Código intermedio
Código máquinaoptimización
Generación de código. Procesadores de Lenguaje II
Generación de Código MáquinaTraducción de la representación intermedia a código objeto (normalmente ensamblador)Hay que tener en cuenta la arquitectura de la máquina para realizar una gestión eficiente de la memoria y de los registrosPrimero se generan las directivas para reservar memoria para las variables y datosLuego se genera el resto del código. Por ejemplo, los árbolesde sintaxis abstracta se recorren para generar código directamenteHay que tener en cuenta:
Los lenguajes fuente y objetoGestión de memoria y registrosJuego de instruccionesOrden de evaluación
Generación de código. Procesadores de Lenguaje II
Generación de CódigoSe debe generar código correcto y de “alta calidad”
Asignación de recursos eficiente (optimizaciones dependientes de la máquina)
Uso de registros (restricciones HW…)
Uso de memoria
Selección y orden de instrucciones (INC, ADD, …)
Asegurar que el código generado es el óptimo para cualquier entrada es un problema “indecidible” (¿mejorar al programador de ensamblador?)
Enfoques:Traducción directa de bloques de código intermedio
Uso de información de uso de variables en el bloque
Generación global de códigoAnálisis de flujo para asignación “óptima” de registros (cada bloque tiene contexto)
Generación de código. Procesadores de Lenguaje II
Sistema Procesador de Lenguaje
skeletal source program
source program
target assembly program
relocatable machine code
absolute machine code
preprocessor
compiler
assembler
loader/link editor
Generación de código. Procesadores de Lenguaje II
EnsambladoresCódigo ensamblador: nemónicos para instrucciones, y nombres para direcciones de memoria.
Ensamblador en dos pasos:Primera pasada: los identificadores se asignan a direcciones de momria (0-offset)e.g. asignar 0 a a, 4 a b …Segunda pasada: produce código máquina (reasignable) :
MOV a, R1ADD #2, R1MOV R1, b
0001 01 00 00000000 *0011 01 10 000000100010 01 00 00000100 *
relocationbit
Generación de código. Procesadores de Lenguaje II
Cargador y Editor de EnlaceCargador(loader): toma código máquina reasignable (relocatable) y mueve direcciones para cargarlas en memoria.
Enlazador (linker): toma varios programas reasignables, con referencias cruzadas, para generar un solo fichero.
Necesita una correspondencia entre nombres de variables y direcciones en cada instrucción.
Generación de código. Procesadores de Lenguaje II
Ejemplos Generación de Código (2)Expresión CódigoX::=Y Comienzo: MOV Y,XX::=Y op Z Comienzo: MOV Y, R0
OP Z, R0MOV R0,X
IF C THEN E1 ELSE E2 Comienzo: Código para CIF-FALSE-GOTO et1Código para E1
GOTO et2et1: Código para E2
et2:WHILE C DO S Comienzo: Código para C
IF-FALSE-GOTO et1Código para SGOTO Comienzo
et1:
Generación de código. Procesadores de Lenguaje II
Máquina ObjetoMáquina de registros R0 … RN-1
Instrucciones de dos direcciones: ins fuente, destinoMOV f,d (mover fuente a destino)ADD f,d (sumar fuente a destino, resultado en destino)SUB f,d (restar fuente a destino, resultado en destino)MULT f,d (multiplicar, idem)DIV f,d (dividir, idem)GOTO d (salto hacia posición)CJ< d (salto condicional según última operación a registro)
Modos de direccionamiento:Modo Forma Dirección Coste extraAbsoluto M M 1Constante #2 - 1Registo Ri Ri 0Registro ind *Ri contenido(Ri) 0Indexado C(Ri) C+contendido(Ri) 1Indexado reg *C(Ri) contenido(C+contendido(Ri)) 1
Con R’s
Generación de código. Procesadores de Lenguaje II
Coste de las instruccionesUno + uno por cada dirección de memoria o literal en la instruicción
Se corresponde con la longitud total de la instrucciónCuesta más cargar una instrucción que ejecutarla
EjemplosMOV R0,R1 (coste 1)MOV R2,M (coste 2)
Generación de código. Procesadores de Lenguaje II
Ejemplos Generación de Código y coste/* código intermedio */temp2 := temp1 + 2
/*código ensamblador */MOV temp1, R1
ADD #2, R1
MOV R1, temp2(coste: 6)
/*código máquina reasignable*/0001 00 01 0000 0000 *0011 00 01 0000 00100010 01 00 0000 0100 *
/*código ensamblador */MOV temp1, temp2
ADD #2, temp2(coste: 6)
/*código máquina reasignable*/0101 00 00 0000 0000 *0000 0100 *0111 00 00 0000 00100000 0100 *
Generación de código. Procesadores de Lenguaje II
Ejemplos Generación de Código y coste/* código intermedio */temp2 := temp1 + 2
/*código ensamblador */ADD R0, R1MOV R1, temp2(R1 tiene temp1,R0 tiene #2)(¡se pierde temp1!)(coste: 3)
/*código máquina reasignable*/1000 00 01 0010 01 00 0000 0100 *
/*código ensamblador */ADD R0,*R1MOV *R1, *R2(R0 tiene #2,*R1 tiene temp1,*R2 tiene temp2)(coste: 2)
/*código máquina reasignable*/1101 00 01 0000 01 02
Variables ya en registros
(por contexto)
Generación de código. Procesadores de Lenguaje II
Generación Simple de CódigoSe divide el código intermedio en bloques básicosSe genera código para cada bloque independiente del restoMás elaborado que un algoritmo “instrucción a instrucción”:
d=a-b+c t1=a-b
t2=t1+c
d=t2
MOV a, R0
SUB b, R0
MOV R0, t1
MOV t1, R0
ADD c, R0
MOV R0, t2
MOV t2, d
Se pueden quitar
Mejor: MOV R0,d
Generación de código. Procesadores de Lenguaje II
Grafos de Flujo y Bloques BásicosGrafo de Flujo
Grafo dirigido que representa el flujo de control
Bloque BásicoNodo de un grafo de flujoSecuencia de sentencias consecutivas. El flujo de control lo recorre de principio a fin
x := 1i := 1
L:x := x * xi := i + 1if i < 10 goto L
Método de divisiónBuscar sentencias “líder”
Primera sentenciaSentencia origen de cualquier saltoCualquier sentencia que sigue a un salto
Bloque básico: instruicciones entre sentencias “líder”
Generación de código. Procesadores de Lenguaje II
Tratamiento Bloque BásicoSea el bloque básico
1. L: 2. t := 2 * x3. w := t + x4. if w > 0 goto L’
(3) nunca puede ser ejecutada sin haberse ejecutado (2) antes
(3) podría cambiarse a w := 3 * xPodría elminarse (2)?
Generación de código. Procesadores de Lenguaje II
Información de Uso Posterior
“x está viva a la salida de un bloque”si x puede ser usada fuera del bloquese supone que todas variables no temporales están vivas a la salida (criterio conservador)
“la sentencia j usa el valor de x calculado en la sentencia i”
si j toma a x como un operando y el control puede ir de i a j sin una asignación a x
i: x := y op z…j: a:= b op x
…x := y op z…
…a := b op x…
Generación de código. Procesadores de Lenguaje II
Información de Uso PosteriorMétodo para determinar variables vivas
Recorrer las sentencias del bloque básico hacia atrásPara cada instrucción i: x:=y op z marcar variables:1. Asignar a la instrucción i la situación de “x”,”y”,”z” en la TS2. Marcar en la TS “x” como “no viva” y “sin uso posterior”3. Marcar en la TS “y” y “z” como “viva”, y el uso posterior fijarlo a i
Todas las variables se marcan como “viva” en la última instrucción
Ej (d=a-b+c)1. t1=a-b2. t2=t1+c3. d=t2
V, NP V, NP V,UP=2 V, NP V,UP=2 NV, NP
V, NP V, NP V, NP V, NP NV, NP V,UP=3
V, NP V, NP V, NP V, NP NV, NP NV, NP
a b c d t1 t21
2
3
Generación de código. Procesadores de Lenguaje II
Generación Simple de CódigoSe efectúa asignación “local” de registros
Considera el uso posterior de cada variable sólo en el bloqueAl final del bloque se almacenan todas las variables en memoria
Se usan descriptoresDescriptores de registros: qué variables almacenanDescriptores de variables: en qué sitios se encuentran
1. Determinar L, y’, z’2. Generar MOV y’,L3. Generar OP z’,L4. Indicar que x está en L5. Si los valores de y o z no tienen
uso posterior, liberar sus registros
L: Localización para guardar resultado: obtenreg(x,y,z)
y’: una de las posiciones de yz’: una de las posiciones de zIdeal: y’, z’ en registros
Almacenar las variables vivas en memoria (según descriptores)
Para cada sentencia x:= y op z
Generación de código. Procesadores de Lenguaje II
Estrategia de almacenamientoDebería L ser un registro o una posición de memoria?Estrategia simple:
Mantener resultados calculados en registros lo máximo posible
El número de registros puede agotarse
Al final del bloque básico salvar todos los registros en memoria
Es el algoritmo más simpleLas técnicas globales gestionan el uso inter-bloque de los registros mediante análisis de flujo de control
Generación de código. Procesadores de Lenguaje II
Obtención de registrosobtenreg(x:=y op z):
1. usar el registro de y si está en un registro que no tiene otra variable, y además y no está viva ni tiene uso posterior. Si no:
2. usar un registro vacío si hay. Si no:3. usar un registro ocupado si op requiere que x
esté en un registro o si x tiene uso posterior. Actualizar el descriptor de registro. Si no:
4. usar la posición de memoria de x
Generación de código. Procesadores de Lenguaje II
Ejemplo Generación Códigof=(a-b)*(c+d)+e t1=a-b
t2=c+d
t3=t1*t2
t4=t3+e
f=t4
MOV a, R0
SUB b, R0
MOV c, R1
ADD d, R1
MULT R0, R1
ADD e, R1
MOV R1, f
Distinguiendo variables temporales en bloque básico
Descriptores Reg
R0 con t1
R1 con t2
R1 con t3
R1 con t4
CódigoInstrucciones
t1=a-b
t2=c+d
t3=t1*t2
t4=t3+e
f=t4
MOV a, R0
SUB b, R0
MOV c, R1
ADD d, R1
MOV R1, R2
MULT R0, R2
MOV R2, R3
ADD e, R3
MOV R3, f
//SALVAR R1-R4
Las variables temporales no se distinguen
Descriptores Reg
R0 con t1
R1 con t2
R2 con t3
R3 con t4
CódigoInstrucciones