7.3 El proceso de ensamblado Resumen en diapositivas 7.3.1 ensambladores de 2 pasadas • El problema de la referencia adelantada (hacia adelante) : • Considerando que cada enunciado es un salto a L. el ensamblador no podrá ensamblar este enunciado hasta que no conozca la dirección del enunciado L. • El problema es que dicho enunciado podría estar cerca del final del programa, y para el ensamblador seria imposible encontrar la dirección sin leer antes casi todo el programa. • Teniendo en cuenta lo anterior, las referencias adelantadas se pueden manejar de dos maneras: 1.-El ensamblador podría leer dos veces el programa fuente. 2.-Leer el programa en lenguaje ensamblador una vez, convertirlo en una forma intermedia, y guardar esta información en una tabla en la memoria. 7.3.2 Primera pasada • Su función principal es construir una tabla llamada «tabla de símbolos» la cual contiene los valores de todos los símbolos. • Los símbolos son etiquetas o mas bien valores a los que se les asigna un nombre simbólico mediante una seudoinstruccíon, ejemplo: • BUFSIZE EQU 8192 • La variable llamada contador de posiciones de instrucciones (ILC, intruction location counter). Es utilizada debido a que, al asignar valor a un símbolo en el campo de etiqueta de una instrucción, el ensamblador debe saber que dirección tendrá esa instrucción durante la ejecución del programa. • Esta variable se pone en 0 al principio de la primera pasada y se incrementa en una cantidad igual a la longitud de la instrucción cada vez que se procesa una instrucción. • La primera pasada utiliza por lo menos 3 tablas: • • • • • 1.- la tabla de símbolos. una entrada por cada símbolo(ver 7.8). Los símbolos se definen ya sea usándolos como etiquetas o por definición explicita(EQU). Cada entrada de la tabla de símbolos contiene el símbolo mismo(o un apuntador a el). su valor numérico y a veces otra información(longitud del campo de datos asociado al símbolo, los bits de reubicación, si el símbolo estará o no accesible fuera del procedimiento). • 2.- la tabla de seudoinstrucciones. • Contiene al menos una entrada para cada código de operación simbólico del lenguaje ensamblador. • Cada entrada contiene el código de operación simbólico, dos operandos, el valor numérico del código de operación, la longitud de la instrucción y un número de tipo que divide los códigos de operación en grupos dependiendo del número y el tipo de operandos. • 3.- la tabla de códigos de operación. • Contiene al menos una entrada para cada cada codigo de operación simbolico (mnemonico) del lenguaje ensamblador. • Cada entrada contiene el codigo de operación simbolico, dos operandos, el valor numerico del codigo de operación, la longitud de la instrucción y un numero de tipo que divide los codigos de operación en grupos dependiendo del numero y el tipo de operandos. Figura 7-9. 7.3.3 Segunda pasada • Su función es generar el programa objeto y posiblemente imprimir el listado de ensamblado. • La segunda pasada debe producir cierta información que el enlazador necesita para enlazar procedimientos ensamblados en diferentes momentos para producir un solo archivo ejecutable. 7.3.4 la tabla de símbolos • Aquí se acumula la información generada en la primera pasada(símbolos y su valores), que debe ser consultada durante la segunda pasada. • hay varias formas de organizar la tabla de símbolos. • en todos los casos se intenta simular una memoria asociativa (conceptualmente es un conjunto de pares: "símbolo - valor"). • Dado el símbolo, la memoria asociativa debe producir el valor. • 1.-La técnica más sencilla es implementar la tabla como un arreglo de pares cuyo primer elemento es el símbolo (o apunta a el) y cuyo segundo elemento es el valor (o apunta a él). Enlazado y carga • La traducción completa de un programa fuente requiere dos pasos: • 1.- Compilación o ensamblado de los procedimientos fuente. • 2.- Enlazado de los módulos objeto. • El ensamblador se encarga del primer paso y el segundo corre por cuenta del enlazador. • La traducción de procedimiento fuente a modulo objeto representa un cambio de nivel porque el lenguaje fuente y el lenguaje objetivo tienen diferentes instrucciones y notación. • Enlazador: • Reúne los procedimientos traducidos por separado y los enlaza para que se ejecuten como una unidad llamada programa binario ejecutable. Tareas que realiza el enlazador • Para ejecutar el programa, el enlazador obtiene los módulos objeto de la memoria principal a fin de formar la imagen de programa binario ejecutable. Estructura de un modulo objeto • 1.-Los módulos objeto a menudo contienen 6 partes : • 2.-El modulo es una lista de símbolos definidos en el modulo a los que otros módulos podían hacer referencia. • 3.-Consiste en una lista de los símbolos que se usan en el modulo pero se definen en otros módulos , junto con una lista que indica cuales instrucciones de maquina usan cuales símbolos. • El enlazador necesita una segunda lista para poder insertar las direcciones correctas en las instrucciones que usan símbolos externos. • 4.-Es el código ensamblado y las constantes, en esta parte el modulo del objeto es la única que se cargara en la memoria para ejecutarse. • Las otras 5 partes serán utilizadas por el enlazador y se desecharan antes de que inicie la ejecución. • 5.-Es el diccionario de reubicación. • 6.- Es una indicación de fin de modulo a veces una suma de verificación para detectar errores ocurridos durante la lectura del modulo y la dirección en la que debe iniciarse la ejecución. Tiempo ligado y reubicación dinámica • Hay por lo menos 6 posibilidades de tiempo ligado: • • • • • 1.-cuando se escribe el programa 2.-cuando se traduce el programa 3.-cuando se enlaza el programa pero antes de cargarlo 4.-cuando se carga el programa 5.-cuando se carga un registro base que se usa para direccionamiento • 6.-cuando se ejecuta la instrucción que contiene la dirección. Tiempo ligado y reubicación dinámica • Hay por lo menos 6 posibilidades de tiempo ligado: • • • • • 1.-cuando se escribe el programa 2.-cuando se traduce el programa 3.-cuando se enlaza el programa pero antes de cargarlo 4.-cuando se carga el programa 5.-cuando se carga un registro base que se usa para direccionamiento • 6.-cuando se ejecuta la instrucción que contiene la dirección. • Si una instrucción que contiene una memoria se desplaza después del ligado, será incorrecta. • Si el traductor produce un binario ejecutable como salida, el ligado habrá ocurrido en el momento de la traducción y el programa deberá ejecutarse en la dirección en la que el traductor esperaba que se ejecutara. Enlazado dinámico • Tiene la propiedad de que todos los procedimientos que un programa podría invocar se enlazan antes de que el programa pueda iniciar su ejecución. • Enlazado dinámico: Es una forma mas flexible de enlazar procedimientos compilados por separado es enlazar cada procedimiento en el momento en que se invoca por primera vez.