CARGADORES 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 enlace, y un cargador separado para manejar la relocalización y la carga. Los procesos de ensamblado y carga están íntimamente relacionados. Las funciones más 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 muy 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 se lee cada registro de texto, el código objeto que contiene pasa a la dirección de memoria indicada. Cuando se encuentra el registro de fin, el cargador salta a al 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 donde se cargarán 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 más programas objeto independientes y proporciona la información necesaria para realizar referencias entre ellos. 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( o 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 fromato. 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 sotware, 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 isntrucción y datos a direcciones concretas de la memoria, mediante un teclado o una cinta magnética. El cargador consiste en un juego de instrucciones que permiten al dispositivo de entrada (teclado o unidad de cinta) asignar la dirección de inicio de la memoria y asegurar que el computador leerá el programa y lo cargará byte a byte. 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 uno de los métodos siguientes: 1 Entrada Manual: Mediante el teclado, el usuario teclea en la máquina el cargador bootstrap. Después de esto, el cargador se carga a sí mismo en la memoria del computador. A partir de este momento, es el cargador el encargado de cargar el programa de aplicación en la memoria. Entrada por ROM: Es posible tener las instrucciones de inicialización almacenadas permanentemente en alguna porción de la ROM, en lugar de introducirlas manualmente por teclado o por el panel frontal. Cuando se requiere el programa de bootstrap, 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 ABSOLUTOS. Este es un programa que carga cada instrucción del programa objeto en una posición fija y preestablecida. Por tanto, cada instrucción tiene una dirección absoluta. El cargador absoluto lee simplemente la línea de código objeto que contiene la dirección de inicio de las instrucciones y datos, y carga las palabras ( o bytes) sucesivas en posiciones de memoria sucesivas. El cargador absoluto tiene un serio inconveniente cuando se utiliza en sistemas computadores grandes. Esto significa que los programas y datos se deben almacenar cada vez en posiciones de memoria distintas. Si se utilizan cargadores absolutos, el programa objeto se tendrá que modificar para que refleje la nueva posición de inicio de memoria. Esta es una actividad larga y sujeta a errores. En tales situaciones, se utilizan cargadores relocatables. Los cargadores absolutos están diseñados generalmente para verificar cada instrucción que leen. Si se detecta una instrucción ilegal, se interrumpe el proceso de carga. CARGADORES RELOCATABLES. Este cargador evita el principal inconveniente del cargador absoluto. El cargador relocatable es un programa más sofisticado, tiene las características del cargador absoluto, y además permite al usuario seleccionar y especificar las posiciones de memoria en las que se debe almacenar las palabras de instrucciones y datos. De esta forma, el mismo programa se puede cargar en distintas zonas de la memoria sin necesidad de reensamblarlo o recompilarlo. Durante el ensamblado o compilación del programa objeto, éste empieza con la dirección =. Las sucesivas instrucciones quedan asignadas a posiciones de memoria consecutivas. No obstante, las direcciones no son absolutas, es decir, no representan las verdaderas posiciones de memoria en las que se está almacenando el programa. Se trata de direcciones relativas. El programador inserta la dirección se añade a cada una de las posiciones de memoria asignadas en el programa, obteniéndose las direcciones reales de las instrucciones y datos del programa. El cargador relocatable ofrece algunas ventajas. CARACTERISTICAS DEL CARGADOR DEPENDIENTE. El cargador absoluto es simple y eficiente sin embargo, tiene varias desventajas potenciales. Una de las más obvias es que el programador necesita especificar la dirección real en la que se cargará en la memoria. Escribir programas absolutos también dificulta el uso eficiente de subrutinas de biblioteca. La mayoría de esas bibliotecas contienen muchas subrutinas de las que puede utilizar cualquier programa. La necesidad de relocalizar los programas es una consecuencia directa del cambio a compoutadoras más grandes y potente. La forma de efectuar la relocalización en un cargador también depende de las características de la máquina. 2 El ligado no es una función dependiente de la máquina en el mismo sentido que la relocalización; sdin embargo a menudo se utilizan las mismas té4cnicas de implantación para esas dos funciones, además el proceso de ligado suele comprender la relocalización de lagunas de las rutinas que se están ligando. RELOCALIZACION. Los cargadores que permiten la relocalización de programas se denominan cargadores relocalizadores o cargadores relativos. Existen dos métodos para la relocalización. El primer método utiliza un registro de modificación para describir cada parte del código que se ha de cambiar al relocalizar el programa. CARACTERISTICAS INDEPENDIENTES DEL CARGADOR. Con frecuencia se piensa que el cargado y el ligado son funciones de servicio del sistema operativo. La conexión del programador con estos servicios no es tan directa como la que tiene con el ensamblador durante el desarrollo del programa. Por tanto, la mayoría de los cargadores tienen menos características diferentes que las que se pueden encontrar en un ensamblador típico. Muchos cargadores ligadores pueden incorporar automáticamente rutinas de un subprograma de biblioteca en el programa que se está cargando. En la mayoría de los casos, se emplea de esta forma una biblioteca estándar del sistema, pero se pueden especificar para el cargador otras bibliotecas, mediante proposiciones de control o parámetros. Esta característica permite al programador utilizar subrutinas de una o más bibliotecas casi como si formaran parte del lenguaje de programación. Las subrutinas llamadas por el programa que se4 está cargando se traen automáticamente de la biblioteca, se ligan al programa principal y se cargan. En algunos sistemas, esta característica se denomina llamada automática a biblioteca. Para evitar confusión con la característica de llamada de la mayoría de los lenguajes de programación, se utiliza el término búsqueda en biblioteca. Los buscadores ligadores con búsqueda en biblioteca deben conocer los símbolos externos a los que se hace referencia, pero que no están definidos, en la entrada primaria del cargador. Las bibliotecas en las que busca el cargador suelen contener versiones ensambladas o complicadas de subrutinas. Esta estructura contiene un directorio que proporciona el nombre de cada rutina y un apuntador a su dirección en el archivo. OPCIONES DE DISEÑO DEL CARGADOR. Los cargadores ligadores realizan el ligado y la relocalización en el momento de la carga. Se analizan dos opciones: los editores de ligado, que realizan el ligado antes del momento de la carga, y el ligado dinámico en el cual la función de ligado se realiza en el momento de la ejecución. El ligado dinámico, utiliza los dispositivos del sistema operativo para cargar subprogramas en el momento en que se llaman por primera vez. Al retardar el proceso de ligado de esta forma, se puede lograr flexibilidad adiconal. Sin embargo, este enfoque suele implicar más operaciones que el del cargado ligador. Los cargadores de arranque (bootstrap loaders,) que pueden utilizar para ejecutar programas autónomos, independientes del sistema operativo o del cargador del sistema. También se pueden utilizar para cargar el sistema operativo o el cargador mismo en la memoria. Proceso de ensamblado de un programa. 3 Los computadores y también los microcomputadores se pueden programar mediante uno de los siguientes niveles de lenguaje: nivel maquina, nivel ensamblador y alto nivel. El lenguaje maquina es el nivel de comunicación más básico entre el computador y el programador. Requiere que el programador piense en términos de funciones de maquina y escriba cada instrucción del programa en el código binario del computador especifico. La programación a nivel de ensamblador evita al programador la penosa tarea de escribir las instrucciones del programa en 0 y 1 binarios. El ensamblador, que no es mas que un programa de computador, permite al programador escribir el programa en un lenguaje simbólico que tiene algún parecido con el ingles. El ensamblador toma este programa fuente y lo traduce en otro programa en código maquina. La traducción se realiza de uno a uno. Aunque el lenguaje ensamblador implica enormemente el trabajo del programador, resulta más costoso. En primer lugar, el ensamblador se debe producir para cada Mp. Un ensamblador escrito para una maquina no se puede utilizar directamente en otra. Consecuentemente, la programación a nivel de ensamblador puede producir un uso ineficiente de la memoria, incrementando su costo. Dificultades del ensamblado manual. Siempre es posible ensamblar un programa de computador sin utilizar un ensamblador. El proceso de ensamblado manual de un programa requiere las siguientes tareas: 1.−Convertir los códigos mnemónicos en sus equivalentes binarios. 2.−Convertir los números decimales en sus equivalentes binarios. 3.−Asignar direcciones de la memoria de programa a cada instrucción de programa principal. 4.−Asignar direcciones de la memoria de programa a cada instrucción de las subrutinas. 5.−Contar el numero de palabras de datos necesarias en la memoria de datos para el programa principal y las subrutinas. 6.−Asignar direcciones de la memoria de datos a las palabras de datos. Los programas en lenguaje maquina son mucho más fáciles de escribir si se hacen en código octal o hexadecimal, en lugar de binario. No obstante si se escribe en código octal o hexadecimal, se debe hacer una segunda traducción a código binario. Un programa diseñado en lenguaje ensamblador para una cierta maquina no puede correr en otra. Si se utiliza el lenguaje ensamblador, el programador debe conocer la arquitectura del computador. Objetivos de programación en ensamblador. · Permitir al programador escribir un programa en lenguaje ensamblador, utilizando los mnemónicos y símbolos dados por el suministrador para el computador en particular. · Disponer de un método para que el propio computador traduzca las instrucciones escritas en lenguaje ensamblador (programa fuente) en 4 instrucciones útiles para el computador, en código binario (programa objeto). · Asignar una dirección absoluta de memoria a cada instrucción que, en el programa fuente este identificada por una etiqueta. · Asignar una dirección absoluta de memoria a cada palabra de datos que, en el programa fuente igual este identificada por una etiqueta. · Disponer de algún método de verificación que determine algunas incongruencias en el programa fuente. Programas ensambladores. Los ensambladores trabajan sobre código fuente en forma de línea por línea, van tomando cada una de las líneas del archivo fuente e intentan traducirlo a instrucciones a lenguaje maquina. Una línea se define como el conjunto de caracteres que se encuentra entre dos retornos de carro. Una línea de código fuente puede contener de uno a cuatro campos (grupos de caracteres), cada uno de los cuales tiene un significado especial para el ensamblador. Estos son: 1: Una etiqueta que normalmente es opcional. 2: Un código OP o pseudocodigo OP que es obligatorio en todas las líneas excepto líneas en blanco o líneas que son solo comentarios o etiquetas. 3: Un operando que se necesita si el código OP o pseudocodigo OP en esa línea requiere un operando. 4: Un comentario que siempre es opcional. Ensambladores de formato libre. Permiten que los campos comiencen en diferentes columnas de las líneas del código fuente con tal que se sigan unas reglas. Típicamente estas reglas incluyen las siguientes: 1. Las etiquetas deben comenzar en la columna 1. En caso contrario la columna 1 debe contener un símbolo que signifique una línea entera de comentario o estar en blanco. 2. Los diferentes campos deben estar separados por uno o más espacios. El carácter espacio se denomina comúnmente como delimitador por que marca las fronteras de cada campo y separa unos de otros. 3. Un comentario que ocupe la línea completa debe indicarse mediante un símbolo especial en la columna 1 de la línea. Tipos de ensambladores. Los ensambladores se clasifican en diferentes categorías, a menudo repletas de opciones y extensiones del procesamiento del lenguaje 5 ensamblador básico. Permiten, en virtud de las pseudo operaciones, acortar el tiempo de desarrollo de un proyecto de programación. Pero existe un precio a pagar, no siempre en el costo del ensamblador. Cuanto más características extras de un ensamblador particular sé, utilicen menos portable a otros ensambladores resulta el código fuente para el mismo chip, aunque ello código objeto sea un portable. La decisión de utilizar las características extra depende del uso que se vaya a hacer del código fuente. La clasificación de los ensambladores depende de diferentes factores. Muchos ensambladores entran dentro de mas de una categoría. Ensambladores Cruzados. Un ensamblador cruzado es aquel que se ejecuta sobre un computador con un procesador diferente de aquel para el que se ensambla el código. Los ensambladores cruzados permiten a un programador desarrollar programas para diferentes sistemas sobre un computador. Sin embargo, excepto en el caso de minicomputadores y grandes computadores que pueden ofrecer un simulador de microprocesador destinatario real, no se puede normalmente probar y depurar el código creado por un ensamblador cruzado sin ejecutarse sobre una maquina real que utilice este procesador. En cualquier caso, siempre se debe utilizar la sintaxis correcta, esto es, códigos OP, operandos, y así sucesivamente, para el microprocesador para el que el ensamblador cruzado esta diseñado. Ensambladores residentes. El polo opuesto del ensamblador cruzado es el ensamblador residente, que se ejecuta sobre una maquina que contiene el mismo procesador que el destinatario del código ensamblado. Un ensamblador residente ofrece al programador la ventaja de utilizar una única maquina para crear, probar, y depurar código. Los ensambladores residentes sobre los primeros microprocesadores fueron algo lentos y restrictivos en características debido al alto costo de memoria y la lentitud del microprocesador, con la disponibilidad de memoria debajo costo (y consecuentemente grandes memorias disponibles en la mayor parte de los sistemas) y la posibilidad del procesador de direccionar directamente grandes cantidades de memoria, así como de realizar funciones mas rápidas, los ensambladores residentes proporcionan ahora una variedad de características y velocidad de ensamblaje que anteriormente solo se encontraban en ensambladores cruzados sobre grandes computadores y microcomputadores. 6