1.
Compilación:
Al diseñar o programar un sistema,
software, aplicación, procede de varias fases de realización en donde una de
sus importantes se encuentra la compilación proceso al que el compilador debe analizar
el texto de nuestro programa fuente, comprobar que no contiene errores y
producir como salida un fichero con la traducción de nuestro código a conjunto
de instrucciones de nuestro procesador.
A la hora de compilar nuestro proyecto
lo que haremos será procesar cada uno de estos módulos por separado,
diciéndole al compilador que tenga en cuenta que ninguno de estos módulos es un
programa por sí mismo, sino una parte del mismo. Lo que hará el compilador será
producir como salida una serie de ficheros
objeto. Estos ficheros son la traducción a binario de cada uno de
nuestros módulos. Sin embargo ninguno de ellos conforma un ejecutable por sí
mismo, ya que ninguno contiene el código completo de nuestro programa.
Ningún proyecto de programación serio
está compuesto hoy en día por un solo archivo fuente, sino más bien todo lo
contrario. Es conveniente que cualquier programa que pase de unos cientos de
líneas sea dividido en una serie de módulos que faciliten la legibilidad y el
mantenimiento del código.
2.
Fases de la Compilación:
Un lenguaje de alto
nivel (compilado) para ejecutarlo como programa es necesario de una traducción o
de las fases para la compilación las cuales se dividen en 3 fases:
a)
Compilación:
En esta fase
se convierte el código fuente a lenguaje máquina, pero no se asignan direcciones
absolutas de memoria, pues no se sabe con exactitud a qué lugar va a ir el
programa, en su lugar se colocan informaciones para el programa enlazador. Se
divide en varias etapas:
a.
Pre procesamiento: no se genera código objeto, básicamente lo que
se hace son modificaciones al código fuente (se expanden las macros, pueden
eliminarse ciertos módulos de programa -compilación condicional-, pueden
añadirse librerías externas, ...) En C las instrucciones para el preprocesador
vienen precedidas por # (#include --> incluye un fichero, #define
--> (definición de macro) realiza una macrosustitución, #if, #ifdef,
#ifndef --> realiza una compilación condicional del bloque).
b.
Generación de código
intermedio: se genera un pseudo-código ensamblador, es
decir, independiente de la máquina. Es un lenguaje ensamblador muy genérico, no
válido para ningún mP, que elimina todas las complejidades de este lenguaje.
c.
Generación de código objeto: El código objeto ya es
código máquina, pero ciertas direcciones de memoria todavía no están resueltas
y han sido sustituidas por etiquetas (nombres), pues todavía no sabemos
en que lugar de la memoria se va a cargar cada módulo del programa.
Entre medias se pueden hacer diversas optimizaciones, bien para que se
ejecute más rápido, ocupe menos espacio, compilar al lenguaje de oros
microprocesadores (compiladores cruzados), obtener el código óptimo para mi
microprocesador o hacerlo más compatible con viejos procesadores.
b) Enlace
Si nuestro
programa es muy extenso podemos descomponerlo en módulos que se compilan y
prueban por separado, pero para construir el programa completo es necesario
enlazarlos. Estos módulos también pueden ser librerías estáticas, que debemos
enlazar antes de poder ejecutarlo (las librerías dinámicas se enlazan mientras
se ejecuta el programa, es decir, se cargan en la memoria asignada al programa
cuando se está ejecutando).
Módulo objeto 1
módulo objeto 2 ---> programa enlazador
--->
programa
ejecutable
...
(linkage)
módulo objeto N
c) Ejecución:
Para ejecutar
un programa es necesario cargarlo en
memoria. El caso más sencillo es cuando un programa cabe completamente
en memoria, si el programa es demasiado grande se tendrá que dividir en segmentos,
que se van cargando y descargando según necesidad.
Un programa .com se ejecuta en
un único segmento, por tanto no puede exceder los 64 k. Un programa .exe tiene asignados varios segmentos
(por lo menos cuatro: uno para el código, otro para los datos, para la pila, y
un segmento extra).
Hoy en día, con los IDE
(entornos de desarrollo integrado)
todas estas fases se realizan de manera automática al pulsar un botón. Nosotros
lo único que tenemos que hacer es trabajar en un proyecto donde se
encuentran codificados todos los programas fuente (en uno o varios módulos).