En la historia de los compiladores han sido utilizadas una amplia variedad de representaciones intermedias como lo es la siguiente clase de representación de código intermedio de un árbol de 3 direcciones,2 para los operandos y una para la ubicación del resultado. esta clase incluye un amplio número de representaciones diferentes entre las cuales encontramos cuadruplos y triples. la principal diferencia entre estas notaciones y la notación postfija es que ellos incluyen referencias explicitas para los resultados de los cálculos intermedios, mientras que la notación posfija los resultados son implícitos al representarlos en una pila.
§La diferencia entre triples y cuadruplos es que con los triples es referenciado el valor intermedio hacia el número del triple que lo creo, pero en los cuádruplos requiere que ellos tengan nombres implícitos.
§Los triples tienen una ventaja obvia de ser más consistente, pero ellos dependen de su posición, y hacen que la optimización presente cambios de código mucho más compleja.
Para evitar tener que introducir nombres temporales en la tabla de símbolos, se hace referencia a un valor temporal según la posición de la proposición que lo calcula. Las propias instrucciones representan el valor del nombre temporal. La implementación se hace mediante registros de solo tres campos (op, arg1, arg2).
§En la notación de tripletes se necesita menor espacio y el compilador no necesita generar los nombres temporales. Sin embargo, en esta notación, trasladar una proposición que defina un valor temporal exige que se modifiquen todas las referencias a esa proposición. Lo cual supone un inconveniente a la hora de optimizar el código, pues a menudo es necesario cambiar proposiciones de lugar.
§Una forma de solucionar esto consiste en listar las posiciones a las tripletas en lugar de listar las tripletas mismas. De esta manera, un optimizador podría mover una instrucción reordenando la lista, sin tener que mover las tripletas en si.
Las proposiciones de tres direcciones se parecen mucho al ensamblador, el cual es un lenguaje intermedio más entendible para la máquina.
• Las estructuras de control (if, switch, while, do-while, for) son realmente etiquetas goto disfrazadas.
• El problema de utilizar cuádruplos radica en que se tienen que colocar los valores temporales en la tabla de símbolo. Con una estructura de tres campos se pueden omitir los valores temporales, dicha estructura recibe el nombre de triples y tiene los siguientes campos: op, arg1 y arg2. Generalmente el código que generan los triples recibe el nombre de código de dos direcciones, aunque en ocasiones puede variar. Cuando se utilizan triples se ocupan punteros a la misma estructura de los triples.
* b t1 t2 //cuádruplos.
* b (0) //triple.
• Se debe tener en cuenta el proceso de asignación, de declaración, expresiones booleanas. Las expresiones lógicas también pueden pasarse a código de tres direcciones, utilizando para ello expresiones en corto circuito.
• La evaluación de expresiones en corto circuito implica que se evalúan condiciones revisando valores anteriores; por ejemplo, para el operador AND con una condición que se detecte como falsa toda la expresión es falsa, en el caso del operador OR si se encuentra una condición verdadera todo será verdadera.
• La notación de tres direcciones es una forma abstracta de código intermedio.
• Esta notación se puede implementar como registros con campos para el operador y operadores.
Intérpretes
• Los intérpretes generalmente utilizan este triplos para generar el código intermedio para ejecutarse una vez considerado la instrucción como válido.
• En este sentido, un compilador es más difícil de implementar ya que tendrá que mantener todas las estructuras generadas que en muchas ocasiones serán cuádruplos.
1.6 Generación de la tabla de símbolo y de direcciones Las tablas de símbolos (también llamadas tablas de identificadores y tablas de nombres), realizan dos importantes funciones en el proceso de traducción: verificar que la semántica sea correcta y ayudar en la generación apropiada de código. Ambas funciones se realizan insertando o recuperando desde la tabla de símbolos los atributos de las variables usadas en el programa fuente. Estos atributos, tales como: el nombre, tipo, dirección de almacenamiento y dimensión de una variable, usualmente se encuentran explícitamente en las declaraciones o más implícitamente a través del contexto en que aparecen los nombres de variables en el programa. Una de las estructuras de datos que se encuentran relacionadas con las fases del proce...
Aquí está la explicación línea por línea del código que proporcionaste: 1. `; You may customize this and other start-up templates;` : Este es un comentario que indica que puedes personalizar esta plantilla de inicio y otras. 2. `; The location of this template is c:\emu8086\inc\0_com_template.txt` : Este es otro comentario que indica la ubicación de la plantilla en el sistema de archivos. 4. `org 100h` : Establece la dirección de origen (origen) del programa en 100h (256 en decimal), lo que indica que el programa se cargará en la memoria a partir de esta dirección. 5. `.model small` : Establece el modelo de memoria en "small", que es un modelo de memoria simple utilizado en programas más pequeños. 6. `.stack 100h` : Define el tamaño de la pila en 100h (256 en decimal), lo que indica que se asignará un segmento de memoria de ese tamaño para la pila. 8. `.data` : Esta sección indica el comienzo de la sección de datos...
Comentarios
Publicar un comentario