Generación de Código Objeto
Generación de Código Objeto
Generación de Código Objeto
LENGUAJES
AUTÓMATAS
Unidad 9
GENERACIÓN DE
CÓDIGO OBJETO
Unidad 10
OPTIMIZACIÓN
Material compilado con fines
académicos, se prohíbe su
reproducción total o parcial sin
la autorización de cada autor.
Temario
Unidad 9.
Generación de código objeto
9.1. Registros
9.2. Lenguaje ensamblador
9.3. Lenguaje máquina
9.4. Administración de memoria
Unidad 10.
Optimización
10.1. Tipos de optimización
10.1.1. Locales
10.1.2. Ciclos
10.1.3. Globales
10.1.4. De mirilla
10.2. Costos
10.2.1. Costo de ejecución. (memoria, registros, pilas)
10.2.2. Criterios para mejorar el código
10.2.3. Herramientas para el análisis del flujo de datos
2
UNIDAD 9
GENERACIÓN DE CÓDIGO OBJETO
Asimismo, la página It-brain (s.f.) manifiesta que el código fuente escrito en un len-
guaje de nivel superior se transforma en un lenguaje de nivel inferior que origina un
código de objeto de nivel inferior, el cual debería presentar las siguientes propieda-
des mínimas:
3
Figura 1. Esquema de generación de código objeto. Fuente: Vilar (2010, p. 2).
9.1.
Registros
4
• Registros de propósito general (General Purpose Registers, GPRs): pueden
guardar tanto datos como direcciones y la mayor parte de las computadoras
modernas usa GPR. Además, son fundamentales en la arquitectura de von
Neumann.
• Registros de propósito específico: guardan información específica del estado
del sistema, como el puntero de pila o el registro de estado.
En resumen, operar sobre registros es más rápido y eficiente que operar sobre me-
moria, por lo que una correcta selección de registros reduce el número de instruc-
ciones y el número de referencias a la memoria.
9.2.
Lenguaje ensamblador
Bautista, Rojas y López (2015) expresan que el lenguaje ensamblador (assembly lan-
guage, ASM) traduce un código de bajo nivel a un código ejecutable directamente
por la máquina para la que se ha generado. El lenguaje ensamblador consiste en
un conjunto de mnemónicos que representan instrucciones básicas para las com-
putadoras, microprocesadores, microcontroladores y otros circuitos integrados pro-
gramables. Además, implementa una representación simbólica de los códigos de
máquina binarios y otras constantes necesarias para programar una arquitectura de
procesador y constituye la representación más directa del código máquina específico
para cada arquitectura legible por un programador.
Valverde (2017) menciona que los elementos del lenguaje ensamblador son los si-
guientes:
5
Figura 2. Elementos del lenguaje ensamblador. Fuente: Valverde (2017).
Pero, ¿cómo se genera el código objeto a través del lenguaje ensamblador? El pro-
grama lee un archivo escrito en lenguaje ensamblador y sustituye cada uno de los
códigos mnemotécnicos por su equivalente código máquina. La tabla 1 muestra un
ejemplo de diferentes mnemotécnicos y su respectiva sustitución a código máquina.
Olivares (2012b) e Infante (2013) sostienen que los ensambladores se pueden clasi-
ficar en dos tipos:
6
Finalmente, empleando las palabras del Instituto Tecnológico de Piedras Negras (s.f.):
Una de las principales ventajas del uso del ensamblador es que se encar-
ga de administrar la creación de memoria y el paso de parámetros para el
usuario de manera transparente. Además, permite acceder directamente a
los recursos de la máquina para un mejor desempeño.
Por tanto, “producir un ensamblador como código objeto hace más fácil el proceso
de generación, pues se pueden generar instrucciones simbólicas y llamadas a ma-
cros de ensamblador” (Sánchez y Valverde, 1989).
9.3.
Lenguaje máquina
Olivares (2012b) argumenta que “el lenguaje máquina sólo es entendible por las
computadoras. Se basa en una lógica binaria de 0 y 1, generalmente implementada
por mecanismos eléctricos”. Por su parte, como señalan Costa y Vivó (s.f.):
7
Por otro lado, la Universidad Nacional Autónoma de México (s.f.) manifiesta que “el
lenguaje máquina es específico de cada máquina o arquitectura de la máquina, aun-
que el conjunto de instrucciones disponibles pueda ser similar entre ellas”.
Sánchez y Valverde (1989, p. 159) plantean que el código máquina puede producirse
desde dos enfoques diferentes:
• Código máquina absoluto. Este código tiene la ventaja de poder cargar y eje-
cutar el programa inmediatamente. En aplicaciones comerciales no se suele
usar esta opción, aunque sí se utiliza en trabajos experimentales y especiales.
• Código máquina reubicable. Este código, también llamado módulo objeto,
es la solución adoptada por la mayoría de los compiladores comerciales, ade-
más permite tener módulos que se compilan por separado, aunque este tipo
precisa de un enlazador (linker) y de un cargador (ver figura 3 en el subtema
9.4. Administración de memoria).
9.4.
Administración de memoria
8
Para que un programa se ejecute sobre un sistema operativo, es necesaria
la existencia de un cargador que suministra al programa un bloque contiguo
de memoria sobre el cual ha de ejecutarse. Por tanto, el código del pro-
grama resultante de la compilación debe organizarse de forma que haga
uso de este bloque, por lo que el compilador debe incorporar al programa
objeto el código necesario para ello (p. 293).
9
Las técnicas de administración de memoria durante la ejecución del programa
difieren de unos lenguajes a otros, e incluso de unos compiladores a otros. En el caso
de lenguajes de bajo nivel, la figura 4 muestra de manera general cómo los registros
(PC, SP, etc.) son cargados en la memoria.
10
UNIDAD 10
OPTIMIZACIÓN
10.1.
Tipos de optimización
11
10.1.1.
Locales
La figura 5 muestra un ejemplo de cómo puede ser la optimización local de una fun-
ción. En este caso, la función de ejemplo recibe un entero al que le debe sumar 10
unidades y regresar el resultado. En el código de la parte izquierda de la figura se
puede observar que se han declarado dos variables extras (y, z), las cuales sirven,
para almacenar el valor de 10 y el valor final. Por otro lado, en la parte derecha de la
figura se puede visualizar que basta con regresar el mismo valor aumentado en 10,
con lo cual, el código se reduce significativamente.
12
10.1.2.
Ciclos
Los ciclos o bucles son una de las partes más esenciales en el rendimiento
de un programa dado que realizan acciones repetitivas, y si dichas acciones
están mal realizadas, el problema se hace N veces más grandes. La mayoría
de las optimizaciones sobre ciclos tratan de encontrar elementos que no
deben repetirse en un ciclo.
10.1.3.
Globales
Citando a Olivares (2012a), “en algunos casos es mejor mantener variables globales
para agilizar los procesos (el proceso de declarar variables y eliminarlas toma su
tiempo) pero consume más memoria. Algunas optimizaciones incluyen utilizar como
variables registros del CPU, emplear instrucciones en ensamblador, etc.”.
13
10.1.4.
De mirilla
En conclusión, Olivares (2012a) afirma que “la optimización es un proceso que busca
minimizar o maximizar alguna variable de rendimiento, generalmente tiempo, espacio,
procesador, etc.”. Para lograrlo se pueden llevar a cabo diferentes tipos de optimiza-
ción, los cuales dependerán del lugar (en el código) donde se realizará.
10.2.
Costos
Los costos son el factor más importante a tomar en cuenta a la hora de op-
timizar, ya que en ocasiones la mejora obtenida puede no verse reflejada
en el programa final, pero sí ser perjudicial para el equipo de desarrollo. La
optimización de una pequeña mejora tal vez tenga una pequeña ganancia
en tiempo o en espacio, pero se invierte mucho tiempo al generarla.
14
10.2.1.
Costo de ejecución (memoria, registros, pilas)
Por otra parte, Badía, Martínez, Morales y Sanchiz (2012, p. 9) manifiestan que “la
ejecución de un algoritmo en una máquina supone el uso de una serie de recursos:
espacio y tiempo”. Badía et al. (2012, p. 9) expresan que el coste espacial hace refe-
rencia a la cantidad de memoria consumida, mientras que el coste temporal alude
al tiempo que se necesita para ejecutar el programa, por ejemplo, el tiempo en que
tarda en ejecutar ciertas operaciones.
Badía et al. (2012) declaran que existen dos métodos que se utilizan para realizar un
análisis de costos:
10.2.2.
Criterios para mejorar el código
Como lo hace notar Olivares (2012a), “la mejor manera de optimizar el código es
hacer ver a los programadores que optimicen su código desde el inicio”, utilizando
15
algunos de los tipos de optimización que se presentaron en la sección 10.1 Tipos de
optimización. Sin embargo, Olivares (2012a) revela que “el problema, como se men-
cionó anteriormente, radica en que el costo podría ser muy grande, debido a que
tendría que codificar más o hacer su código más legible”.
10.2.3.
Herramientas para el análisis del flujo de datos
Olivares (2012a) plantea que los depuradores y los desambladores son algunas de
las herramientas que permiten analizar los flujos de datos. A continuación, los des-
cribimos brevemente (Ruiz, 2019):
16
En conclusión, la optimización y los costos son dos tareas que están relacionadas.
Por un lado, la optimización, teóricamente, nos ayudará a tener un código “limpio” en
cuanto al manejo de instrucciones, ciclos, etc., lo cual generará un mejor rendimiento
y aprovechamiento de los recursos (memoria, por ejemplo) de la maquina destino.
Sin embargo, en la práctica puede ocurrir que la optimización genere un costo mayor
a que si no estuviera optimizado. Por lo tanto, es importante realizar un análisis de
costo para cuantificar las mejoras obtenidas a partir de la optimización.
17
Referencias.
Badía, J., Martínez Salvador, B., Morales Escrig, A. y Sanchiz Martí, J. M. (01 de
junio de 2012). Tema 3. Análisis de costes. Recuperado de: http://repositori.uji.es/
xmlui/bitstream/handle/10234/119885/tema3.pdf?sequence=1&isAllowed=y
Bautista, J., Rojas, C. y López, A. (2015). Metodología para la enseñanza de sistemas digitales
mediante lenguaje ensamblador. Revista de Sistemas y Gestión Educativa, 2 (5), 1003-
1009. Recuperado de: https://www.ecorfan.org/bolivia/researchjournals/Sistemas_y_
Gestion_Educativa/vol2num5/Sistemas_y_Gestion_Educativa_Vol2_N5_4.pdf
Candela Solá, S. C., García Rodríguez, R., Quesada Arencibia, A., Santana Pérez,
F. J., Santos Espino, J. M. (2007). Fundamentos de sistemas operativos: teoría
y ejercicios resueltos. España: Editorial Paraninfo. Recuperado de: https://books.
google.com.mx/books?id=fRK3lbTrNy4C&printsec=frontcover#v=onepage&q=la%20
memoria%20es%20el%20recurso&f=false
Costa, R. y Vivó, J. (s.f.). Lenguaje máquina, ensamblador y de alto nivel. Recuperado de:
http://cv.uoc.edu/moduls/XW02_79049_00373/web/main/m4/v2_3.html
It-brain (s.f.). Diseño del compilador: generación de código. Recuperado de: https://
es.it-brain.online/tutorial/compiler_design/compiler_design_code_generation/
18
Magaña, M. (03 de abril de 2014). Funciones de administración de memoria. Recuperado de:
https://es.slideshare.net/MiguelMagaa2/funciones-de-administracion-de-memoria
Ruiz, A. (21 de octubre de 2019). Lenguajes y autómatas II. Recuperado de: https://
alexisruizclemente1998.blogspot.com/2019/10/323-herramientas-para-el-analisis-del.html
19