Generación de código objeto
El generador de
código objeto como lo menciona (Urbina, 2011) transforma el código Intermedio
optimizado en código objeto de bajo nivel. Toma código intermedio y genera
Código objeto para la máquina considerada Es la parte más próxima a la arquitectura
de la Máquina. Habitualmente, se escriben ``a mano´´ desarrollo a medida´ para
cada máquina Específica.
REGISTROS
¿Qué son?
Los registros son la
memoria principal de la computadora. Existen diversos registros de propósito
general y otros de uso exclusivo. Algunos registros de propósito general son
utilizados para cierto tipo de funciones. Existen registros acumuladores, puntero
de instrucción, de pila, etc.
Los registros son
espacios físicos dentro del microprocesador con capacidad de 4 bits hasta 64
bits dependiendo del microprocesador que se emplee.
¿Quiénes lo utilizan?
Antes de nada, para el
desarrollo de esta parte hablaremos indistintamente de registros de activación
o de marcos de pila. Esto se debe a que en la documentación encontrada sobre el
manejo de los registros ebp y esp se hace mención a dicho concepto de marco de
pila. Puesto que el
lenguaje permite recursividad,
los registros de activación
se asignan dinámica mente.
Distribución
La UCP o CPU tiene 14
registros internos, cada uno de ellos de 16 bits (una palabra). Los bits están
enumerados de derecha a izquierda, de tal modo que el bit menos significativo
es el bit 0.
Los registros se pueden
clasificar de la siguiente forma:
Registros de datos:
AX: Registro acumulador.
Es el principal empleado en las operaciones aritméticas.
BX: Registro base. Se
usa para indicar un desplazamiento.
CX: Registro contador.
Se usa como contador en los bucles.
DX: Registro de datos.
Estos registros son de
uso general y también pueden ser utilizados como registros de 8 bits, para
utilizarlos como tales es necesario referirse a ellos como por ejemplo: AH y
AL, que son los bytes alto (high) y bajo (low) del registro AX. Esta nomenclatura
es aplicable también a los registros BX, CX y DX.
Registros de
segmentos:
CS: Registro de segmento
de código. Contiene la dirección de las instrucciones del programa.
DS: Registro segmento de
datos. Contiene la dirección del área de memoria donde se encuentran los datos
del programa.
SS: Registro segmento de
pila. Contiene la dirección del segmento de pila. La pila es un espacio de
memoria temporal que se usa para almacenar valores de 16 bits (palabras).
ES: Registro segmento
extra. Contiene la dirección del segmento extra. Se trata de un segmento de
datos adicional que se utiliza para superar la limitación de los 64Kb del
segmento de datos y para hacer transferencias de datos entre segmentos.
Registros punteros de
pila:
SP: Puntero de la pila.
Contiene la dirección relativa al segmento de la pila.
BP: Puntero base. Se
utiliza para fijar el puntero de pila y así poder acceder a los elementos de la
pila.
Registros índices:
SI: Índice fuente.
DI: Índice
destino.
¿Cuales su aplicación en
la generación de códigos?
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
Ensambladores
Son los encargados de traducir los programas escritos en lenguaje ensamblador a lenguaje máquina.
Compiladores
Son programas que leen el código fuente y lo traducen o convierten a otro lenguaje. Estos programas te muestran los errores existentes en el código fuente.
Etapas del proceso de compilación:
Edición. Esta fase
consiste en escribir el programa empleando algún lenguaje y un editor. Como
resultado nos dará el código fuente de nuestro programa.
Compilación. En
esta fase se traduce el código fuente obtenido en la fase anterior a código
máquina. Si no se produce ningún error se obtiene el código objeto.
En caso de errores el compilador los mostraría para ayudarnos a corregirlos y se procedería a su compilación de nuevo, una vez corregidos.
En caso de errores el compilador los mostraría para ayudarnos a corregirlos y se procedería a su compilación de nuevo, una vez corregidos.
Linkado. Esta fase
consiste en unir el archivo generado en la fase dos con determinadas rutinas
internas del lenguaje, obteniendo el programa ejecutable.
Existen dos tipos de linkados:
Existen dos tipos de linkados:
linkado estático: Los
binarios de las librerías se añaden a nuestros binarios compilados generando el
archivo ejecutable.
Linkado dinámico: no se
añaden las librerías a nuestro binario sino que hará que se carguen en memoria
las librerías que en ese momento se necesiten.
Una vez traducido,
compilado y linkado el archivo esta listo para su ejecución donde también
podrán surgir problemas y fallos, para los cuales tendríamos que volver a
realizar todo el proceso anteriormente citado, de modo que puedan ser
corregidos.
Por este motivo es importante realizar numerosas pruebas en tiempo de ejecución antes de presentar el programa al cliente.
Otro sistema para la ejecución de nuestro código fuente es mediante el uso de intérpretes (estos no se encontrarían dentro de los traductores).
Intérpretes
Los intérpretes realizan la traducción y ejecución de forma simultanea, es decir, un intérprete lee el código fuente y lo va ejecutando al mismo tiempo.
Las diferencias entre un compilador y un intérprete básicamente son:
Por este motivo es importante realizar numerosas pruebas en tiempo de ejecución antes de presentar el programa al cliente.
Otro sistema para la ejecución de nuestro código fuente es mediante el uso de intérpretes (estos no se encontrarían dentro de los traductores).
Intérpretes
Los intérpretes realizan la traducción y ejecución de forma simultanea, es decir, un intérprete lee el código fuente y lo va ejecutando al mismo tiempo.
Las diferencias entre un compilador y un intérprete básicamente son:
Un programa compilado
puede funcionar por si solo mientras que un código traducido por un intérprete
no puede funcionar sin éste.
Un programa traducido
por un intérprete puede ser ejecutado en cualquier máquina ya que, cada vez que
se ejecuta el intérprete, tiene que compilarlo.
Un archivo compilado es
mucho más rápido que uno interpretado.