Sei sulla pagina 1di 34

Compiladores, intérpretes

y máquinas virtuales
Cuando aprendemos a programar, normalmente escogemos o nos
imponen un determinado lenguaje de programación. Una de las
primeras distinciones que es interesante conocer acerca de nuestro
lenguaje es si el lenguaje se compila o se interpreta.
La confección de un programa se realiza
escribiendo una serie de órdenes o instrucciones
que siguen las normas de un lenguaje de
programación. Estas órdenes las escribimos en
ficheros de texto plano, utilizando algún editor de
textos más o menos sencillo, o bien alguno de los
editores especializados para programación
A estos ficheros de texto les llamamos fuente. (del inglés source. A
menudo se utilizan expresiones como código fuente, ficheros fuente,
etc.).
Sin embargo, sabemos que la CPU sólo entiende su propio lenguaje,
que normalmente es extraordinariamente sencillo comparado el
lenguaje de programación que estamos aprendiendo. El lenguaje de la
CPU es el código máquina (del inglés machine code). El código
máquina son secuencias binarias que la CPU ejecuta como
instrucciones sencillas
Los humanos expresamos la dinámica de un programa mediante un
lenguaje de los llamados de "alto nivel". Estos son lenguajes como C#,
Java, Visual Basic, Delphi, Python, etc... casi cualquiera de los nombres
que conoces.
Decimos que un lenguaje tiene un nivel más bajo cuanto más parecido
es en su expresión al código máquina y al funcionamiento de la CPU, y
de un nivel más alto cuanto más ajeno es al funcionamiento de la CPU
y más se acerca a la forma de razonar humana.
Compilar

La compilación consiste en tomar los ficheros fuente que conforman un


programa y, línea por línea, traducir cada instrucción de alto nivel por
varias instrucciones en código máquina que realicen lo que la
instrucción de alto nivel expresa.
Si se repite esa traducción para todas las líneas del código fuente,
obtendremos un conjunto de instrucciones máquina. Grabando esas
instrucciones máquina en un fichero que contiene una estructura
interna que un determinado sistema operativo es capaz de entender,
obtenemos un fichero binario ejecutable, o simplemente, "un
ejecutable".
El encargado de realizar esta traducción es un tipo de programa
llamado compilador. En su funcionamiento más básico, un compilador
acepta uno o más ficheros fuente y si no contienen errores sintácticos
produce un fichero binario ejecutable, que un sistema operativo será
capaz de cargar en memoria principal y pedir a la CPU que lo ejecute.
A menudo se compara a un compilador con un traductor de idiomas.
Imagina un libro escrito en inglés. Para publicar su versión en español,
una persona que conoce las reglas de los dos idiomas y dispone de la
técnica para expresarse en ambos va leyendo el libro en inglés frase a
frase y va escribiendo su equivalente en español.
Compilación nativa y compilación cruzada

• Es habitual que un desarrollador utilice para programar una


determinada plataforma... por ejemplo, el lenguaje C++ sobre una
máquina con Windows. Normalmente, el compilador generará código
compilado que la CPU puede entender, y que se puede ejecutar en la
misma máquina con la participación de un sistema operativo
Windows.
• No obstante, a veces, se desarrolla en una plataforma y se compila
para que los programas sean ejecutados en otra. A esto se le llama
"compilación cruzada".
Interpretar
El proceso de interpretación es bastante diferente al de compilación,
pero su resultado debería ser similar: la ejecución de un programa.
El encargado de hacer esto es un programa llamado intérprete. A
diferencia del compilador, el intérprete de un lenguaje no produce una
traducción a código máquina. El intérprete intenta realizar "al vuelo" lo
que se expresa en los ficheros fuente. El intérprete contiene en su
interior miles de porciones de código máquina, que combinándolas
adecuadamente pueden realizar las mismas tareas que expresa una
orden escrita en el lenguaje de alto nivel.
• Cuando un programa es interpretado, el proceso que se sigue es el
siguiente: el intérprete obtiene una instrucción del fichero fuente y la
realiza inmediatamente. Para ello, ejecuta en secuencia varias de esas
porciones de código máquina que comentábamos antes, y que residen
en el interior del intérprete. Cuando la CPU termina la ejecución de esa
secuencia, el resultado es que la CPU habrá hecho lo que la línea de
código fuente expresaba.
• Repitiendo esta secuencia para todas las líneas, el intérprete realiza lo
que los ficheros fuente expresan... es decir, ejecuta el programa.
A menudo, se compara al intérprete con un traductor simultáneo de
idiomas. Por ejemplo, cuando vemos en la tele a alguna personalidad
expresándose en otro idioma y un traductor simultáneo nos traduce lo
que esta persona dice "al vuelo". Esta persona no espera a que el
discurso de la personalidad concluya para traducirlo todo de golpe, sino
que cada vez que este traductor ha entendido un concepto, lo traduce
al español y lo expresa.
Diferencias entre compilar e interpretar

• La opción de compilar o interpretar no está siempre disponible.


Algunos lenguajes típicamente se compilan y otros típicamente se
interpretan. En muy pocas ocasiones podemos optar por una u otra
indistintamente.
• Por ejemplo, programas escritos en lenguajes como C o Pascal
prácticamente siempre se compilan, y otros como PHP o Python
prácticamente siempre se interpretan.
El enfoque de Máquina Virtual

La filosofía de la máquina virtual es la siguiente: el código fuente se


compila, detectando los errores sintácticos, y se genera una especie de
ejecutable, con un código máquina dirigido a una máquina imaginaria,
con una CPU imaginaria. A esta especie de código máquina se le
denomina código intermedio, o a veces también lenguaje
intermedio, p-code, o byte-code (según quién nos lo cuente).
Como esa máquina imaginaria no existe, para poder ejecutar ese
ejecutable, se construye un intérprete. Este intérprete es capaz de leer
cada una de las instrucciones de código máquina imaginario y
ejecutarlas en la plataforma real. A este intérprete se le denomina el
intérprete de la máquina virtual.
¿Y para qué todo este montaje?

Pues esta pregunta puede responderse desde varios puntos de vista,


pero se puede afirmar que este esquema aporta muchas de las
ventajas de la compilación y la interpretación, deshaciéndose de
algunos inconvenientes.
Principalmente se pueden recalcar:
Portabilidad y rapidez: El código intermedio ya está libre de errores
sintácticos, y es un código muy sencillo (al estilo del código máquina).
Si existe un intérprete para este código en distintas plataformas, el
mismo código se puede ejecutar en cada una de ellas. Además, la
construcción de este intérprete será relativamente sencilla y su
ejecución más rápida, ya que no ha de comprobar la sintaxis.
Estabilidad: El código intermedio no es ejecutado por una CPU real
directamente, sino por una CPU virtual: realmente, por el intérprete de
la máquina virtual, que es un programa y no un chip real. Esto permite
un mayor control sobre este código, facilitando la labor de impedir que
un código descontrolado afecte a la estabilidad de la plataforma real.
Para entender algo mejor este concepto, podemos fijarnos, por
ejemplo, en el lenguaje JAVA. Imaginemos que disponemos de dos
ordenadores: uno con un sistema operativo Windows y un procesador
intel de 64 bits y el otro con un sistema operativo Linux y un
procesador AMD de 32 bits.
• En el primer ordenador instalamos un compilador de Java y una
máquina virtual de Java específicos para Windows 64 bits.

• En el segundo hacemos lo mismo, pero con un compilador y máquina


virtual específicos para Linux 32 bits.
• Confeccionamos un programa sencillo (por ejemplo, que escriba "Hola
Mundo" por la pantalla) escrito en Java en el primer ordenador y lo
compilamos, generando un ejecutable intermedio. Si utilizamos la
máquina virtual del primer ordenador para ejecutar ese código
intermedio, comprobaremos que el programa escribe, en efecto "Hola
Mundo" por la pantalla.
• Si cogemos ese ejecutable intermedio lo llevamos tal cual a la segunda
máquina, podremos utilizar la máquina virtual instalada allí para
ejecutarlo, y comprobaremos que el resultado es exactamente el mismo:
"Hola Mundo".
Ventajas que tiene este enfoque de máquina virtual de proceso
comparado con la compilación o la interpretación. Vamos a retomar la
tabla anterior, pero añadiendo la máquina virtual.
Compilar Interpretar Máquina virtual

-Genera una especie de ejecutable, pero


-Genera un ejecutable -No genera un ejecutable portable entre plataformas, dirigido a una CPU
imaginaria.

-Se realiza una sola traducción a código


-El proceso de traducción se realiza una sola -El proceso de traducción se realiza en cada
intermedio, y una interpretación muy rápida
vez ejecución
del código intermedio en cada ejecución.

-La ejecución es muy rápida debido a que el -La ejecución es más lenta, ya que para cada -La ejecución no es tan rápida como en la
programa ya ha sido traducido a código línea del programa es necesario realizar la compilación tradicional ni tan lenta como en la
máquina traducción intepretación
-No hay ejecutable, así que si existe un
-El ejecutable va dirigido a una plataforma
intérprete para una plataforma concreta, el
concreta (una CPU, un sistema operativo, y
programa se podrá ejecutar en ambas.
quizá alguna otra consideración), siendo
Típicamente, los programas interpretados
prácticamente imposible portarlo a otra. En -El ejecutable va dirigido a una CPU
son mucho más portables que los
ocasiones, si existe un compilador para otra imaginaria. Se puede transportar a una
compilados, ya que suelen existir
plataforma, se puede recompilar el plataforma para la cual exista una "máquina
intérpretes del mismo lenguaje en distintas
programa, aunque normalmente esto virtual" (el intérprete de código intermedio)
plataformas. Los programas que se van a
plantea serias dificultades. Los programas
interpretar no suelen ser muy dependientes
que se van a compilar suelen estar muy
de su plataforma de destino, siendo más
ligados a la plataforma de destino.
portables.
Los lenguajes compilados suelen -Los lenguajes interpretados no suelen -La plataforma de destino es virtual. Así
proporcionar al programador ser muy dependientes de la plataforma pues, los programas son dependientes de
mecanismos más potentes y flexibles, a de destino, pero en contrapartida suelen esta plataforma virtual, que es emulada
costa de una mayor ligazón a la ser menos flexibles y potentes que los luego sobre plataformas reales por la
plataforma. compilados. "maquina virtual".

-Una vez compilado el programa, el


-El código fuente es necesario en cada
código fuente no es necesario para -El código fuente no es necesario para la
ejecución, así que no puede permanecer
ejecutarlo, así que puede permanecer en ejecución, sólo el código intermedio.
en secreto
secreto si se desea.
-Los errores sintácticos se detectan
durante la ejecución, ya que traducción
y ejecución se van haciendo
Los errores sintácticos se detectan
simultáneamente. Algún error
durante la compilación. Si el fuente -Los errores sintácticos se detectan
sintáctico podría quedar enmascarado,
contiene errores sintácticos, el durante la compilación.
si para una ejecución concreta no es
compilador no producirá un ejecutable.
necesario traducir la línea que lo
contiene. (Algunos intérpretes son
capaces de evitar esto)
-Un programa compilado puede, por
error, afectar seriamente a la
-Un programa interpretado con un -Un programa con un
estabilidad de la plataforma,
comportamiento torpe normalmente comportamiento torpe es ejecutado
comprometiendo la ejecución de los
puede ser interrumpido sin dificultad, sobre la máquina virtual, que tiene un
otros procesos, por ejemplo,
ya que su ejecución está bajo el control absoluto sobre él, con lo que
acaparando la CPU, la memoria o
control del intérprete, y no sólo del no se suele comprometer la
algún otro recurso, siendo a veces
sistema operativo. estabilidad de la plataforma real.
complicado para el sistema operativo
interrumpir su ejecución.
En definitiva, compilación e interpretación son las opciones típicas para
los lenguajes de programación más tradicionales, presentando cada una
de ellas sus ventajas e inconvenientes. El enfoque más moderno es el
de máquina virtual, en el que se realiza una compilación cuya plataforma
de destino es una máquina imaginaria o virtual, y el ejecutable
intermedio es posteriormente interpretado en cada ejecución.

Potrebbero piacerti anche