Código de tres direcciones

De Wikipedia, la enciclopedia libre
Saltar a: navegación, búsqueda

En ciencias de la computación, el código de tres direcciones (en inglés: three address code, normalmente abreviado a TAC o 3AC) es un lenguaje intermedio usado por compiladores optimizadores para ayudar en las transformaciones de mejora de código. Cada instrucción TAC tiene a lo sumo tres operandos y es típicamente una combinación de asignación y operador binario. Por ejemplo, t1 := t2 + t3. El nombre proviene del uso de tres operandos en estas declaraciones aunque instrucciones con menos operandos pueden existir.

Ya que el código de tres direcciones es usado como un lenguaje intermedio en los compiladores, los operandos normalmente no contendrán direcciones de memoria o registros concretos, sino que direcciones simbólicas que serán convertidas en direcciones reales durante la asignación de registros. Es también común que los nombres de los operandos sean numerados secuencialmente ya que el código de tres direcciones es típicamente generado por el compilador.

Ejemplos[editar]

En este ejemplo, un cálculo está compuesto por otros más pequeños.

En el código de tres direcciones, esto sería dividido en varias instrucciones, que son más fáciles de traducir a lenguaje ensamblador. También es más sencillo detectar sub-expresiones comunes para acortar el código.

# Calcular una solución de la ecuación cuadrática
x = (-b + sqrt(b^2 - 4*a*c)) / (2*a)
t1 := b * b
t2 := 4 * a
t3 := t2 * c
t4 := t1 - t3
t5 := sqrt(t4)
t6 := 0 - b
t7 := t5 + t6
t8 := 2 * a
t9 := t7 / t8
x := t9


En este ejemplo de tipo C, un bucle almacena los cuadrados de los números del 0 al 9.

El código de tres direcciones puede tener saltos condicionales e incondicionales para acceder a la memoria. Puede tener también métodos de llamadas a funciones o puede reducir estos a saltos. De este modo, el código de tres direcciones puede ser útil en el análisis de control del flujo.

...
for (i = 0; i < 10; ++i) {
    b[i] = i*i; 
}
...
     t1 := 0                ; inicializa i
L1:  if t1 >= 10 goto L2    ; salto condicional
     t2 := t1 * t1          ; cuadrado de i
     t3 := t1 * 4           ; reserva de cuatro bytes para el almacenamiento
     t4 := b + t3           ; dirección para almacenar i*i
     *t4 := t2              ; almacenar mediante puntero
     t1 := t1 + 1           ; incrementar i
     goto L1                ; repetir bucle
L2:

Véase también[editar]

Referencias[editar]