| Volver menú revistas | Volver página anterior |
|
El Amiga Me Encanta ha conseguido el permiso por escrito de IDG Comunications España para ofrecer los artículos de la revista Amiga World España. |
| N°
7- Febrero 1990 |
|
INICIACION AL LENGUAJE ENSAMBLADOR
|
|
Por Fernando G. Terradillos
Para continuar debe saber que un disco se compone de 80 cilindros (del 0 a la 79), cada uno de ellos con dos cabezas de lectura (superior e inferior) y en cada una de ellas, 11 sectores (del 0 al 10, 22 em total por cada cilindro). Esto hace en total 1760 bloques (del 0 al 1.759). Cada bloque es cuestión contiene 512 bytes, siendo la totalidad exacta de un disco en bytes 901.120. Pero si sólo disponemos de 856 k. cuando formateamos uno de ellos, dónde se encuentra el resto. Pues exactamente está ocupando bloques tan importantes como el bootblock (2 bloques = 1 k.), el directorio principal (1 bloque), el utilizado como mapa de bloques libres en disco (1 bloque), y si tenemos en cuenta que por cada bloque arranca 24 bytes al disco (un total de 42144 bytes) esto hace una suma suficiente para que nos demos cuenta que el sistema operativo del disco usa parte del mismo para utilización propia. Resumen de organización del disco: 80 cilindros = 160 pistas. Como he dicho antes, el sistema para organizar todos estos bloques es jerárquico, como el de un árbol, teniendo como base el directorio principal, que es el que conseguimos al hacer un simple DIR desde el CLI a cualquier disco. Este directorio principal ocupa simplemente un bloque de disco, y para mayor facilidad de búsqueda se ha situado en el centro exacto del disco (bloque 880, sector 0, cabeza 0, cilindro 40). Esto es totalmente lógico, pues sería de tontos meter el directorio prinicipal en el comienzo del disco para que el cabezal del DRIVE se volviera loco dándose unos paseos por toda su superficie. A continuación voy a presentar los 512 bytes del bloque 880 de mi Workbench, para que a continuación explique cuál es el contenido del mismo. Antes de hacerlo quiero decir que hay un libro magnífico que recomendé en el capítulo 1 y voy a repetir su título: "The AmigaDOS Manual" de BANTAM AMIGA LIBRARY. También recomiendo utilizar algún editor de discos (DISK ED, por ejemplo) para hacer el seguimiento poco a poco. La información de la derecha pertenece al offset o posición dentro del bloque en hexadecimal. Los números del centro pertenecen a la notación hexadecimal de la información del bloque en sí. La parte de la derecha pertenece a la información en ASCII correspondiente a la misma línea. Como podrá comprobar de un vistazo ya estamos viendo el nombre del disco en la parte inferior del bloque. También hemos de decir que la información de estos tipos de bloques se agrupan de cuatro en cuatro bytes (dobles palabras), excepto para la información de nombres de ficheros, directorios, etc. El resto de la información vamos a darla como offsets en hexadecimal, es decir, por ejemplo el offset $0138 contiene $FFFFFFFF y explicaremos el contenido de la misma posición (cuadro 1).
Ahora vamos a ver cómo enlaza el directorio principal con otro directorio; en este caso pondremos el directorio 'devs' que contiene la información acerca de los periféricos del Amiga. Para encontrarlo hay que mirar las posiciones dentro de la tabla de bloques entre los offsets $0018-$0137, y es exactamente el $0070 el que enlaza al directorio. El valor contenido en este offset es el de $0000037D que en decimal se convierte a 893, siendo éste el bloque exacto que contiene la información necesaria para enlazar el directorio 'devs' con otros ficheros u otros directorios. Quiero hacer ver que todavía no hemos llegado a la información propia que contiene un fichero, sino que estamos viendo qué es lo que hace el Amigados hasta llegar a un fichero que le hemos pedido. Y a continuación veamos el bloque referente al directorio 'devs' en mi Workbench. También podrá ver a primera vista el nombre del directorio, siendo, asi mismo, la estructura parecida a la del directorio principal. veamos cuáles son las diferencias (cuadro 2).
Como podrá observar, la semejanza al directorio principal por parte de un directorio de usuario es bastante, ya que los dos son directorios. A continuación veamos el bloque referente a un fichero, en driver de la impresora. El bloque es cuestión es el que se encuentra en el offset $0098 con el valor $402 (en decimal 1026). El bloque cabecera de fichero contiene información parecida a los dos tipos de bloques anteriores. Veámoslo. Podrá observar una serie más o menos consecutiva de números, éstos pertenecen a la lista de bloques en el que se encuentran los datos fichero en cuestión, asimismo contiene información ya vista anteriormente. Veamos la configuración de este tipo de bloques (cuadro 3).
Cuando un fichero contiene más bloques de los que caben en el rango de los offsets dedicados a ellos se crea un bloque de extensión que contendra la continuación de serie de bloques que le faltaban al fichero. En este caso no tiene bloque de extensión, pero veremos otro ejemplo en el siguiente tipo de bloque. -$01F4 $0000037D, bloque apuntando al directorio anterior, exactamente a 'devs', ya que este bloque pertenece a la estructura del directorio. Observa que el número $037D es el mismo que contenia el anterior tipo. -$01FC $FFFFFFFD, segundo número indicando el tipo de bloque. Si lo cambiamos como negativo nos encontramos con $-3, el valor exacto perteneciente al tipo de bloque. Cuando el Amiga tiene que encontrar el nombre del fichero en cuestión para su posterior lectura, busca entre todos los bloques del directorio que tiene presente que le indica los punteros de los offsets $0018 a $0137. Cuando lo haya encontrado pasa a almacenar la cabecera del bloque que le dará toda la información vista anteriormente. Ahora pasará a la lectura del fichero y para ello chequea el número de bloques que contiene el fichero (offset $0008), almacena la lista de bloques consecutiva contenida en los offsets $0018 a $0137 (en sentido inverso), y si el fichero es lo suficientemente largo para que haya un bloque de expansión también pasa a su lectura. En el caso anterior, de que necesite un bloque de expansión para almacenar esa lista de punteros, se creará un nuevo bloque llamado simplemente de expansión de fichero. Veamos el ejemplo de mi Workbench con el fichero Preferences situado em el directorio principal. La estructura para este tipo de bloques es el cuadro 4.
El último tipo de bloque que queda es el de bloque de datos, es decir, el que realmente contiene los datos del fichero. Como dije anteriormente, 24 bytes de cada uno de estos bloque contienen información para el sistema operativo, y que en realidad se pierden, pues el nuevo (bueno, ya un poco antiguo) Fast File System lo resuelve. Para ello carga sólo en memoria toda la lista de bloques correspondiente al fichero y luego los lee todos. Esto en disco duro es enormememnte favorable, consiguiendo aceleración en lectura cuatro veces superior al sistema antiguo. La estructura para cualquier bloque de datos es el cuadro 5.
Voy a hacer un resumen viendo cómo el sistema operativo del disco lee el fichero printer.device del directorio 'devs' del Workbench. Lo primero que realiza el ordenador cuando insertamos un disco dentro del Workbench o del CLI es leer el bloque 880 para saber su nombre y que está insertado. En estos momentos el bloque es la única información que tiene el Amiga acerca del disco. Ahora para pasar al directorio 'devs' dentro del CLI entraremos el comando ya conocido de CD seguido del nombre. El amiga busca entre la tabla de bloques conteniendo punteros hacia todos los directorios y ficheros que se encuentran en el bloque 880 o directorio principal. Una vez que ya lo ha encontrado pasa a leer en memoria la cabecera del directorio encontrado. Dentro de éste hay otra lista de bloques apuntando a otros ficheros y directorios, siendo en este caso el fichero printer.device. Al igual que en el directorio principal, el Amiga busca de la misma manera y una vez que la encuentra lee el bloque en memoria. Este bloque se trata de la cabecera del fichero, conteniendo otra lista, que le sirve para leer todos los bloques pertenecientes a los datos reales del fichero. En muchos casos, ocupan más número bloques de los que se puede almacenar en la cabecera del fichero, creándose bloques de extensión. Para leer el fichero, el Amiga carga en memoria todos los punteros de los bloques de datos, y a continuación los carga uno a uno, es decir, comprobando que esos punteros corresponden con los que se encuentran dentro de cada bloque de datos. En Fast File System esto no lo comprueba, siendo su acceso a los datos muy rápido. A la hora de grabar un fichero el sistema que utiliza es sencillo. Cada disco tiene un mapa de bloques libres. Primero graba el puntero del fichero dentro de la lista del directorio en el que se encuentra en el momento. Actualiza el mapa de bloques y por último graba todos los bloques de datos. Esto último tiene un enorme inconveniente, pues sería lo más lógico actualizar el mapa de bloques libres en último lugar. Si ocurre algún gurú mientras estamos grabando un fichero aparte de que nos hemos quedado sin fichero, el sistema de validación (reactualizar el mapa de bloques libres) falla con gran asiduidad, teniendo que copiar todos los ficheros de nuevo a otro disco. Mala suerte para los que posean un disco duro original de Commodore (no he podido probar otros sistemas), pues formateándolo en FFS, si grabando un fichero se queda colgado el Amiga va a tener grandes problemas si al arrancar de nuevo se encuentra que tiene todos los bloques disponibles, aunque estén presentes todos los ficheros. Esto es debido al incorrecto sistema de validación, el cual se podría resolver si a la hora de validar el disco, por cualquier error, verificara la presencia de cada fichero reactualizando por cada uno el mapa de bloques libres. Ahora pasemos a otro tema, que es el misterioso y desconocido bootblock, que tantos quebraderos de cabeza ha traído, pues son los portadores de la mayoría de los virus. El bootblock en el Workbench tiene la misión de configurar todo el sistema (memoria, librerías, periféricos, etc.) para luego activar un CLI, carga las preferencias con el fichero system-configuration del directorio 'devs' y ejecutar el fichero startup-sequence del directorio. Técnicamente el bootblock son los bloques 0 y 1 de cada disco. Cuando insertamos el disco en el ordenador al empezar la sesión el Amiga carga estos dos bloques (1.024 bytes) en memoria de zona alta en Chip Memory. Las tres primeras largas palabras (12 bytes) son fundamentales para que el ordenador se dé cuenta de que es un disco ejecutable. La primera de ellas contiene el texto DOS seguido del byte 0, que indica el tipo de formato que lleva el disco. Los segundos cuatro bytes son el CHECKSUM o suma de chequeo, en el cual resta el valor hexadecimal $FFFFFFFF a la suma de todas las restantes largas pañlabras, para luego compararlos. Si no corresponden con el valor no continuará el proceso. La tercera palabra larga contiene el bloque donde se encuentra el directorio principal. En el momento de que el sistema cargue estos dos bloques insertará dos valores en dos registros. En A0 pondrá la dirección de ejecución (posición $C = 12 a partir del bootblock) y en D0 pondrá un valor 0 si el proceso anterior de chequeo de suma ha salido correcto. Una vez verificado todo esto el resto de 1.012 bytes contiene el programa que el ordenador ejecuta. En el momento de hacerlo el sistema tiene un registro ajustado para que lo utilice el usuario. Este es el A1, en el que apunta a una estructura IORequest perteneciente al disco, es decir la estructura encargada de realizar todos los procesos que lleva un drive (lectura, grabación, etc., de bloques). Resumiendo, el ordenador se enciende, insertamos nuestro Workbench o juego preferido, el sistema carga en una posición de zona alta de Chip Memory los bloques 0 y 1 (bootblock). Comprueba que los primeros cuatro bytes llevan el texto DOS, los segundos cuatro bytes se ajustan a la suma de chequeo y que la tercera palabra larga contiene el valor $370 correspondiente al bloque 880 o que es lo mismo, directorio principal. Una vez comprobado inserta en el registro A1 un puntero a la estructura IORequest del 'drive' y ejecuta el código restante (posición 12). Por último, vamos a ver las rutinas necesarias para leer uno o más bloques en memoria, asimismo como el de la grabación. Para ello hay que utilizar estructuras muy específicas, pero el resultado final consiste en un programa de muy fácil uso y de corto espacio. Primero veamos la rutina para la lectura del bloque 880 (ver listado 1).
El programa utiliza la estructura comentada anteriormente, IORequest, encargada de efecturar las funciones primarias de lectura, grabación, etc., de bloques. Observa cómo maneja en la parte del PROGRAMA esta estructura, insertando en los offsets $1C,$2C,$24 y $28 los valores respectivos de comando, ofset del bloque, longitud y posición de memoria del buffer para la lectura o para la grabación- En cuanto a los comandos en offset $1C existen los siguientes: 1 RESET Los que se utilizan generalmente son el 2, 3, 4 y 9. En cuanto al offset del bloque hay que
tener en cuenta una formula: 512 x (S + 11 x H + 11 x 2 x C) en la que
S es el sector, H es la cabeza y C el cilindro. Para el caso del bloque
880 (directorio principal) el sector es el 0, la cabeza 0 y el cilindro
el 40. La operación nos da el valor 450560 (hexadecimal = $6E000), para
luego insertarlo en el offset correspondiente. La longitud es en realidad
el número de loques a leer a partir del bloque indicado. Para un bloque
son 512 bytes |
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| Volver menú revistas | Volver página anterior |