UNIDAD I.- INTRODUCCIÓN A SOFTWARE DE
SISTEMAS
- ¿QUÉ ES EL SOFTWARE DE
SISTEMAS?
Software son las instrucciones electrónicas que
van a indicar a la PC que es lo que tiene que hacer.
También se puede decir que son los programas usados
para dirigir las funciones de un
sistema de
computación o un hardware(1).
El software es el conjunto de instrucciones que las
computadoras
emplean para manipular datos. Sin el
software, la computadora
sería un conjunto de medios sin
utilizar. Al cargar los programas en una computadora,
la máquina actuará como si recibier a una educación
instantánea; de pronto "sabe" cómo pensar y
cómo operar. El Software es un conjunto de programas,
documentos,
procedimientos, y rutinas asociados con la
operación de un sistema de computo. Distinguiéndose
de los componentes físicos llamados hardware.
Comúnmente a los programas de computación se les
llama software; el software asegura que elprograma o sistema
cumpla por completo con sus objetivos,
opera con eficiencia, esta
adecuadamente documentado, y suficientemente sencillo de operar.
Es simp lemente el conjunto de instrucciones individuales que se
le proporciona al microprocesador
para que pueda procesar los datos y generar los resultados
esperados. El hardware por si solo no puede hacer nada, pues es
necesario que exista el software, que es el conjunto de
instrucciones que hacen funcionar al hardware(2).
(1 Dir. http://www.conozca
su pc.com.ar/soft1.htm) definición de software de
sistemas
(2 Dir.
http://www.salonhogar.com/ciencias/tecnologias/computadoras/definicion
software.htm)
Por que estudiarlo
El software para uso general ofrece la estructura
para un gran número de aplicaciones empresariales,
científicas y personales. El software de hoja de
cálculo, de diseño
asistido por computadoras (CAD), de procesamiento de texto, de
manejo de Bases de Datos,
pertenece a esta categoría. La mayoría de software
para uso general se vende como paquete; es decir, con software y
documentación orientada al usuario (
manuales de
referencia, plantillas de teclado y
demás )(1).
(1 Dir.
http://www.salonhogar.com/ciencias/tecnologias/computadoras/softwaredeusogeneral.htm)
Diferencias con el software de
aplicación
El software de
aplicación esta diseñado y escrito para
realizar tareas específicas personales,,empresariales o
científicas como el procesamiento de nóminas,
la
administración de los recursos
humanos o el control de
inventarios. Todas éstas aplicacion es procesan datos
(recepción de materiales) y
generan información (registros de
nómina). para el usuario. Sistemas
Operativos Un sistema Operativo
(SO) es en sí mismo un programa de
computadora. Sin embargo, es un programa muy especial,
quizá el más complejo e importante en una
computadora. El SO despierta a la computadora y hace que
reconozca a la CPU, la memoria, el
tecla do, el sistema de vídeo y las unidades de disco.
Además, proporciona la facilidad para que los usuarios se
comuniquen con la computadora y sirve de plataforma a partir de
la cual se corran programas de aplicación. Cuando
enciendes una computadora, lo primero que ésta hace es
llevar a cabo un autodiagnóstico llamado autoprueba de
encendido (Power On Self Test, POST).
Durante la POST, la computadora indentifica su memoria, sus
discos, su teclado, su sistema de vídeo y cualquier otro
dispositivo conectado a ella. Lo siguiente que la computadora
hace es buscar un SO para arrancar (boot).
Una vez que la computadora ha puesto en marcha su
SO, mantiene al menos parte de éste en su memoria en todo
momento. Mientras la computadora esté encendida, el SO
tiene 4 tareas principales.
1.Proporcionar ya sea una interfaz de línea de
comando o una interfaz gráfica al usuario, para que este
último se pueda comunicar con la computadora. Interfaz de
línea de comando: tú introduces palabras y
símbolos desde el teclado de la computadora, ejemplo, el
MS-DOS.Interfaz gráfica del Usuario (GUI),
seleccionas las acciones
mediante el uso de un Mouse para
pulsar sobre figuras llamadas iconos o seleccionar opciones de
los menús.
2.Administrar los dispositivos de hardware en la
computadora. Cuando corren los programas, necesitan utilizar la
memoria, el monitor, las
unidades de disco, los puertos de Entrada/Salida (impresoras,
módems, etc). El SO sirve de intermediario entre los
programas y el hardware.
3.Administrar y mantener los sistemas de archivo de
disco. Los SO agrupan la información dentro de
compartimientos lógicos para almacenarlos en el disco.
Estos grupos de
información son llamados archivos. Los
archivos pueden contener instrucciones de programas o
información creada por el usuario. El SO mantiene una
lista de los archivos en un disco, y nos proporciona las herramientas
necesarias para organizar y manipular estos archivos.
4.Apoyar a otros programas. Otra de las funciones
importantes del SO es proporcionar servicios a
otros programas. Estos servicios son similares a aquellos que el
SO proporciona directamente a los usuarios. Por ejemplo, listar
los archivos, grabarlos a disco, eliminar archivos, revisar
espacio disponible, etc. Cuando los programadores escriben
programas de computadora, incluyen en sus programas instrucciones
que solicitan los servicios del SO. Estas instrucciones son
conocidas como "llamadas del sistema" (1)
(1 Dir.
http://www.salonhogar.com/ciencias/tecnologias/computadoras/software
de aplicaciones.htm)
2.1 El Nivel Del Lenguaje
Ensamblador
Dicho nivel difiere considerablemente de los niveles de
microprogramación, de maquina convencional y del sistema
operativo, debido a que se implanta por traducción y no
por interpretación(1).
2.2 Funciones De Un Ensamblador
La tarea fundamental de un ensamblador es
traducir un programa en lenguaje de ensamblador al código
correspondiente en lenguaje de máquina. En esencia, el
ensamblador debe realizar las siguientes tareas:
1. Convertir los códigos ("opcode" o
mnemónicos: ej. LDA, STX) a su código equivalente
en lenguaje de máquina
2. Convertir los operandos simbólicos (las
etiquetas o variables) en
las direcciones correspondientes de los operandos
3. Construir las instrucciones en lenguaje de
máquina en el formato apropiado
4. Convertir las constantes definidas en el programa en
su verdadera representación
5. Escribir el "listing" en lenguaje de ensamblador con
el código en lenguaje de máquina
correspondiente
6. Procesar las directrices al ensamblador (las
directrices son instrucciones o comandos
dirigidos al ensamblador, que éste procesa y ejecuta al
hallarlos en el programa en lenguaje de ensamblador; estas
directrices no se traducen a lenguaje de máquina, si no
que el ensamblador ejecuta alguna acción, como reservar
memoria para variables, entre otras)
(Org. De Computadoras Un Enfoque Estructurado,
Tanenbaum, P.445)
En general, la mayoría de las tareas se puede
realizar si se recorre el programa línea por línea.
Pero surge una dificultad si se trata de traducir una
instrucción cuyo operando está definido
más abajo en el programa. Si esto ocurre, el
ensamblador desconoce la dirección del operando y la
instrucción no se podría ensamblar(1).
2.3 Tipos De Ensambladores
Aunque todos los ensambladores realizan
básicamente las mismas tareas, podemos clasificarlos de
acuerdo a características.
Así podemos clasificarlos en:
Ensambladores Cruzados
(Cross-Assembler).
Se denominan así los ensambladores que se
utilizan en una computadora que posee un procesador
diferente al que tendrán las computadoras donde va a
ejecutarse el programa objeto producido.
El empleo de este
tipo de traductores permite aprovechar el soporte de medios
físicos (discos, impresoras, pantallas, etc.), y de
programación que ofrecen las máquinas
potentes para desarrollar programas que luego los van a ejecutar
sistemas muy especializados en determinados tipos de
tareas.
Ensambladores Residentes.
Son aquellos que permanecen en la memoria principal de
la computadora y cargan, para su ejecución, al programa
objeto producido. Este tipo de ensamblador tiene la ventaja de
que se puede comprobar inmediatamente el programa sin necesidad
de transportarlo de un lugar a otro, como se hacía en
cross-assembler, y sin necesidad de programas
simuladores.
Sin embargo, puede presentar problemas de
espacio de memoria, ya que el traductor ocupa espacio que no
puede ser utilizado por el programador. Asimismo, también
ocupará memoria el programa fuente y el programa objeto.
Esto obliga a tener un espacio de memoria relativamente amplio.
Es el indicado para desarrollos de pequeños sistemas de
control y sencillos automatismo empleando microprocesadores(1).
(1)Dir. (http://www.usc.clu.edu/comweb/cco220/ensambladores.htm)
Ensambladores
Dir.(http://mx.geocities.com/laura_40cruz/idicelau.htm)
Página de la arquitectura de
las computadoras
La ventaja de estos ensambladores es que permiten
ejecutar inmediatamente el programa; la desventaja es que deben
mantenerse en la memoria principal tanto el ensamblador como el
programa fuente y el programa objeto.
Macroensambladores.
Son ensambladores que permiten el uso de
macroinstrucciones (macros). Debido a
su potencia,
normalmente son programas robustos que no permanecen en memoria
una vez generado el programa objeto. Puede variar la complejidad
de los mismos, dependiendo de las posibilidades de
definición y manipulación de las
macroinstrucciones, pero normalmente son programas bastantes
complejos, por lo que suelen ser ensambladores
residentes.
Microensambladores.
Generalmente, los procesadores
utilizados en las computadoras tienen un repertorio fijo de
instrucciones, es decir, que el intérprete de las mismas
interpretaba de igual forma un determinado código de
operación.
El programa que indica al intérprete de
instrucciones de la UCP cómo debe actuar se denomina
microprograma. El programa que ayuda a realizar este
microprograma se llama microensamblador. Existen procesadores que
permiten la modificación de sus microprogramas, para lo
cual se utilizan microensambladores.
Ensambladores de una fase.
Estos ensambladores leen una línea del programa
fuente y la traducen directamente para producir una
instrucción en lenguaje máquina o la ejecuta si se
trata de una pseudoinstrucción. También va
construyendo la tabla de símbolos a medida que van
apareciendo las definiciones de variables, etiquetas,
etc.
Debido a su forma de traducción, estos
ensambladores obligan a definir los símbolos antes de ser
empleados para que, cuando aparezca una referencia a un
determinado símbolo en una instrucción, se conozca
la dirección de dicho símbolo y se pueda traducir
de forma correcta. Estos ensambladores son sencillos, baratos y
ocupan poco espacio, pero tiene el inconveniente
indicado(1).
Ensambladores de dos fases.
Los ensambladores de dos fases se denominan así
debido a que realizan la traducción en dos etapas. En la
primera fase, leen el programa fuente y construyen una tabla
de símbolos; de esta manera, en la segunda fase,
vuelven a leer el programa fuente y pueden ir traduciendo
totalmente, puesto que conocen la totalidad de los
símbolos utilizados y las posiciones que se les ha
asignado. Estos ensambladores son los más utilizados en la
actualidad.
Para mayor información http:
www.sapag.com
CONCLUSIONES
Al parecer así como hay diferentes tipos de
memoria también hay diferentes tipos de ensambladores
y diferentes tipos de buses pero bueno me parece que cada
característica le sirven a cada persona o ustedes
que opinan..nos vemos(1).
2.4 El Proceso De
Ensamble De Uno, Dos O Mas Pasos
Es por esta razón que la mayoría de los
ensambladores hacen su trabajo pasando dos veces por el
programa fuente: una primera vez se pasa para asignar a cada
etiqueta su dirección correspondiente en el programa
objeto. El ensamblador pasa una Segunda ocasión por el
programa fuente para llevar a cabo el ensamblaje de las
instrucciones una vez ya tiene asignadas las direcciones de todas
las etiquetas. Estos ensambladores se llaman ensambladores de dos
pasadas ("two pass assembler").
Las tareas que el ensamblador lleva a cabo en cada
pasada son:
Primera pasada:
1. asignar una dirección de memoria a cada
instrucción
2. guardar en una tabla las direcciones de todas las
etiquetas del programa
3. procesar algunas de las directrices
Segunda pasada:
1. cambiar los mnemónicos a su código
correspondiente en lenguaje de máquina
2. poner las direcciones de los operandos
simbólicos o etiquetas en las instrucciones
3. generar los valores de
las constantes declaradas
4. procesar el resto de las directrices
5. escribir el programa en lenguaje objeto y el
"listing" (1)
(1)Dir.(http://ww.usc.clu.edu/comweb/cco220/ensambladores.htm)
Continuación de ensambladores
El "object program" que se genera se guarda en un
archivo en disco, para luego ejecutarse. Este archivo contiene
tres (por ahora) tipos de récords:
un "header record" con el nombre del programa, su
dirección inicial y el largo del programa (la
dirección inicial se obtiene de la directriz START del
programa fuente)
varios "text records" con las instrucciones
ensambladas
un "end record" con la dirección de la primera
instrucción ejecutable del programa(1).
Ensambladores De Dos Pasadas.- consta de una serie de
sentencias de una línea, parece natural tener un
ensamblador que lea una sentencia, la traduzca a lenguaje de
maquina y escriba el código de maquina generando en un
archivo y la porción del listado correspondiente, si la
hay, en otro. El proceso se repetirá hasta que todo el
programa sé haya traducido. Por desgracia, este método no
funciona.
La Primera Pasada.- la función
principal es construir, lo que sé llama tabla de
símbolos, donde se guardan los valores de
todos los símbolos. Un símbolo es una etiqueta o un
valor al que
se le asigna un nombre simbólico por medio de una
seudoinstrucción: espacio equ 100
La Segunda Pasada.- es generar el programa objeto y
posiblemente, imprimir el listido de ensamblaje. Además,
debe producir cierta información necesaria para que el
programa ligador enlace procedimientos ensamblados en momentos
diferentes(2).
(2.Org. De Computadoras Un Enfoque Estructurado,
Tanenbaum, P.453)
2.5 Literales Y Expresiones
Literales.- se le llama así a las
constantes para las cuales el ensamblador reserva memoria
automática. Además de ahorrar al programador un
poco de escritura, las
literales hacen más legibles de los programas al hacer que
el valor de la constante aparezca en la instrucción
fuente(1).
Expresiones.-Una expresión es una
combinación de símbolos constantes, operadores
algebraicos y paréntesis. La expresión especifica
un valor, el cual será utilizado como operando.
Las expresiones pueden consistir de símbolos,
constantes o del caracter ‘ * ‘ (denotando el valor
actual del contador de programa PC) unidos entre sí por
alguno de los operadores: +, -, *, /, %, &, I, ^.
(2)
(1.Org. De Computadoras Un Enfoque Estructurado,
Tanenbaum, P.500)
(2 Dir. Members.es.tripod.de/patricio/ensam/ensam1.htm)
continuación de Macros y Procedimientos
2.6 Definición De Una Macro
Una macro es un grupo de
instrucciones repetitivas en un programa que se codifican solo
una vez y pueden utilizarse cuantas veces sea
necesario.
La principal diferencia entre una macro y un procedimiento es
que en la macro se hace posible el paso de parámetros y en
el procedimiento no (esto es aplicable solo para el MASM, hay
otros lenguajes de
Programación que si lo permiten). Al momento de
ejecutarse la macro cada parámetro es sustituido por el
nombre o valor especificado al momento de llamarla.
Podemos decir entonces que un procedimiento es una
extensión de un determinado programa, mientras que la
macro es un módulo con funciones específicas que
puede ser utilizado por diferentes programas(1).
2.6.1 Macroinstrucción
son las instrucciones normales del nivel de
maquina convencional, como ADD, MOVE, etc(2).
2.6.4 Bibliotecas De
Macros
Una de las facilidades que ofrece el uso de las
macros es la creación de bibliotecas, las cuales son
grupos de macros que pueden ser incluidas en un programa desde un
archivo diferente.
La creación de estas bibliotecas es muy sencilla,
unicamente tenemos que escribir un archivo con todas las macros
que se necesitarán y guardarlo como archivo de
texto.
Para llamar a estas macros solo es necesario utilizar la
instrucción Include NombreDelArchivo, en la parte de
nuestro programa donde escribiriamos normalmente las macros, esto
es, al principio de nuestro programa(1).
(1 Dir. Members.es.tripod.de/patricio/ensam/ensam1.htm)
Macros y Pocedimento
(2.Org. De Computadoras Un Enfoque Estructurado,
Tanenbaum, P.200)
2.7 Ensamble Condicional
Se
emplean para que el ensamblador evalúe unas condiciones y,
según ellas, ensamble o no ciertas zonas de código.
Es frecuente, por ejemplo, de cara a generar código para
varios ordenadores: pueden existir ciertos símbolos
definidos que indiquen en un momento dado si hay que ensamblar
ciertas zonas del listado o no de manera condicional,
según la máquina. En los fragmentos en ensamblador
del código que generan los compiladores
también aparecen con frecuencia (para actuar de manera
diferente, por ejemplo, según el modelo de
memoria). Es interesante también la posibilidad de definir
un símbolo que indique que el programa está en fase
de pruebas y
ensamblar código adicional en ese caso con objeto de
depurarlo. Sintaxis:
IFxxx [símbolo/exp./arg.] ; xxx es la
condición
…ELSE ; el ELSE es opcional
…ENDIF
IF expresion (expresión distinta de
cero)
IFE expresión (expresión igual a
cero)
IF1 (pasada 1 del ensamblador)
IF2 (pasada 2 del ensamblador)
IFDEF símbolo (símbolo definido o
declarado como externo)
IFNDEF símbolo (símbolo ni definido ni
declarado como externo)
IFB <argumento> (argumento en blanco en macros
-incluir '<' y '>'-)
IFNB <argumento> (lo contrario, también es
obligado poner '<' y '>')
IFIDN <arg1>, <arg2> (arg1 idéntico a
arg2, requiere '<' y '>')
IFDIF <arg1>, <arg2> (arg1 distinto de arg2,
requiere '<' y '>')(1)
(1 Dir. http://www.usc.clu.edu/comweb/cco220/ensambladores.htm)
Continuación de Ensambladores
3.1 Concepto De
Cargadores y Ligadores
Un ligador es un programa de sistema que combina dos o
mas programas objeto separados y permite que se hagan referencias
unos a otros, o sea, que cada uno de estos programas pueden hacer
referencia a código ó variables de los otros
programas con los que está enlazado.
En muchos programas el cargador hace la labor del
programa de enlace, por que existe solo un "linking loader" y no
existe programa de enlace independiente. Es importante
señalar que no se necesita un programa de enlace ni un
cargador separado para cada traductor en el sistema, ya que estos
programas trabajan con el programa objeto, sin importar el lenguaje
fuente. Por otro lado es importante que cada compilador o
ensamblador produzca el programa objeto usando el mismo formato.
Cada programa objeto es un archivo de récord.
Un cargador es un programa que coloca en la memoria para
su ejecución, el programa guardado en algún
dispositivo de almacenamiento
secundario.
Un cargador es un programa del sistema que realiza la
función de carga, pero muchos cargadores también
incluyen relocalización y ligado.
Algunos sistemas tienen un ligador para realizar las
operaciones de
enlaces y un cargador separado para manejar la
relocalización y la carga.
Los procesos de
ensamblado y carga están íntimamente
relacionados.
El cargador consiste en un juego de
instrucciones que permiten al dispositivo de entrada ( teclado
ó unidad de cinta ) asignar la dirección de inicio
de la memoria y asegurar que el computador
leerá el programa y lo cargara byte a byte.
3.2 Funciones De Un Cargador Y Un
Ligador
Las funciones mas importantes de un cargador son:
colocar un programa objeto en la memoria e iniciar su
ejecución. Si tenemos un cargador que no necesita realizar
las funciones de ligado y relocalización de programas, su
operación es simple pues todas las funciones se realizan
en un solo paso. Se revisa el registro de
encabezamiento para comprobar se ha presentado el programa
correcto para la carga (entrando en la memoria disponible). A
medida que lee cada registro de texto, el código objeto
que contiene pasa a dirección de la memoria indicada.
Cuando se encuentra el registro de fin, el cargador salta a la
dirección especificada para iniciar la ejecución
del programa cargado. Un programa objeto contiene instrucciones
traducidas y valores de datos del programa fuente y
específica direcciones en memoria dónde cargaran
estos elementos.
Carga que lleva el programa objeto a la memoria para su
ejecución.
Relocalización que modifica el programa objeto de
forma que puede cargarse en una dirección diferente de la
localidad especificada originalmente.
Ligado que combina dos o mas programas objeto
independientes y proporciona la información necesaria para
realizar diferencias entre ellos.
El cargador es un programa del sistema que realiza la
función de carga pero muchos cargadores también
incluyen relocalización y ligado. Algunos sistemas tienen
un ligador (ó editor de ligado ) para realizar las
operaciones de enlace, y un cargador separado para manera la
relocalización y la carga.
En la mayoría de los casos todos los traductores
de programas ( esto es, ensambladores y compiladores ) de un
sistema en particular producen programas objeto en el mismo
formato.
De esta misma forma, puede usarse el cargador o ligador
del sistema con independencia
del lenguaje de
programación fuente original, se suele utilizar el
término cargador en lugar de cargador y ligador, los
procesos de ensamblado y carga están íntimamente
relacionados entre sí.
Se han desarrollado herramientas especiales de software,
llamadas cargadores para asistir, al programados en la carga del
programa. El cargador es normalmente un programa pequeño
que permite al usuario entrar directamente las palabras de
instrucción y datos a direcciones concretas de la memoria
mediante, ó un teclado ó una cinta
magnética.
3.3 Tipos de cargadores y Ligadores
Hay diferentes tipos de cargadores como:
Cargadores Bootstrap: el programa cargador
una vez, situado en la memoria del computador, cargará el
programa de aplicación y los datos. Pero, previamente, se
ha debido cargar el cargador en la memoria. Y esto se puede
realizar por los siguientes métodos:
Entrada manual: mediante
el teclado el usuario teclea el cargador BOOTSTRAP.
Después de esto, el cargador se carga así mismo en
la memoria del computador.
Entrada por ROM: es posible tener las instrucciones de
inicialización almacenados permanentemente en alguna
porción de la ROM, en lugar de introducirlas manualmente
por teclado o por panel frontal. Cuando se requiere el programa
de bootstra, el operador simplemente dirige al computador,
mediante los conmutadores del panel, a ejecutar las instrucciones
memorizadas en ROM: al estar el programa almacenado en ROM se
elimina también la posibilidad de borrados
accidentales.
Cargadores iniciales: indican a la
computadora la forma de poner, dentro de la memoria principal
unos datos que están guardados en un periférico de
memoria externa ( cinta, disco, etc ). Sirven para cargar en la
memoria pequeños programas que inician el funcionamiento
de una computadora .
Algunas computadoras de carácter
general no tienen en memoria ningún programa de forma
permanente y cuando se desconectan pierden toda la
información de su memoria interna. Al volverlos a conectar
no son capaces de controlar ningún periférico. Se
hace así para que sea el usuario el que ponga los
programas que le interese ejecutar.
Cargadores absolutos: el programa cargador
pone en memoria las instrucciones guardadas en sistemas externos.
Independientemente de que sea un cargador inicial, o no sin
dichas instrucciones se almacenan siempre en el mismo espacio de
memoria ( cada vez que se ejecuta el programa cargador ) se dice
que es un cargador absoluto.
Cargadores con reubicación: en
ocasiones un mismo programa necesita ejecutarse en diferentes
posiciones de memoria. Para esto la traducción debe estar
realizada en forma adecuada, es decir no utilizando referencias
absolutas a direcciones en memoria, sino referencias a una
dirección especial llamada de
reubicación.
Cargadores ligadores: conocidos
también como linker . un linker se un término en
inglés
que significa montar.
Montar un programa consiste en añadir al programa
objeto obtenido a la traducción las rutinas externas a las
que hace referencia dicho programa. El ensamblador debe permitir
dichas referencias y las rutinas deben estar a su vez en lenguaje
máquina guardadas en algún elemento accesible por
el montador. Generalmente, dichas rutinas se encuentran guardadas
en un fichero especial al que suele denominarse librería
porque están almacenadas todas las rutinas externas
susceptibles de ser utilizadas por los diferentes programas del
usuario. Allí va el programa ligador cuando esta
realizando el montaje de un programa a buscarlas y las adjunta al
programa objeto.
Editores de ligado: la diferencia
fundamental entre un editor de ligado y un cargador ligador
es:
Primero.- se ensambla o compila el programa fuente,
produciendo un programa objeto ( que puede contener varias
secciones de control
diferentes ). Una cargador ligador realiza todas las operaciones
de ligado y relocalización incluyendo búsqueda
automática en bibliotecas, si se específica, y
carga el programa ligado directamente en la memoria para su
ejecución. Por otro lado un editor de ligado produce una
versión ligada del programa ( llamada a menudo modulo de
carga ó imagen ejecutable
) que se escribe en un archivo o biblioteca para
su ejecución posterior.
Cuando el usuario está listo para ejecutar el
programa ligado, se puede utilizar un cargador relocalizador
simple para cargar el programa en la memoria. La única
modificación necesaria al código objeto es la suma
de una dirección de carga real a los valores relativos del
programa. El editor de ligado realiza la relocalización de
todas las secciones de control al inicio del programa ligado. De
esta forma todos los elementos que necesitan modificarse en el
momento de la carga tienen valores relativos al inicio del
programa ligado.
Los editores de ligado se pueden utilizar para construir
paquetes de subrutinas u otras secciones de control que se suelen
utilizar juntas . esto puede ser útil al tratar con
bibliotecas de subrutinas que manejan lenguajes de
programación de alto nivel. A veces permiten al usuario
especificar que las referencias externas no se resuelven por
búsqueda automática en biblioteca.
Ligado dinámico: ofrece algunas
ventajas sobre los tipos de ligado. Proporciona la posibilidad de
cargar las rutinas sólo cuando si se necesitan. Si las
subrutinas son grandes ó tienen muchas referencias
externas se pueden conseguir ahorros considerables de tiempo y espacio
en memoria.
El ligado dinámico evita la necesidad de cargar
la biblioteca completa para cada ejecución. Puede incluso
hacer innecesario que el programa conozca el conjunto de
subrutinas que se podría utilizar. El nombre de la
subrutina se trataría simplemente como otro elemento de
entrada. En el método que se utilice aquí las
rutinas que se carguen dinámicamente deben llamarse por
medio de una solicitud del servicio al
sistema operativo. Este método también
podría considerarse como una solicitud a una parte del
cargador que se mantiene en la memoria durante la
ejecución del programa.
Cuando se utiliza ligado dinámico, la
asociación de dirección real y el nombre
simbólico de la rutina llamada no se hace hasta que se
ejecuta la proposición llamada.
3.4 Proceso De Carga Absoluta
Para ser ejecutados los programas se deben ubicar e la
memoria principal. Una tarea muy importante es asociar
instrucciones y datos con localidades específicas de
memoria. El trabajo de
realizar está asociación se deja algunas veces al
usuario, otras al traductor, otras al programa llamado cargador y
otras más al sistema operativo. La asociación de
instrucciones con ciertas localidades de memoria se conoce como
ligamiento. Dentro de la programación el lenguaje
máquina, el ligamiento y los sistemas de memoria
virtual actuales lo realizan de manera dinámica mientras se ejecuta el programa.
El retraso del ligamiento aumenta la flexibilidad para el usuario
y el sistema, pero los traductores, ligadores y los sistemas
operativos resultan más complejos. Un cargador es un
programa que coloca las instrucciones de un programa y sus datos
en memoria principal. Un cargador absoluto coloca
las instrucciones y los datos en las localidades precisas
indicadas por el programa en lenguaje de
máquina.
El proceso de carga absoluta consiste en que con la
máquina vacía ó inactiva no hay necesidad de
hacer relocalización de programas tan solo se puede
especificar la dirección absoluta del programa que se
cargue en primer lugar. En la mayoría de los casos este
programa es el sistema operativo que ocupa un lugar predefinido
en la memoria. Esto significa que se necesitan algunos medios
para realizar las funciones de el cargador absoluto. Una
opción es que el operador introduzca en la memoria el
código objeto de un cargador absoluto, utilizando los
interruptores en la consola del computador. Algunos computadores
requerían que el operador hiciera exactamente eso. Sin
embargo este proceso es demasiado incomodo y propenso a errores
para ser una buena solución del problema.
Para ver el gráfico seleccione la
opción "Descargar"
FIGURA 6.12 proceso de carga
Otra posibilidad es que el programa del cargador
absoluto resida permanente en una memoria sólo de lectura (
ROM). Cuando se produce una señal de hardware la
máquina empieza a ejecutar este programa de la ROM. En
algunos computadores el programa se ejecuta directamente en la
ROM; en otros el programa se copia de la ROM a la memoria
principal y se ejecuta allí. Sin embargo algunas
máquinas no tienen ese almacenamiento sólo de
lectura, además puede no ser conveniente cambiar un
programa en ROM si es necesario hacer modificaciones en el
cargador absoluto. Una solución inmediata es tener una
función de hardware incorporada que lea un registro de
longitud fija de algún dispositivo en alguna localidad
fija de la memoria; el dispositivo que se utilice puede
seleccionarse mediante interruptores de la consola. Una vez
completa la operación de lectura, el control se pasa
automáticamente a la dirección de la memoria
dónde se almaceno el registro. Este registro contiene
instrucciones de máquina que cargan el programa absoluto
que sigue. Si el proceso de carga requieren de mas instrucciones
de las que pueden leerse en un solo registro, el primer registro
causa la lectura de
otros y estos a su vez pueden originar la lectura aún de
más registros de ahí el término
arranque.
La carga absoluta necesita que el modulo de carga ocupe
siempre la misma posición de la memoria principal.
Así pues , todas las referencias del módulo de
carga para el cargador deben ser direcciones específicas
ó absolutas en memoria principal. Por ejemplo si x en la
siguiente figura es la posición de 1024 la primera palabra
del módulo de carga destinado a esa región de
memoria tendrá la dirección 1024.
La asignación de direcciones especificas a la
referencia a memoria de un programa pueden ser realizada tanto
por el programador como el tiempo de compilación o
ensamblaje. Con el primer método se tienen varias
desventajas. En primer lugar todos los programadores
tendrán que conocer la estrategia de
asignación deseada para situar los módulos en
memoria principal. En segundo lugar si hace alguna
modificación en el programa que suponga inserciones
ó borrados en el cuerpo del módulo tendrán
que cambiarse todas las direcciones. Por consiguiente es
preferible permitir que las referencias a memoria dentro de los
programas se expresen simbólicamente y que se resuelvan en
el momento de la compilación o el ensamblaje. Así
cuando se presente el módulo para la entrada a un cargador
absoluto, el ensamblador o el compilador convertirán todas
estas referencias direcciones específicas.
3.5 El Proceso De Carga Relocalizable
En la relocalización se establece la
correspondencia entre las direcciones usadas en el programa y
direcciones físicas cada vez que se utilizan durante la
ejecución del programa. Las direcciones lógicas
generadas por el ensamblador y el enlazador no se alteran durante
la carga. Comenzaremos por ver un sencillo método en el
cuál el programa se carga en posiciones contiguas de la
memoria; es decir el programa no está disperso por la
memoria. En la siguiente figura se presenta un cargador sencillo
que puede usarse con la relocalización dinámica. En
este caso el cargador lee encabezado del archivo ejecutable y
determina la cantidad de espacio necesaria para el programa.
Después asigna espacio suficiente para el programa y copia
el archivo ejecutable a memoria. Cuando se carga el programa en
la memoria, el cargador establece la correspondencia necesaria
para el programa, pasando la dirección de carga y el
tamaño v del programa a una rutina llamada
establecer-correspondencia. Al leer este código observe
que la función de carga devuelve un entero sin signo en
lugar de un apuntador. Esto refleja el hecho de que la
dirección inicial es una dirección lógica
y física.
Struct enc-ejec {
Unsigned int dir_ini
Unsigned int tamaño texto, tamaño_datos,
tamaño_bss;
/* otros campos de registro de encabezado*/
};
/*** prototipos para las funciones usadas por el
cargador **/
struct enc_ejec leer_enc(file*);
char leer_byte(file*);
char *obtener_memoria(unsigned int);
/***______________el cargador____________
***/
unsigned int *carga(file *arch_ejec)
{
struct enc_ejec encabezado;
char *dir_byte, *dir_carga;
unsigned int tamaño_prog;
encabezdo=leer_enc(arch_ejec);
/* determinar el tamaño del programa y asignarle
espacio */
tamaño_prog=encabezado.tamaño_texto+
encabezado.tamaño_datos+
encabezado.tamaño_bss;
dir_carga=obtener_memoria(tamaño_prog);
/* copiar los segmentos de textos y datos */
dir_byte=dir_carga;
while(leof(arch_ejec);)
{
*dir_byte=leer_byte(arch_ejec);
dir_byte=dir_byte+1;
}
/* establecer la correspondencia de direcciones
*/
establecer_correspondencia(dir_carga,tamaño_prog);
return(char*)encabezado.dir_ini);
}
FIGURA 10.18 seudo código para un cargador
sencillo (relocalizable)
Cuando varios programas comparten la memoria principal
puede no ser conveniente decidir por adelantado en que
región de la memoria debe cargarse un módulo en
particular es mejor tomar esa decisión en el momento de
carga. Así pues se necesita un módulo de carga que
pueda ubicarse en cualquier posición de la memoria
principal. Para satisfacer este nuevo requisito el ensamblador o
el compilador no generará direcciones reales de memoria
principal (direcciones absolutas) si no direcciones relativas a
algún punto conocido, tal como el comienzo del programa
esta técnica se ilustra en la siguiente figura que es la
6.13. al comienzo de módulo de carga se le asigna la
dirección relativa 0 y todas las demás referencias
dentro del módulo se expresan en relación al
comienzo del módulo.
Con todas las referencias a memoria expresadas en forma
relativa, situar los módulos en la posición deseada
se convierte en una tarea sencilla para el cargador, si el
módulo va a ser cargado comenzando por la dirección
x el cargador simplemente sumará x a cada referencia a
memoria a medida que cargue el módulo en memoria. Para
ayudar en esta tarea el módulo de carga debe incluir
información que indique el cargador dónde
están las referencias a direcciones y como se interpreten
(generalmente de forma relativa al comienzo del programa pero
también es posible que sean relativas a algún otro
punto del programa, como la posición actual). El
compilador prepara este conjunto de información que se
conoce como carga relozalizable.
3.6 Ligaduras De Subrutinas
Al estudiar subrutinas es conveniente identificar dos
funciones distintas : el invocador y el invocado.
El invocador : es la sección de código que
inicia la llamada a la subrutina.
El invocado: es la subrutina llamada por el
invocador.
Examinaremos las transferencias de control necesarias
para implantar la invocación de subrutinas. Al efectuar
una llamada se transfiere el control al cuerpo de la subrutina;
cuando esta concluye, devuelve el control a la instrucción
que está inmediatamente después de la llamada a la
subrutina desde diversos puntos en el programa, las subrutinas
deben ser capaces de regresar a distintos lugares del programa.
La dirección de retorno es la dirección de la
instrucción que esta inmediatamente después de la
instrucción que transfiere el control al invocado. El
invocador proporciona la dirección del retorno al invocado
como parte de enlace de la subrutina.
El enlace de subrutina es la estructura con que
se comparte información sobre el invocador y el invocado.
El invocador establece parte del enlace de subrutina en una
secuencia de instrucciones llamada secuencia de arranque.
El invocado establece lo que resta del enlace de subrutina en el
prologo de subrutina, el cuál puede estar vacío
como suponemos de todas las rutinas están bien
estructuradas, las instrucciones al final de la subrutina
regresan al invocador. Está secuencia de instrucciones se
denomina epílogo de subrutina . cuando el control
regresa al invocador, es posible que este tenga que limpiar el
enlace; este conjunto de instrucciones se denomina secuencia de
limpieza y también puede estar vacía.
En la siguiente figura se presenta un ejemplo de
secuencia de código:
Para ver el gráfico seleccione la
opción "Descargar" del menú superior
FIGURA 6.1 enlace de subrutina
Llamada subrutina
Para ver el
gráfico seleccione la opción
"Descargar"
La presentación de la figura 6.1 es un poco
engañosa. Al mostrar lado a lado los componentes del
programa parece que es posible ver las cuatro secuencias del
código al mismo tiempo. Sin embargo, esto ocurre rara vez.
El invocador y el invocado pueden estar separados por varias
páginas en el listado del programa, además puede
haber muchas llamadas separadas a la misma rutina. Como las
secuencias del código están distribuidas por todo
el programa, no es fácil correlacionar las acciones
realizadas por estás secciones de código
relacionadas. Así que es importante adoptar un convenio de
llamadas a subrutinas cuando escriba código que llame a
una subrutina o implante el cuerpo de una subrutina. En esencia
un convenio se llamada subrutina describe la asignación,
construcción y designación, de
enlace de subrutina, el enlace debe incluir la dirección
de retorno, un convenio de llamada especialmente simple almacena
la dirección de retorno en un registro. Usaremos el
registro R31 para almacenar la dirección, en la siguiente
figura se documenta este convenio de llamada listando las
acciones realizadas en cada secuencia de
código.
Secuencia de arranque:
Almacenar la dirección de retorno R31
Ramificar a la subrutina
Prologo de subrutina:
Nada
Epílogo de subrutina:
Ramificar a la dirección almacenada en
R31
Secuencia de limpieza:
Nada
Convenio de codificación: modos de
direccionamiento e instrucciones BRANCH
Observe que el epílogo de subrutina presentado
usa direccionamiento indirecto por registro con una
instrucción BRANCH. Muchas máquinas no permiten
usar de esta manera los modos de direccionamiento pero cuentan
con operaciones especiales, por ejemplo una operación que
asigna al contador del programa el valor almacenado en un
registro.
Convenio de codificación: ranuras de retardo
BRANCH
La mayoría de las máquinas RISC tienen una
ranura de retardo de ramificación después de cada
instrucción BRANCH, incluyendo aquellas con que se
implantan convenios a subrutinas. Seguiremos ignorando la
posibilidad de ranuras de retardo de ramificación en
nuestros ejemplos de código.
Para disponer de subrutinas muchas máquinas
proporcionan una instrucción que almacena la
dirección de retorno y hace una ramificación al
inicio de la subrutina. Algunas máquinas llaman a esta
operación JSR (jump to subroutine: salto de subrutina)
otras usan el nombre BL( branch and link: ramificación y
enlace) ya que la instrucción es una ramificación
que establece un enlace de subrutina.
Estas instrucciones requieren tres operandos: uno para
especificar la dirección de
retorno, otra para indicar almacenar la dirección
de retorno y un tercero para especificar la dirección
inicial de la subrutina el primer operando por lo general no
está explícitamente en la instrucción si no
se supone que el operando es la dirección de la siguiente
instrucción. El segundo operando puede ser
implícito o explicito dependiendo de la máquina. En
la especificación implícita la máquina
designa un registro como de enlace, en el cuál almacena la
dirección de retorno durante la ejecución de la
instrucción llamada subrutina. El último operando
la dirección inicial para la subrutina, por lo general es
un operando explicito en la instrucción.
: :otras instrucciones
:secuencia de arranque
: no hay secuencia de limpieza
BL R31
:otras instrucciones
: otras partes del programa
SUB 1 : no hay prologo
EJEMPLO 6.2 muestra como
puede usar una instrucción BL en el fragmento de
código.
www.google.com,
www.monografías.com,
www.t1msn.com
Sistemas computacionales.- MACCABE.- MCGRAWLL
HILL
- Funciones de un compilador
Un compilador es un programa que lee un programa escrito
en un lenguaje fuente y lo traduce a un programa
equivalente en otro lenguaje, el lenguaje objeto [Aho et al.
1990]. Como parte importante de este proceso de
traducción, el compilador informa al usuario de la
presencia de errores en el programa fuente.
En la compilación hay dos partes análisis y síntesis .
Durante el análisis se determinan las operaciones que
implica el programa fuente y se registran en una estructura
jerárquica llamada árbol. A menudo se usa una clase
especial de árbol llamado árbol sintáctico ,
donde cada nodo representa una operación y los hijos del
nodo son los argumentos de la operación.
Fases de un Compilador
Un compilador típicamente opera en fases , cada
una lleva a cabo una tarea sobre el programa fuente. La figura
4.1 , muestra la descomposición en fases de un
compilador.
Las primeras tres fases suelen agruparse en una sola
fase llamada fase de análisis y las últimas tres en
una llamada fase de síntesis. La fase de análisis y
el modulo de manejo de errores se describen posteriormente en
este mismo capítulo. La fase de síntesis no es
relevante en el contexto de un lenguaje multibase de datos, ya
que este sigue un enfoque diferente que el de los lenguajes
tradicionales, por esta razón solo se menciona.
Muchas herramientas de software que manipulan programas
fuente realizan primero algún tipo de análisis,
entre estas se encuentran los editores de estructuras,
impresoras estéticas, verificadores estáticos y los
interpretes1 .
Figura 4.1
Tipos de compiladores
Compilador cruzado: Es el que genera un
código objeto ejecutable en un ordenador distinto de
aquél en el que se realiza la
compilación.
Compilación-Montaje-Ejecución: En
las aplicaciones grandes es conveniente fragmentar el programa a
realizar en módulos que se compilan por separado, y una
vez que estos estén compilados unirlos mediante un
programa denominado montador para formar el módulo
ejecutable. El montador se encarga, a su vez, de incluir las
librerías donde están guardadas las funciones
predefinidas de uso común.
Compilación en una o varias pasadas: Se
llama pasada a cada lectura que hace el compilador del
texto fuente.
Compilación incremental. Este compilador
actúa de la siguiente manera. Compila un programa fuente.
Caso de detectar errores al volver a compilar el programa
corregido sólo compila las modificaciones que se han hecho
respecto al primero.
Autocompilador: Es aquél que está
escrito en el mismo lenguaje que se pretende compilar.
Supongamos, por ejemplo, que queremos desarrollar la
versión 2.0 de un compilador Pascal. Dicho
compilador generará un código mucho más
rápido y eficiente que el que generaba la versión
anterior 1.0. Sin embargo, son ya muchas las máquinas (IBM
370, Serie 1, PDP 11, …) que disponen del antiguo compilador, o
que al menos tienen otro compilador Pascal. La mejor
opción consiste en escribir el nuevo compilador en Pascal,
ya que así podrá (el compilador) ser compilado en
las distintas máquinas por los compiladores Pascal ya
existentes.
Metacompilador: Es un traductor que tiene como
entrada la definición de un lenguaje y como salida el
compilador para dicho lenguaje2.
Decompilador: Es el que traduce código
máquina a lenguaje de alto nivel. Los decompiladores
más usuales son los desensambladores, que traducen un
programa en lenguaje máquina a otro en
ensamblador.
Bootstrapping: Es una técnica muy usada
actualmente para el desarrollo de
compiladores de lenguajes de alto nivel, en especial si se quiere
obtener un autocompilador, o sea, un compilador que se compile a
sí mismo.
Para describir el proceso de autocompilación se
emplea la notación en T que representa gráficamente
los tres lenguajes implicados en el proceso de
compilación:
Lenguaje fuente: Lenguaje origen que traduce el
compilador.
Lenguaje objeto: Lenguaje meta, al cuál
traduce el compilador.
Lenguaje del compilador: Lenguaje en el que
está escrito el compilador.
Análisis lexicográfico.
La cadena de caracteres que constituye el programa
fuente se lee de izquierda a derecha y se agrupa en componentes
léxicos, que son secuencias de caracteres que tienen un
significado colectivo. El análisis léxico se
encarga de hacer esta agrupación1.
Las principales funciones que realiza son:
Identificar los símbolos.
Eliminar los blancos, caracteres de fin de línea,
etc…
Eliminar los comentarios que acompañan al
fuente.
Crear unos símbolos intermedios llamados
tokens.
Avisar de los errores que detecte.
Ejemplo: A partir de la sentencia en PASCAL
siguiente
nuevo := viejo + RAZON*2
genera un código simplificado para el
análisis sintáctico posterior, por
ejemplo:
<id1> <:=> <id2> <+> <id3>
<*> <ent>
Nota: Cada elemento encerrado entre <> representa
un único token. Las abreviaturas id y ent significan
identificador y entero, respectivamente2.
Análisis sintáctico
Implica agrupar los componentes léxicos en frases
gramaticales que el compilador utiliza para sintetizar la salida.
Por lo general, las frases gramaticales del programa fuente se
representan mediante un árbol de análisis
sintáctico como el que se ilustra en la figura
4.3.
Figura 4.3
La división entre el análisis
léxico y el análisis sintáctico es algo
arbitraria. Generalmente se elige una división que
simplifique la tarea completa del análisis. Un factor para
determinar la división es si una construcción es
inherentemente recursiva o no. Las construcciones léxicas
no requieren recursión, mientras que las construcciones
sintácticas suelen requerirla. Las gramáticas
independientes de contexto son una formalización de reglas
recursivas que se pueden usar para guiar el análisis
sintáctico1.
Comprueba que las sentencias que componen el texto
fuente son correctas en el lenguaje, creando una
representación interna que corresponde a la sentencia
analizada. De esta manera se garantiza que sólo
serán procesadas las sentencias que pertenezcan al
lenguaje fuente. Durante el análisis sintáctico,
así como en las demás etapas, se van mostrando los
errores que se encuentran.
Ejemplo: El esquema de la sentencia anterior
corresponde al de una sentencia de asignación del lenguaje
Pascal. Estas sentencias son de la forma:
- <id> <:=> <EXPRESION>
- y la parte que se denomina <EXPRESION> es de la
forma2: - <id> <+> <EXPRESION> o
bien - <id> <*> <EXPRESION> o
bien - <real>
La estructura de la sentencia queda, por tanto, de
manifiesto mediante el siguiente esquema:
<id1> <:=> <EXPRESION> / |
<id2> <+> <EXPRESION> / | <id3>
<*> <EXPRESION> | <real>
Análisis semántico
La fase de análisis semántico utiliza la
estructura sintáctica determinada por la fase de
análisis sintáctico para identificar los operadores
y operandos de expresiones y proposiciones. En el caso de un
interprete de consultas se debe validar que los nombres de
atributos y de relaciones sean válidos y tengan sentido
desde el punto de vista semántico.
Un componente importante del análisis
semántico es la verificación de tipos. Aquí,
el interprete verifica si cada operador tiene operandos
permitidos por la especificación del lenguaje fuente y
verifica la compatibilidad de los tipos cuando estos están
involucrados, por ejemplo, en una
condición1.
Se ocupa de analizar si la sentencia tiene algún
significado. Se pueden encontrar sentencias que son
sintácticamente correctas pero que no se pueden ejecutar
porque carecen de sentido. En general, el análisis
semántico se hace a la par que el análisis
sintáctico introduciendo en éste unas rutinas
semánticas.
Ejemplo: En la sentencia que se ha analizado
existe una variable entera. Sin embargo, las operaciones se
realizan entre identificadores reales, por lo que hay dos
alternativas: o emitir un mensaje de error "Discordancia de
tipos", o realizar una conversión automática al
tipo superior, mediante una función auxiliar
inttoreal2.
<id1> <:=> <EXPRESION> / |
<id2> <+> <EXPRESION> / | <id3>
<*> <EXPRESION> | <real> | <inttoreal> |
<int>
Generación de código
intermedio.
El código intermedio es un código
abstracto independiente de la máquina para la que se
generará el código objeto. El código
intermedio ha de cumplir dos requisitos importantes: ser
fácil de producir a partir del análisis
sintáctico, y ser fácil de traducir al lenguaje
objeto. Esta fase puede no existir si se genera directamente
código máquina, pero suele ser conveniente
emplearla.
Ejemplo: Consideremos, por ejemplo, un
código intermedio de tercetos, llamado así porque
en cada una de sus instrucciones aparecen como máximo tres
operandos. La sentencia traducida a este código intermedio
quedaría2:
temp1 := inttoreal (2)temp2 := id3 * temp1temp3 := id2 +
temp2id1 := temp3
Generación de código
completo.
A partir de los análisis anteriores y de las
tablas que estos análisis van creando durante su
ejecución produce un código o lenguaje objeto que
es directamente ejecutable por la máquina. Es la fase
final del compilador. Las instrucciones del código
intermedio se traducen una a una en código máquina
reubicable.
Nota: Cada instrucción de código
intermedio puede dar lugar a más de una de código
máquina.
Ejemplo: El código anterior traducido a
ensamblador DLX quedaría:
LW R1,id3MUL R1,R1,2LW R2,id2ADD R2,R2,R1SW
id1,R2
en donde id1, id2 y id3 representan las posiciones de
memoria en las que se hallan almacenadas estas variables; R1 y R2
son los registros de la máquina; y las instrucciones LW,
SW, MUL y ADD representan las operaciones de colocar un valor de
memoria en un registro, colocar un valor de un registro en
memoria, multiplicar en punto flotante y sumar,
respectivamente2.
Optimización de código
A partir de todo lo anterior crea un nuevo código
más compacto y eficiente, eliminando por ejemplo
sentencias que no se ejecutan nunca, simplificando expresiones
aritméticas, etc… La profundidad con que se realiza esta
optimización varía mucho de unos compiladores a
otros. En el peor de los casos esta fase se suprime.
Ejemplo: Siguiendo con el ejemplo anterior, es
posible evitar la función inttoreal mediante el cambio de 2
por 2.0, obviando además una de las operaciones
anteriores. El código optimizado queda como
sigue2 :
temp1 := id3 * 2.0id1 := id2 + temp1
Herramientas generadoras de
compiladores
Esta es una lista de las herramientas más
conocidas para la construcción de compiladores. Si conoce
otro generador que no figure en esta lista, por favor hága
saber.
Se agradecerá informar sobre la desactualización de
alguno de los enlaces.
Nombre: Lex y Yacc
Descripción: los generadores más populares
de analizadores léxicos y sintácticos
LALR(1).
Lenguaje: Pascal – C
Download:
Turbo Pascal y FPK
Nombre: Flex y Bison
Descripción: versiones mejoradas (generan
analizadores más rápidos) de Lex y Yacc.
Lenguaje: C
Nombre: BTYacc (Back Tracking Yacc)
Descripción: es una versión modificada de
yacc que genera parsers con capacidad de backtracking
automático.
Lenguaje: C
Download: DOS
Nombre: BYacc (Berkeley Yacc)
Descripción: es un generador de parsers LALR(1)
de dominio
público compatible con AT&T Yacc (el Yacc
original).
Lenguaje: C
Download:
Nombre: YAY (Yet Another YACC)
Descripción: es un generador de analizadores
sintácticos ascendentes similar a Yacc pero con una
extensión sumamente importante: soporta gramáticas
LALR(2).
Lenguaje: C
Download: DOS
Nombre: ParseGenerator
Descripción: es una IDE (Entorno Integrado de
Desarrollo), bajo Windows32, para los generadores AYACC y
ALEX, clones de Yacc y Lex respectivamente.
Lenguaje: C – C++
Download: Win32
Nombre: Eli
Descripción: ofrece soluciones a
casi todas las tareas relacionadas con la implementación
de un lenguaje.
Lenguaje:
Download: ELI
Nombre: COCKTAIL
Descripción: es un conjunto de generadores de
programas para casi todas las fases de un compilador. LALR(1) –
LL(1) – Generador de ASTs – Evaluador de Atributos – Herramienta
de transformación de programas.
Lenguaje:
Download: COCKTAIL
Nombre: PCCTS
Descripción: es un conjunto de herramientas para
la construcción de traductores y reconocedores de
lenguajes. Comprende tres herramientas: ANTLR un generador de
parsers LL(k), DLG un analizador de analizadores léxicos y
SORCERER un generador de parsers para árboles
que le permite al programador definir la estructura del
árbol por medio de una gramática.
Lenguaje:
Download: PCCTS
Nombre: Coco/R
Descripción: es un generador de parsers
descendentes.
Lenguaje:
Download: COCO(R)
Nombre: Depot4
Descripción: es un generador de parsers
descendentes que soporta especificaciones al etilo de la
traducción dirigida por la sintaxis.
Lenguaje:
Download: Depot4
Nombre: LLgen
Descripción: es una herramienta para generar
parsers descendentes a partir de una gramática
ELL(1). La gramática puede ser ambigua o más
general que una ELL(1).
Lenguaje:
Download: LLGEN
Nombre: PRECC
Descripción: es un generador de compiladores para
gramáticas dependientes del contexto con infinito
lookahead.
Lenguaje:
Download: PRECC
Nombre: RDP
Descripción: es un generador de parsers
descedentes para gramáticas LL(1).
Lenguaje:
Download: RDP
Nombre: Visual Parse++
Descripción: provee una interfase visual
que permite aprender y utilizar, de manera interactiva, la
tecnología
de parsing. Genera parsers en C, C++, VBasic y Java.
Lenguaje:
Download: VISUALPARSE++
Nombre: AnaGram
Descripción: es un generador de parsers
LALR con resincronización automática en presencia
de errores. Usualmente no necesita de un analizador
léxico.
Lenguaje:
Download: AnaGram
Nombre: TCLL1
Descripción: es un generador de parsers
descendentes para gramáticas LL(1) y LL(k).
Lenguaje:
Download: TCLL1
Nombre: Elegant (recomendado por David
Riemens)
Descripción: es un lenguaje orientado a la
construcción de compiladores desarrollado por
Phillips y puesto a dispocisión del público en
1997.
Lenguaje:
Download:
Elegant
Nombre: Cogencee (link recomendado por Peter
Evans)
Descripción: generador de parsers descendentes en
Delphi.
Lenguaje: Delphi
Download: Cogencee
Nombre: ProGrammar (link recomendado por Norm
Wilson)
Descripción: un moderno generador de parsers
OO.
Lenguaje:
Download: ProGrammar
Una lista más extensa herramientas puede
encontrarse en Catalog
of Compiler Construction
Tools3
(c) 2000 Compiladores e Intérpretes
http://www.ucse.edu.ar/fma/compiladores/
Salvador V. Cavadini
Principios de la
interpretación.
En lugar de producir un programa objeto como resultado
de una traducción, un intérprete realiza las
operaciones que implica el programa fuente. Por ejemplo un
interprete podría construir un árbol, y
después efectuar las operaciones de los nodos conforme
recorre el árbol.
Muchas veces los interpretes se utilizan para ejecutar
lenguajes de órdenes, pues cada operador que se ejecuta en
un lenguaje de este tipo suele ser una invocación de una
rutina, como un editor o un compilador. Del mismo modo algunos
lenguajes de alto nivel son interpretados, porque hay muchas
cosas sobre los datos, como el tamaño y la forma de las
matrices que
no se pueden deducir en el momento de la
compilación1.
Intérprete: Es un traductor que realiza la
operación de compilación paso a paso. Para
cada sentencia que compone el texto de entrada, se realiza una
traducción, ejecuta dicha sentencia y vuelve a iniciar el
proceso con la sentencia siguiente. La principal ventaja del
proceso de compilación frente al de interpretación
es que los programas se ejecutan mucho más
rápidamente una vez compilados; por el contrario, es
más cómodo desarrollar un programa mediante un
intérprete que mediante un compilador puesto que en el
intérprete las fases de edición y ejecución
están más integradas. La depuración de los
programas suele ser más fácil en los
intérpretes que en los compiladores puesto que el
código fuente está presente durante la
ejecución. Estas ventajas pueden incorporarse al
compilador mediante la utilización de entornos de
desarrollo y depuradores simbólicos en tiempo de
ejecución2.
Diferencia entre un interprete y
compilador
INTERPRETE: Es un programa que lee línea a
línea un programa escrito en un lenguaje; en lenguaje
fuente y lo va traduciendo a un código intermedio, para
ejecutarlo.
COMPILADOR: Es un programa que lee totalmente un
programa escrito en un lenguaje; el lenguaje fuente, y lo traduce
a un programa equivalente a otro lenguaje, lenguaje
objeto.
Autor:
LAS MISMAS.COM
Pérez Rivera Marlene
Jiménez Márquez María Del
Rosario
Castillo García Brenda Berenice
Gutiérrez Simon Flavia Marisol
Crespo Loto Karina
Correo electrónico:
Girl_yahua [arroba] hotmail.com
Rossjim21 [arroba] hotmail.com
Brendiz81 [arroba] hotmail.com