en n0 Miguel Rod iló 'lo') 9088-8086/aof'i| PROG RAMACION ENSAM BLADOR EN ENTORNO MS DOS 8088-m/W Programación Ensamblador en entorno MS DOS Miguel Angel Rodríguez-Roselló Arur4tr4q ffiffigiltT{f?nf,ffi;Affi INFORMATICA PERSONAL-PROFESIONAL Diseño de colección: Narcís Fernández Diseño de cubierta: Javier David García Primera edición, 1987 Primera reimpresión, 1988 Reservados todos los derechos. Ni la totalidad ni parte de este libro puede reproducirse o transmitirse por ningún procedimiento electrónico o mecánico, incluyendo fotocopia, grabación magnética o cualquier almacenamiento de información y sistema de recuperació4, sin permiso escrito de Ediciones Anaya Multimedia. S. A. O EDICIONES ANAYA MULTIMEDIA, S. A., 1988 Villafranca. 22. 28028 Madrid Depósito legal: M. 36.796-1987 ISBN: 84-7614-128-9 Printed in Spain Imprime: Anzos, S. A. - Fuenlabrada (Madrid) lndice lt Prólogo PARTE I LOS MICROPROCESADORES 8088/8086 y 8087 Y EL LENGUAJE ENSAMBLADOR 1. t7 Conceptos básicos Sistemas de numeración, I7.-Canibios de base de numeración, I9.-Estructura de la memoria del ordenador, 20.-Suma de números binarios/hexadecimales, 22.-Números negativos, 23.-Agrupaciones superiores al byte; 25.-Tipos de datos en memoria, 25.-Operaciones lógicas, 28. ) El concepto de microprocesador Introducción, 30.-El microprocesador, 31.-El áus, 31.-Puertos y regis- 30 tros, 32.-Los microprocesadores Intel 8088 y 8086, 32,-Características generales de los microprocesadores 8088/8086, 33.-Otros microprocesadores de la familia Intel 8086, 33.-Cómo se comunica el 8088/8086, 34.-Interrupóiones, 35. 3. Introducción al lenguaje de programación ensamblador . Terminología, 36.-Direccionamiento de la memoria, 36.-Recuperación y ejecución de instrucciones, 37.-Interrupciones, 38.-Los registros internos del microprocesador, 38.-El puntero de instrucción (IP), 40.-El registro de banderas (flags), 40.-Segmentos y registros asociados, 41. 36 4. Contenido de un módulo fuente 43 Tipos de sentencias fuentes, 43.-Instrucciones, 43.-Tipos de operandos, 45.Los modos de direccionamiento, 46.-Los prefijos de segmento, 47.-Directivas, 48. 5. Constantes y operadores en sentencias fuentes 49 Constantes, 49.-Operadores, 50. 6. El aspecto de un programa ensamblador. Un programa ejemplo 7. El juego de instrucciones . . . 60 68 Clasificación de las instrucciones, 68.-Instrucciones de transferencia de datos (14), 72.-Instrucciones de manejo de bits (12), 74.-Instrucciones aritméticas (20), 76.-Instrucciones de transferencia de control (23), 76.-Instrucciones de manejo de cadenas (8), 78.-Instrucciones de control del microprocesador (12), 80.-Instrucciones de interrupción (3), 81. 8. Codificación de las instrucciones 82 Notación, 82.-Formato general de una instrucción, 83.-Ejemplos de codificación de instrucciones, 84. 9, Clasificación de las directivas . . 87 Directivas de datos. 87.-Directivas condicionales. 89.-Directivas de lista- do, 89.-Directivas de macros, 90. 10. Directivas 11. Instrucciones ... . 93 165 Abreviaturas y símbolos utilizados, 165. PARTE II APLICACIONES EN ENTORNO MS DOS 12. Arquitectura del IBM PC 295 La CPU, 295.-La memoria, 296.-Los controladores auxiliares, 296. 13. Uso de los recursos del sistema 298 La memoria del sistema (espacio direccionable), 298.-Las interrupciones, 300. Cambio de un vector de interrupción, 300. 14. Interrupciones BIOS 15. Interrupciones DOS 303 309 Las funciones DOS. 310. 16. El PSP. Comienzo y terminación de un programa 3ll 17. Herramientas de programación . 314 (MASM), El editor, 314.-El programa ensamblador 314.-El montador (LINK), 315.-El programa EXE2BIN, 315.-El gestor de librerías de objetos, 316.-El programa DEBUG, 3l7.-Ficheros BAT, 317. lE. Interfaz con subrutinas ... . Pase de pará,rnetros, 323.-Recogida de parámetros, 323.-La directiva STRUC y el manejo de parámetros, 327. 322 t9. La pantalla y sus modos de funcionamiento 330 El adaptador de pantalla, 330.-Resolución de la pantalla, 332.-El cursor, 333' Modo de funcionamiento de la pantalla, 333.-Las interrupciones asociadas a la pantalla, 334 .-Dibujo de líneas rectas, 337.-Aplicaciones, 337. 20. La pantalla en modo alfanumérico . ... 340 Páginas y bancos de memoria, 342.-Correspondencia entre la memoria de pan- talla y las posiciones de la pantalla, 344.-Aplicaciones, 345. 21. La pantalia en modo gráfico 410 Bancos de memoria, 4l0.-Representación de los pixels en la memoria de pantalla, 4l2.-Localización y acceso en la memoria de pantalla del pixel (x,y), 413' La generación de caracteres en modo gráfico, 416.-Aplicaciones, 418. ,,, El tectado 465 Combinaciones de teclas especiales, 466.-Bytes de estado del teclado, 466.Interrupciones asociadas al teclado, 467.-CódiCos generados por las operaciones, 469.-Aplicaciones, 471. 23. La impresora en modo alfanumérico ... . 486 Interrupciones asociadas a la impresora en modo alfanumérico, 487. 24. La impresora en modo gráfico 489 La memoria de impresora gráfica, 49O.-Impresión de la memoria de impreso- ra, 491 . grandes, 492.- Aplicaciones, 492. -Dibujos 25. Acceso a disco 510 Anatomía de w diskette,5lO.-Anatomía de un disco duro, 5ll.-Numeración y acceso, 512.-Areas en disco reservadas para el DOS, 512.-Mapa de un dlskette (doble cara,9 sectores/pista), 517.-Mapa de un disco duro, 518. Relación entre clusters y sectores, 518.-Subdirectorios, 5l9.-Acceso a disco desde ensamblador, 519.-Aplicaciones, 523. 26. Acceso a ficheros Registros y bloques, 540.-Areas referenciadas por el DOS, 540.-Proceso de 539 un fichero, 542.-Proceso de errores, 543.-El File Hondle,543.-Los ficheros tipo texto, 544.-Funciones DOS correspondientes a la interrupción 2lh, 545.-Aplicaciones, 555. 27. Comunicaciones serie Los dos tipos de comunicaciones, 579.-El protocolo serie asíncrono, 580.El UART, 580.-Los errores, 581.-El modem, 582.-El interfaz asíncrono RS-232, 583.-Interrupciones asociadas a la comunicación serie, 584. 579 28. El sonido y la música . 587 Funcionamiento del altavoz, 588.-Método l: Control del altavoz mediante el temporizador, 589.-Método 2: Control director del altavoz, 590.-Música, 593.-Aplicaciones, 595. 29. Conversión de datos Conversión de una cadena de caracteres ASCII a binario, 623.-Conversión de un número binario sin signo en una cadena de caracteres, 624.-Aplicaciones. 625. 622 30. Aritmética multiprecisión 635 Suma y resta, 636.-Multiplicación, 636.-División, 637.-Aplicaciones, 638. 31. Matemáticas 658 Raíz cuadrada, 658.-Números primos, 660.-Aplicaciones, 660. 32. Estructuras de datos 668 Clasificación de una lista. Método de la burbuja, 669.-Listas ordenadas. Búsqueda binaria o dicotómica, 671.-Algoritmo de búsqueda binaria en lista ordenada de forma ascendente, 671.-Aplicaciones, 672. 33. Programas residentes 685 La interrupción DOS 27h, 685.-Instalación de una rutina, 686.-Instalación de una rutina de servicio de una interrupción, 688.-La función DOS 3lh (interrupción 2lh), 690.-Aplicaciones, 691. 34. Varios 700 Otras funciones DOS (interrupción 21h), 700.-Aplicaciones, 703. 35. Interfaz con lenguajes de alto nivel 712 El interfaz, 713.-Los parámetros, 714.-Los registros, 714,-La pila, 714. 36. Interfaz con intérprete de BASIC 715 Código dentro del segmento del BASIC, 716.-Código fuera del segmento del BASIC, 7I7._MétOdO POKE, 7I8.-MétOdO BLOAD, 7I9.-MétOdO POKE dentro del segmento del BASIC, 721.-Método POKE fuera del segmento del BASIC, 722.-Mérodo BLOAD dentro del segmento del BASIC, 722.-Método BLOAD fuera del segmento del BASIC, 722.-Método de las subrutinas residentes, 7 23.- Aplicaciones, 7 24. 37. Interfaz con BASIC compilado La sentencia CALL ABSOLUTE, 734.-Método BLOAD, 734.-Método POKE, 735.-La sentencia COMMON, 735.-Metodo de las subrutinas resi- 733 dentes, 737. 38. Interfaz con COBOL 738 Aplicaciones, 738. 39. Interfaz con FORTRAN .. 742 Llamada mediante CALL, 142.-Llamada mediante una función, 743.-Aplicaciones. 744. 40. Interfaz con C . 41. Interfaz con PASCAL . .. . 42. Prograrnacién estructura Definición. 751.-La estructura DOWHILE-ENDDO. 752.-La estructura IF-ELSE-ENDIF, 7 54.-La estructura FOR-NEXT, 755.-Aplicaciones, 756. 745 747 751 PARTE III EL COPROCESADOR MATEMATICO 8087 43. El coprocesador matemático 8087 779 El coproceso, 7D.-Constantes, 780.-Arquitectura del 8087, 781.-La pila, 781. Los siete tipos de datos, 782 [Esquema de los siete formatos de datos, 784; Directivas de definición de datos, 7851.-El entorno, 786 [Palabra de estado (l), 786; Palabra de control (2),787; Palabra tag (3),788; Palabras de direcciones (4 a 7), 7881.-Tratamiento de excepciones, 788.-El juego de instrucciones del 8087, 789 [Instrucciones de transferencia de datos, 789; Instrucciones aritméticas, 789; Instrucciones de comparaci6n,T9li Instrucciones de cálculo de funciones trascendentes, 793; Instrucciones relativas a constantes, 793; Instrucciones de control del microprocesador, 7931.-Instrucciones 8087 (por orden alfabético),795.-Las versiones del programa MACRO ASSEMBLER y las instrucciones 8087. 799. Apéndice A Juego de caracteres ASCII estandar, 800.-Juego de caracteres ASCII para el IBM PC, 802.-Caracteres para el dibujo de recuadros, 804.-Caracteres de re- lleno y sombreado, 804. Apéndice B Tabla de potencias de 2, 805.-Tabla de potencias de 16, 806. Apéndice C Tablas de conversión hexadecimal/decimal. 808. Apéndice D Tiempos de ejecución de las instrucciones, 810. Apéndice E Matriz del juego de instrucciones del 8088/8086, 818. Apéndice F Algoritmo de Bresenham, 821. Apéndice G Un programa para recuperación de ficheros borrados, 827. Indice alfabético 837 Prologo PROPOSITO DEL LIBRO El propósito de este libro es ofrecer al lector en castellano una alternativa a la diversa y variada bibliografía existente en inglés en el área de la programación ensamblador del ordenador IBM PC y compatibles, reuniendo en un solo volumen la información necesaria para desarrollar aplicaciones en este lenguaje. El lenguaje ensamblador es realmente el código simbólico asociado a cada función del microprocesador del ordenador, que es donde reside la inteligencia de la máquina. Se han considerado los microprocesadores Intel 8088 y 8086, que son los más extendidos y utilizados. La diferencia entre ambos es mínima. Ambos poseen el mismo juego de instrucciones y el software escrito para uno puede funcionar en el otro sin cambios. Se han castellanizado los términos originales hasta donde ha sido posible. De todas maneras, se ha incluido (entre paréntesis) el término original inglés correspondiente a cada término en castellano. El libro pretende ser a la vez: o Una vía de aprendizaje de las posibilidades del lenguaje. Para ello, se han dividido las diferentes sentencias fuentes en grupos para proporcionar una mejor comprensión. o Una guía completa y clara del lenguaje. En este sentido, se incluyen referencias completas y separadas del juego de instrucciones y de las 11 seudooperaciones o directivas, por orden alfabético. En la explicación de cada sentencia se insertan uno o varios ejemplos de utilización. Una colección de macros y subrutinas de carácter general. Se.presentan de forma normalizada y ampliamente comentadas. Las áreas a las que se aplican son muy variadas: gráficas, aritméticas, generación de sonidos, etc. Además, las subrutinas pueden ser utilizadas también desde un lenguaje de alto nivel con pocos o ningún cambio, dependiendo del lenguaje. Una colección de programas-ejemplo en cada área de aplicación, que tienen una doble función. Por una parte, sirven para probar las macros y subrutinas anteriores. Por otra, ilustran el modo de desarrollo de programas, con especial énfasis en el diseño modular. ¿POR QUE EL LENGUAJE ENSAMBLADOR? Paradójicamente, el ensamblador es el lenguaje más básico y, sin embargo, es el más complejo. En este libro se pretende desvelar los aparentes misterios de este lenguaje de programación, haciéndolo asequible a cualquier persona con mínimos conocimientos de informática. - Vaiias son las razones para aprender el lenguaje ensambládor del IBM PC: ¡ Conocer en mayor profundidad el funcionamiento básico de la máquina. ¡ Ganar rapidez en la ejecución de los programas. ¡ Poder tener acceso a posibilidades de la máquina que son inaccesibles desde otros lenguajes. o Entender mejor cómo funcionan los lenguajes de alto nivel. r Poder utilizar las posibilidades de la máquina desde los propios lenguajes de alto nivel. ESTRUCTURA DEL LIBRO El libro se ha dividido en tres partes: o En la primera, se explica el procesador 8088/8086 y el lenguaje de programación ensamblador. Esta primera parte está preceCida por un repaso de los conceptos básicos necesarios sobre los tipos de datos, su almacenamiento y operaciones aritméticas y lógicas, así como una introducción general a los microprocesadores. Incluye también la estructura de un programa ensamblador, de los tipos de instrucciones y de las constantes y operadores que pueden aparecer en las sentencias fuentes. Se describen el formato y los tipos de directivas, divididas en diez gru12 ] pos. Las directivas suministran al ensamblador potencia y flexibilidad. Un tipo de directivas son las macros, que facilitan el desarrollo de programas. Se describen los diferentes modos de direccionamiento, el formato de las instrucciones y el juego completo de instrucciones agrupadas en siete tipos. También se trata de la filosofía de diseño modular de los programas de aplicación. Y se presenta por primera vez un programa ensamblador muy simple, que se comenta de forma general y que tiene por objeto familiarizar al lector con la estructura de un programa. Se incluye una referencia completa de las instrucciones y de las directivas. ordenadas alfabéticamente. o La segunda parte trata del desarrollo de aplicaciones en el entorno del ordenador IBM PC. Se incluyen las interrupciones BIOS y DOS. Las diferentes interrupciones se presentan agrupadas por funciones: entrada de teclado, salida por pantalla, acceso a disco, etc., en diferentes capitulos. También se presentan las herramientas necesarias para el desarrollo de programas en ensamblador: el editor, el programa ensamblador, el gestor de librerías de módulos objetos, el montador y el programa DEBUG. Se incluyen también una serie de aplicaciones, como manejo de estructuras de datos y de cadenas, gráficos por pantalla, matemática de alta precisión, manejo de ficheros, generación de sonidos, etc. En cada área de aplicación se incluyen macros y/o subrutinas, así como programas-ejemplo. Se tratan también en esta segunda parte una serie de temas especiales, como son: programaS estructurados mediante macros, programas residentes e interfaces con lenguajes de alto nivel. o La tercera parte describe el coprocesador matemático 8087. Por último, se incluye una serie de apéndices, como tablas de conversión y resúmenes. CONDICIONES PREVIAS Aunque no se presupone ningún tipo especial de conocimientos previos sobre programación, al lector con alguna experiencia en algún lenguaje (BASIC, por ejemplo) le será más fácil la comprensión de los conceptos que aparecen a lo largo del libro. En cualquier caso, es básico el haber "atertizado" en el mundo del IBM PC y poseer ciertos conceptos elementales, conceptos que de todas maneras se revisan. Para obtener el máximo provecho, sería deseable que el lector dispusiera del material siguiente: 13 ¡Un ordenador IBM PC o XT (o compatible). .El programa MACRO Assembler, con su documentación. .El manual de referencia del DOS. ¡El manual de referencia técnico del IBM PC o XT. De todas maneras, el libro puede comprenderse sin equipo fisico y sin documentación adicional. DISKETTE Las aplicaciones que se describen a lo largo de los capítulos se han registrado en el diskette que acompaia al libro. Para hacer uso del mismo, listar por pantalla el fichero LEERME. Este fichero contiene las instrucciones de instalación. 14 Parte I Los microprocesadores 8088/8806 y 8087 el lenguaje ensamblador Conceptos bás¡cos Sistemas de numeración Nuestro sistema de numeración habitual es de base l0 (o decimal), es decir: o Existen l0 dígitos (0, 1, ..., 9) posibles en cada posición del número. . Numerando de derecha a izquierda los dígitos de un número, empezando con cero, el valor de posición del dígito ¡z es l0'. Por ejemplo, 1234 en base l0 quiere decir: I x 103 +2x 102 + 3 x l0' +4x l0o Para indicar explícitamente que el número 1234 está.en base 10, lo representaremos así: 1234qrc. El ordenador está diseñado sobre la base de numeración binaria (base 2). Por tanto: o Existen 2 digitos (0 y 1) en cada posición del número. ¡ Numerando de derecha a izquierda los digitos de un número, empezando por cero, el valor de posición es 2'. 17 Por ejemplo, ll0l en base 2 quiere decir: I x23 + | x22 + 0 x 2' + L x20 : 8 + 4 + 0 + I : 13,,0. Para indicar que el número l10l está en base 2, lo representaremos como ll01,r. En general, el subíndice "(n" indica la base de numeración en que se representa un número. Si no se indica, se supone que la base es 10. En ensamblador se utiliza un lenguaje simbólico que se corresponde con las instrucciones en código (binario) de la máquina. De aquí que sea muy importante conocer cómo funciona este sistema de numeración. Cara al ordenador, es importante conocer también otras bases de numeración como: o La base 8 (octal), con los dígitos 0, l, 2, 3, 4, 5, 6 y 7. o La base 16 (hexadecimal), con los dígitos 0, 1,2,3,4, 5,6,7,8,9, A, B, C, D, E y F. Los dígitos hexadecimales A al F se corresponden con los valores decimales l0 al 15. Las bases 2, 4, 8 y 16 son equivalentes en el sentido de que es inmediato pasar de una a otra. Todo consiste en agrupar o desagrupar los dígitos binarios. Por ejemplo, para pasar de base 2 a bases 4, 8 y 16, se agrupan 2,3 y 4 dígitos binarios, respectivamente, y se convierte a continuación cada grupo de dígitos binarios al dígito de la base correspondiente: . Base2abase 4: ll0l12: l1 0l(, :311t :3x4+1 : l31ro o Base2abase 8: 110112:001 l0l(r: l5<s :8 + 5 o Base 2 abase t6: 1101,2: 110112: Drro: 13 : 13110 :13110 A la inversa, si se dispone de la representación en base 4, 8 ó 16, para pasar a base 2 basta con convertir cada dígito en un cierto número de dígitos binarios (2, 3 y 4, respectivamente). Por ejemplo: r Base 4 a base 2: l\o : ¡ Base 8 a base 2: 34,, : 0l l0(, : 11Q, : 11100(, o Base 16 a base 2: 56,,u:0101 0110r, : 10101lq, 011 100(, La base 4 no se utiliza en la práctica y bastante poco la base 8. La base l6 es muy utilizada para representar la información almacenada en la memoria del ordenador. Vamos a utilizar la notación siguiente para referirnos a los valores numéricos almacenados en la memoria, en lugar del subíndice "(n" para denotar una base ¿ cualquiera, puesto que sólo se van a usar (aparte de la decimal) las bases 2, 8 y 16 18 Sufijo Base Ejemplos b 2 o'9 0lll ll0lb 8 175q h d t6 7Dh r23d l0 Si no existe sufijo, se supone que la base es la decimal. Cambios de base de numeración Ya hemos visto que la conversión de un número dentro del entorno de las bases 2, 4, 8 y 16 es inmediata. Pero existe un procedimiento general para cambiar de una base cualquiera a otra cualquiera. Para pasar de una base cualquiera a base 10, hemos visto que basta con rcalizar la suma de los productos de cada dígito por su valor de posición: e Base 16 abase l0:4D?^ru:4x162 + 13 x l6t +2:123411s A la inversa , para pasar de base l0 a otra base, en vez de multiplicar, dividimos el número a convertir entre la nueva base. El cociente se vuelve a dividir por la base, y así sucesivamente hasta que el cociente sea inferior a la base. El último cociente y los restos (en orden inverso) indican los dígitos en la nueva base. Por ejemplo: 1234 | r0 lt4 2 77| " 13lro4 o Base l0 a base 16:. 1234,,0: 4D4,u Puesto que: 1234 :77 x 16 + 2 77: 4xl6+ 13 Se tiene: 1234: (4x 16+ 13)x 16+2:4x162 + 13x 16+2 La conversión entre dos bases cualesquiera se realiza de manera similar. 19 Estructura de la memoria del ordenador BIT . La memoria del ordenador se compone de unidades de almacenamiento llamadas bits, que tienen dos estados posibles (representados por 0 y l), es decir, sirven para almacenar números expresados en binario. La palabra bit es la contracción de binary digit (digito binario). Así pues, todo lo que reside en la memoria del ordenador (el código de las instrucciones y los datos) son números binarios en bits de la memoria, a razón de un dígito binario por bit. BYTE Los bits de la memoria se agrupan en bytes (u octetos), arazón de 8 bits por byte. Un byte es realmente la unidad de direccionamiento, es decir, podemos referirnos a cada byte mediante un número que es su dirección. Los bytes de la memoria se numeran así: el primer byte es el 0, el segundo es el l, etc. La cantidad de memoria de un ordenador se mide en Kilobytes (en abreviatura, Kbyte, Kb o simplemente K), siendo: I Kbyte : I Kb : 1024 bytes : 2'0 b¡es : 400h bytes. Por ejemplo, un ordenador con 256 Kb tiene 256 x 1024 bytes. Un b¡e puede almacenar, pues, 8 dígitos binarios, es decir, 2 dígitos hexadecimales. El número de valores posibles que se pueden almacenar es de 28 :256. Las configuraciones posibles dentro de un byte serían: 0000 0000b 0000 0001b : : 0 I llll lll0b:254 llll llllb:255Q8-l\ Los bits de un byte se numeran de derecha a izquierda del 0 al 7, es de- cir, se corresponden con los exponentes de las potencias de base 2. I 76543 0 I +número I Los valores de posición de cada bit son: m - bits Bit Valor 0 0:20: 0h 2:21 : 2h 4=22: 4h 8:23: 8h 16:24 : lOh I 2 a J I 32 :25 -- 2Oh ) 6 64 :26 : 40h 7 128 =21 :80h En el ejemplo de la figura, 01ll llOlb: 0x21 + lx26 + lx2s + lx24 + lx23 + lx22 +0x2t + lx20: :64+32+16+8+4+l:123 NIBBLE La agrupación de los 4 bits (superiores o inferiores) de un byte se llama nibble. Por tanto, un byte contiene 2 nibbles. El que corresponde a los bits 0 a 3 se llama nibble inferior, y el de los bits 4 a 7 se llama nibble stperior: 7654 321o nibble nibble superior inferior -6i¡t El nibble es una unidad de trabajo mucho más cómoda que el bit. En cada nibble se almacena un dígito hexadecimal. Los 16 valores posibles de un nibble son: Hex. Decimsl 1000 8 8 1001 9 9 l0l0 A l0 J l0l I 4 l 100 B C 5 5 l10l D 6 6 I110 E t2 l3 l4 7 7 F 15 Binqrio Hex. Decimal Binario 0000 0 0 0001 I I 0010 2 2 001 I 0100 J 1 0l0l 0l l0 0lll llll ll El número de configuraciones posibles de nibbles en un byte es de 16' :256. Las configuraciones posibles son: 00h: Olh: 0 I FEh :254 FFh : 255 (16'z-L\ Los nibbles de un byte se numeran de derecha a izquierda del 0 al l, es decir, se corresponden con los exponentes de las potencias de base 16. lrl 7 D* I 0 * número nibble Los valores de posición de cada nibble son: Nibble Valor 0 l:160= lh 16: 16' : lOh I En el ejemplo de la figura, 7Dh = 7 x 16 + 13:123. Suma de números b¡nar¡os/hexadecimales Los números contenidos en bytes, expresados en modo binario o hexadecimal, se suman de forma análoga que los de base decimal, es decir, de derecha a izquierda y arrastrando el acarreo (0 ó l) a la columna inmediata de la izquierda. Por ejemplo: 1l0l 0010b D2h +0001 0lllb + l7h l l l0 l00lb E9h La tabla de sumar en binario es: 01 0[lTTl l--+---1l I I l0 (acarreo : I sólo en el caso I + l) | La tabla de sumar en hexadecimal es: z2 A 0 I 2 J 4 5 0123456 234567 45678 6789 89A AB C 6 7 8 9 A B C D E D F 78gABCDEF 8 9 A B C D E FIO 9 A B C D E F 10 1I ABCDEFIOII12 BCDEFl0ll1213 cDEFl0ll121314 D E F l0 ll r2 13 14 15 E F l0 ll 12 13 14 15 16 10 ll 12 13 14 15 16 17 12 13 14 15 16 17 18 14 15 16 17 l8 19 16 17 18 19 lA 18 19 lA lB IA 1B IC IC ID IE F Los valores posibles de un b¡e (00h a FFh) son cíclicos, en el sentido de que, si los valores sumados exceden la capacidad del byte, el acarreo de la última columna se pierde. Por ejemplo: FFh + Olh 00h Números negat¡vos Hasta ahora hemos visto la representación de números sin signo. En un b¡e, se pueden almacenar valores ente 0 y 255 (00h y FFh). Teniendo en cuenta ef carácter ciclico de los valores de un byte en operaciones de suma, podríamos, por convenio, definir el negativo de un número como aquel que sumado a dicho número nos da como resultado 00h. En el ejemplo anterior, *1:01h y -l:FFh. La suma de ambos da cero: FFh: -l * 01h: I 00h Es decir, que FFh es 255 si se considera que en un byte sólo se pueden si se considera que en un byte almacenar números positivos, o bien es positivos negativos. o pueden números almacenar se -l Análogamente: 23 * 0:00h :0000 0000 * I :Olh :0000 0001. -l : FFh: 1ll llllb * 2:02h: 0000 0010, -2: FEh: l1l l1lOb t 3:03h:0000 0011. -3 : FDh: lll l10lb * 126 :7Eh : 0111 I ll0, -126 : 82h : 1000 0010b *127 :7Fh:0111 llll. -127 : 8lh: 1000 0001b -128 = 80h : 1000 0000b Se ve que, en todos los casos de los números negativos, el primer bit de la izquierda (bit 7) es siempre l, siendo 0 para los positivos. A este bit se le llama bit de signo. La configuración 80h es especial. Su negativo sería también 80h, puesto que 80h + 80h :00h. Por convenio, se considera negativo (valor -128), por tener el bit de signo igual a l. El cero (00h) se considera positivo, pues el bit de signo es 0. En resumen, las 256 configuraciones posibles se reparten así: o Valores positivos posibles: del 0 al o Valores negativos posibles: del al -l 127 (total,l28 valores). -128 (total, 128 valores). ¿Cómo se calcula la configuración correspondiente al negativo de un número dado? Existe una regla muy sencilla que se deduce de lo anterior: se halla el complementario de cada dígito y al número resultante se le suma uno. o El complementario de un dígito binario es I -dígito, es decir, se.cambian los unos por ceros y los ceros por unos. Dígito binorio Complementario 0 ¡ El complementario de un dígito hexadecimal es F-dígito. Dígito hex. 24 Complementorio 0 F I E 2 D J C 4 B 5 A 6 9 7 8 Como el complementario del complementario nos da el dígito original, sólo se ha incluido la mitad de los dos dígitos posibles en cada columna. Es decir, si el complementario de 7 es 8, el de 8 es 7. Ejemplo de cálculo de un número negativo: *3 03h: *3 llll 1100b*complementario FCh + lb (se le suma l) - + lh pOh:-¡ lltl llOlb:-¡ 0000 0011b: Otra manera de hacerlo es restando directamente de la manera sisuiente: 0000b -00000011b:*3 lltl llOlb:-¡ 10000 100h - 03h:*3 FDh:-3 Este procedimiento es extensible para números almacenados en campos de memoria superiores al byte. Hay que señalar, por último, que el ordenador no "sabe" restar. Para calcular X-Y, lo que hace es obtener el negativo de Y y luego se lo suma aX. Agrupac¡ones super¡ores al byte Son las siguientes: Tipo Definición Palabra Doble palabra Cuádruple palabra 2 bytes contiguos Párrafo l6 bytes Página 256 bytes 64 Kbytes Segmento 2 palabras contiguas (8 bytes) 4 palabras contiguas (8 bytes) Tipos de datos en memor¡a NUMEROS BINARIOS Pueden ser con signo y sin signo y ocupan desde 1 byte hasta 4 palabras. Para los números binarios positivos, los valores máximos que se pueden almacenar son: Valor máximo Tipo byte palabra tloble palabra cuádruple palabra 162 164 168 - = FFh = FFFFh = FFFFFFFFh :255 :65 535 : 4 294 967 295 : 18 446 744 073 709 551 615 : FFFFFFFFFFFFFFFFh - L6t6 Para los números binarios negativos, los valores máximos y mínimos son: Valor máximo (positivo) Tipo byte palabra tloble palabra cuádruple palabra = Fh : TFFFFh : FFFFFFFh :127 z'i3l a63 = TFFFFFFFFFFFFFFFh :9 223 372 036 854 775 807 a7 Valor mínimo (negativo) Tipo br4e palabra doble palabra cuádruple palabra =32767 = 2 147 483 &7 80h -22 =:8000h -215 -23t:80000000h - 263 = 800000000000O000h : -128 : -32 768 = -2 147 483 648 : -9 223 372036 854 775 808 Los números binarios se almacenan (cuando su longitud es superior al byte) al revés de lo que cabría esperar. Por ejemplo, en el caso de una palabra, el primer byte contiene el valor menos significativo. Esto tiene la ventaja de que siempre, independientemente de la precisión del número, los dos caracteres hexadecimales menos significativos del número se encuentran en el primer byte. Esto es muy útil cuando se pasan parámetros. Tipo byte palabra doble palabra cuádruple palabra Almacenamiento Vslor 0 h 0 23h 0 234567h 0l 0 23456789ABCDEFh EF CD AB 89 67 45 23 01 23 0l 67 45 23 0l NUMEROS DECIMALES DESEMPAQUETADOS Cada byte contiene un dígito BCD en los 4 bits inferiores (nibble inferior). Los 4 bits superiores son cero (nibble superior). Cada byte puede almacenar un valor del 0 al 9 (dígito decimal). n Los dígitos BCD (Binary-Coded Decimal o decimal codificado en binario) tienen la codificación sisuiente: Dígito BCD 0 0000 I 0001 2 0010 J 001 I +^ 0100 ) 0l0l 6 0l l0 7 0lll 8 1000 9 l00l Por ejemplo, el número 1234 se almacena en 4 bytes como 01020304h. NUMEROS DECIMALES EMPAQUETADOS Cada byte contiene dos dígitos BCD. El dígito más significativo se almacena en el nibble superior. Cada byte puede almacenar un valor del 00 al 99 (dos dígitos decimales). Por ejemplo, el número 1234 se almacena en 2 bytes como 1234h. CARACTERES ASCII Además de para representar valores numéricos, los bytes se usan para representar caracteres. Cada b¡e puede representar 256 caracteres posibles: o Los 128 primeros (0 a 127) son los caracteres ASCII estándar. o Los 128 últimos (128 a 255) son los caracteres ASCII extendidos para el caso IBM PC. El código ASCII (Americon Standard Code for Information Inter- change) es un convenio adoptado para asignar a cada carácter un valor nu- mérico. El código ASCII incluye: o Letras mayúsculas y minúsculas. o Dígitos decimales (0 al 9). r Caracteres especiales como *, >, <, +, etc. ¡ Códigos de control (los 32 primeros, del 0 al 3l), que tienen dos usos: 27 a) b) Por una parte, tienen el significado ASCII estándar, es decir, códigos de control de impresión y de comunicaciones), como l3 (retorno de carro), 12 (alimentación de página), etc. Por otra parte, se utilizan para representar en pantalla caracteres especiales (símbolos de la baraja, musicales, flechas, etc.). Los caracteres ASCII extendidos incluyen: o Símbolos para el dibujo de recuadros. o Símbolos de relleno y sombreado. . Letras griegas. o Símbolos científicos. r Caracteres especiales en idiomas distintos del inglés. En el apéndice A se incluye la tabla completa de los códigos ASCII estándar y el juego de caracteres para el IBM PC. Operaciones lógicas Se realizan a nivel de bit. Pueden ser de un solo operando o de dos ope- randos. OPERACION LOGICA "NO'' (NOT) Es una operacion lógica de un solo operando definida así: x NOT(x) 0 I I 0 Evidentemente, se cumple que NOT(NOT(x)) : ¡. De acuerdo con la definición de número negativo, se cumple que: -n: NOT(n) + I NOT(n): -n-l Ejemplos: NOT(101lb) :61966 n NOT(Bh) :4h NOT(I1) : 4 I OPERACIONES LOGICAS "Y" (AND), "O" (OR) Y "O EXCLUSIVO'' (XOR) Son operaciones lógicas de dos operandos. Las definiciones son: xy 00 0l l0 l1 Es decir: AND vale OR vale XOR vale xANDy xORy xXORy 0 0 0 0 0 I I I I I I 0 cuando ambos operandos son l. cuando alguno de los operandos sea l. cuando ambos operandos son distintos. Ejemplos: l0llb AND 0llOb :0010b Bh AND 6h:2h l0llbOR 0llOb:llllb BhOR 6h:Fh l0llb XOR 0llOb: 1101b Bh XOR 6h: Dh AND 6:2 oR 6: 15 XOR 6: 13 RELACIONES ENTRE LAS OPERACIONES LOGICAS Evidentemente, existen relaciones entre las operaciones lógicas definidas anteriormente. Por ejemplo, las leyes de De Morgan: NOT(x AND Y) : NOT(x) OR NOT(Y) NOT(x OR Y) : NOT(x) AND NOT(Y) O lo que es lo mismo: x AND Y: NOT(NOT(x) OR NOT(y)) x OR y: NOT(NOT(x) AND NOT(y)) Lo cual quiere decir que: AND puede expresarse mediante OR y NOT. OR puede expresarse mediante AND y NOT. También la operación XOR puede expresarse mediante las restantes: x XOR y: (NOT(x) AND y) OR (x AND NOT(y)) 29 El concepto de microprocesador Introd ucción Vamos a repasar brevemente los conceptos básicos de un microordenador. Un ordenador es una máquina de tratamiento automático de la información que manipula señales eléctricas digitales binarias (0 y l) y cuyos componentes son: . La unidad central de proceso (CPU). r La memoria. : i:: ;:ljl:'*':l'ln,,.u¿uz,a,ida La CPU realiza tareas de control y cálculo. Se compone de: ¡ La unidad de control. Interpreta las instrucciones y genera las órdenes para que se ejecuten. ¡ La unidad de cálculo (aritméticológica). Siguiendo las órdenes generadas por la unidad de control, recibe los datos de la memoria, opera con ellos y almacena el resultado en la memoria. Los cáLlculos son de tipo aritmético o lógico. La memoria contiene los datos de entrada/salida y el programa a ejecu- tar. El ordenador sólo entiende secuencias determinadas de valores bina30 rios. Por eso, toda información destinada a ser procesada por el ordenador debe traducirse, en último término, a binario. El ordenador sólo ejecuta órdenes elementales. Un conjunto de estas órdenes elementales ordenadas consecutivamente se llama programa. Un controlador constituye el interfaz entre el ordenador y una determinada unidad de entrada/salida. Las unidades de entrada,/salida contiendn los datos a procesar. El microprocesador Un microprocesador (¡rP) es un procesador en un solo chip (pastilla de circuito integrado). Es la unidad central del proceso (CPU). El microprocesador está conectado a un oscilador (o reloj) que genera impulsos igualmente espaciados en el tiempo. Su frecuencia base es de 14,31818 Mhz (millones de ciclos por segundo). El microprocesador generalmente divide esta frecuencia base por una constante para implementar un ciclo de máquina. Por ejemplo,4,77 Mhz es un tercio de la frecuencia base. Cada instrucción que ejecuta el microprocesador consume un número determinado de ciclos de'máquina. El bus El bus es simplemente un canal de comunicación entre todas las unidades funcionales del sistema. La interconexión entre estas unidades se realiza al "pinchar" o "colgar" cada unidad al bus. Cuando se añade una nueva unidad, se conecta en una de las ranuras (slots) de expansión, conectada directamente al bus. Un bus se compone de varias líneas o hilos (uno por bit) por el que circula un cierto tipo de información. Hay tres tipos de buses, según la información que circula por el mismo: o Bus de datos. o Bus de direcciones. o Bus de control. E'l bus de datos Funciona en conjunción con el bus de direcciones para transmitir datos. E/ bus de direcciones Son n lineas de señales para transmitir las direcciones de las posiciones de memoria y de los dispositivos conectados al bus. Puesto que cada línea puede tener dos valores posibles (0 y l), se pueden especificar 2' direcciones distintas. 31 ,E/ bus de control Son una serie de líneas que sirven básicamente para indicar el tipo de información que viaja por el bus. En la figura siguiente vemos cómo están interconectados los diferentes elementos de un microordenador: Bus de direcciones B¡zs de datos Bus de control C : controlador de la unidad de entrada/salida. M : memoria. CPU : unidad central de proceso. Puertos y reg¡stros Cuando la información se transmite de un componente a otro, viaja por el bus desde el componente fuente al de destino, almacenándose temporalmente en puertos y registros. Un puerto de E/S es una vía de comunicación con otros componentes del ordenador (excepto la memoria). Como las posiciones de memoria, cada puerto se identifica mediante una dirección, pudiéndose leer datos de un puerto o escribir datos sobre ella. Cuando un dato está preparado para ser transmitido, primero se envía su dirección de destino por el bus de direcciones, y a continuación se envía el dato por el bus de datos. Los microprocesadores Intel 8088 y 8086 El microprocesador Intel 8088 es de 8 ó 16 bits, según el punto de vista: o El bus de datos es de 8 bits, es decir, los datos se transmiten byte a byte. o El bus de direcciones es de 20 bits. Los ocho primeros bits del bus de direcciones es el óas de datos. Los cuatro primeros bits contienen el estado (status). Con los 16 bits se pueden direccionar solamente 64 Kb. Pero gracias a la utilización de dos registros internos de 16 bits se pueden direccionar hasta I Mb (20 bits) de posiciones de memoria. n El microprocesador 8086 es idéntico al 8088 funcionalmente, pero el bus de datos es de 16 bits, es decir, sólo es necesaria una operación para transferir 2 bytes (l palabra). Del 8086 se puede decir que es realmente un microprocesador de 16 bits. Desde el punto de vista de programación, es idéntico al 8088. El 8088 necesita más tiempo que el 8086 en una transferencia de 16 bits, al tener que hacerla en dos transferencias separadas de 8 bits cada una, mientras que el 8086 la realiza de una sola vez. Características generales de los microprocesadores 8088/8086 Los bytes y las palabras pueden residir en cualquier dirección de memoria (no es necesario ajuste a frontera). Tipos de números con los que puede operar: . Binarios (con o sin signo, de 8 ó 16 bytes). . Decimales (empaquetados o no). a Existen 92 tipos de instrucciones. Existen 7 modos de direccionamiento. a Dentro de la familia de microprocesadores 8088/8086, las frecuencias del reloj interno más comunes son: a . 4,77 MHz: 4,77 mlllones de ciclos/seg. (8088). . $ MHz: 8 millones de ciclos/seg. (8086). o Duracción de un ciclo (período T): . Para f :4,77,T : l/4770000: 210 nanoseE.:210 x l0-eseg. . Para f:8, T: l/8000000:125 nanoseg.:I25 x lO-eseg. Las instrucciones más rápidas se ejecutan en 2 ciclos. Las instrucciones más lentas requieren 206 ciclos. Se pueden direccionar hasta 64K puertas de E/S. Otros microprocesadores de la familia Intel 8086 80188 y el 80186, versiones avanzadas del 8088 y 8086, respectivamente. a 8088-2 y 8086-2 (8 MHz). a 80C88 (4,77 MHz). *l o 80286, que tiene capacidad de proceso multitarea y almacenamiento de memoria virtual, conceptos asociados a los ordenadores grandes (moinframes). El proceso multitarea es la capacidad de la CPU de realizar varias tareas al mismo tiempo. El 8088/8086 puede realizar multitarea con la ayuda de softwore, alternando de un proceso a otro. Pero un procesador multitarea realiza el cambio de una tarea a otra internamente y con la ayuda del sistema operativo, procedimiento más fiable. La memoria virtual permite a un ordenador funcionar como si tuviera más memoria de la realmente presente. Mediante cierto diseño de hardware y software se puede direccionar un espacio que físicamente se localiza parte en memoria y parte en disco. El 80286 puede funcionar a 6, 7, 5 u 8 MHz. Un programa desarrollado para el 8088/8086 funciona sin cambios en un entorno 80286, pero este microprocesador posee instrucciones adicionales. Existen también dos procesadores especiales opcionales: . 8087 o coprocesador matemático, que permite hacer cálculo con nú- meros de punto flotante. Existe zócalo en la placa base para este coprocesador. Existe la versión del 8087 que funciona en conjunción con el 80286, que es el 80287. . 8089 o coprocesador de entrada/salida, con el que IBM no suministra circuitería. Cómo se comunica el 8088/8086 El 8088/8086 se comunica con el exterior de tres maneras: 'o Mediante acceso (directo o indirecto) a memoria. El acceso directo se logra a través del controlador DMA (Direct Memory Access). Las unidades de disco y las puertas de comunicación serie pueden acceder a la memoria directamente a través de este controlador. El acceso indirecto se logra a través de los registros internos que se utilizan para transferir datos a/desde memoria. ¡ A través de puertas de entrada/salida. Es el medio normal de comunicación del 8088/8086 con otros procesadores. o Mediante interrupciones. u Interrupciones Son señales que se le envían a la CPU para que termine la ejecución de la instrucción en curso y atienda una petición determinada. Hay cuatro tipos de interrupciones: r Interrupciones hardware. Son las generadas por la circuitería del ordenador en respuesta a algún evento como pulsar una tecla del teclado. Este tipo de interrupciones la maneja el controlador de interrupciones, que establece la prioridad antes de enviar la señal a la CPU. o Interrupciones internas. Son las generadas por la propia CPU cuando se produce una situación anormal, como, por ejemplo, una división por cero. . Interrupciones software. Son las generadas por el propio programa para invocar a ciertas rutinas almacenadas en memoria (ROM o RAM). Es posible cambiar estas rutinas a desarrollar otras nuevas. . Interrupción no enmascarable. Se usa para pedir la atención inmediata de la CPU en situaciones de emergencia, como caída de voltaje o error de paridad de memoria. Cada interrupción lleva asociado un número que identifica el tipo de servicio que debe realizar. A partir del número de la interrupción calcula la dirección de la rutina que realiza el servicio requerido, la ejecuta y retorna a la instrucción siguiente a la última que ejecutó antes de que se produjera la interrupción. 35 lntroducción al lenguaje de programación ensamblador Terminología El término original Assembly denota el lenguaje simbólico que corresponde a las instrucciones del microprocesador. El término Assembler se refiere al programa que convierte los nombres simbólicos de las instrucciones en código máquina. En castellano, vamos a usar el término "Ensamblador" para referirnos, sin distinción, a ambas cosas, es decir, al lenguaje fuente y al programa que genera el código objeto. Direccionamiento de la memoria Con dos bytes (una palabra) se pueden direccionar: 256*256:64 (4x256):64x 1024:64Kb (0 a 65535 : FFFFh) Para superar este límite, se utilizan dos registros: o segmento, . desplazamiento (offsel, dirección relativa o dirección efectiva, 36 de tal manera que la dirección completa es: 16 x segmento * desplazamiento : lOh x segmento + desplazamiento Realmente no se multiplica por 10h, sino que se desplazan 4 bits (un nibble) a la izquierda del registro de segmento: XXXX0 (hex) desplazamiento: YYYY (hex) + dirección ZZZZZ (hex) segmento La dirección completa es de 5 (nibbles) x 4 (bits/nibble): 20 bits, que es la longitud del bus de direcciones. Mediante este sistema es posible direccionar: 16 x 64Kb : 1024Kb : 1 Mb : 165 que corresponden a las direcciones 0 a FFFFFh. Cada segmento puede ser de hasta 64 Kb de longitud y comienza en una posición que es múltiplo de 16: lOh. Esta dirección se llama también párrafo del segmento. Una dirección de memoria tiene, pues, dos componentes y se expresa simbólicamente de la forma segmento : desplazamiento y también segmento : Idesplazamiento] y se llama también dirección completa, dirección segmentada o vector de dirección. Una dirección de memoria puede expresarse de distintas formas. Por ejemplo, las siguientes direcciones (en hexadecimal) son equivalentes: 100: 50 : 1050 : 105 :0 : 0: 1050 : l0:950 Recuperación y ejecución de instrucciones El ciclo de ejecución de las instrucciones de un programa consta de dos fases. La primera fase consiste en la recuperación de una instrucción. La se- gunda fase es la ejecución en sí. Con objeto de optimizar estos dos procesos, el microprocesador posee dos unidades separadas: g7 r Para recuperación de instrucciones: BIU (Bus Interface Unit). ¡ Para ejecución de instrucciones: EU (Execution Unit). Existe lógicamente una comunicación entre la BIU hacia la EU, es decir, que la instrucción recuperada por la BIU se la pasa a la EU para que la ejecute. Mientras se ejecuta la instrucción, el BIU recupera la siguiente en memoria, que será la que se ejecute a continuación (si no hay bifurcación)' lnterru pc¡ones Una interrupción es un suceso que hace que el microprocesador pare la ejecución del programa en curso para atender otra actividad requerida. Existen dos tipos de interrupciones: o Externas (provocadas por los periféricos del ordenador)' o Internas (generadas por el propio microprocesador cuando ocurren ciertas condiciones especiales). Los tipos de interrupciones internas son cinco: 0 - Error en división. I - Paso a paso (modo depuración de programas). 2 - No enmascarable (no se puede desactivar por programa). 3 - Sirve para indicar puntos donde debe pararse el programa (modo depuración de programas). 4 - Desbordamiento (overflow). Se dispara por la instrucción INTO (interrupció n si ov e rfl ow). Existen en total 256 interrupciones (códigos 0 a255). Mediante este código se apunta a una tabla de vectores de interrupción. Cada vector de interrupción contiene la dirección de la rutina de tratamiento de la interrupción (rutina de servicio de la interrupción). Algunas de las interrupciones Se reservan para el BIOS (Basic Input Output System) y otras para el sistema operativo (DOS) o el BASIC. Los registros ¡nternos del microprocesador Son catorce registros, todos de 16 bits (una palabra). Los bits se numeran de derecha a izquierda. El bit 0 es el menos significativo. F E DC B A 9 8 7 6 5 4 3 2 I O+bits(hex) 38 Existen: ¡ Cuatro registros de datos o de almacenamiento temporal. AX: Acumulador. Es el registro principal utilizado en las instrucciones aritmé- ticas. BX : Base. Se usa para indicar un desplazamiento (offset). CX : Contador. Se utiliza como contador en los bucles y en las operaciones de tipo repetitivo. DX: Dato. Se usa también en operaciones aritméticas. Es posible referirse al b¡e superior (más significativo) o al byte inferior (menos significativo) en los registros AX, BX, CX y DX: Registro Byte superior (bits 15 o 8) Byte inferior (bits 7 a 0) AX AH AL BX BH BL CX CH DL DX DH DL F E D C B A 9 8 7 6 5 4 3 2l 0 -bits(hex) o Cuatro registros de segmentos. Contienen la dirección de comienzo de ciertos segmentos de memoria. CS : Registro de segmento de código (code segment). Contiene la dirección del segmento de código, es decir, las instrucciones del programa. DS : Registro de segmento de datos (data segment). Contiene la dirección del segmento de datos, es decir, el área de memoria donde se encuentran los datos del programa. SS : Registro de segmento de pila (stak segment). Contiene la dirección del segmento de pila. La pila es un espacio de memoria temporal que se utiliza para almacenar valores de 16 bits (palabras). ES : Registro de segmento extra (extra segment). Contiene la dirección del segmento extra, que es un segmento 39 de datos adicional que se utiliza para superar la limitación de los 64 Kb del segmento de datos y para hacer transferencia de datos entre segmentos. ¡ Dos registros punteros de la pila. SP (Stack Pointer) - Puntero de la pila. Contiene la dirección relativa al segmento de pila. BP (Base Pointer) - Puntero base. Se utiliza para fijar el puntero de la pila y asi poder acceder a los elementos de la pila. o Dos registros índices. Se utilizan como desplazamiento relativo a un campo de datos. Sl (Source Index) - Indice fuente. DI (Destinotion Index) - Indice destino. o Un registro puntero de instrucciones. IP (Instruction Pointey'. Puntero de instrucción. ¡ Un registro de banderas (flogs). El puntero de instrucción (lPl También llamado contador de programa (Program Counter, PC), contiene el desplazamiento de la instrucción siguiente a ejecutar respecto al segmento de código del programa en ejecución. En conjunción con el registro CS, indica la dirección completa de la siguiente instrucción a ejecutar, es decir, CS:IP. Los programas no pueden manejar directamente a este registro, pero si lo pueden hacer de forma indirecta mediante instrucciones de bifurcación. Ef registro de banderas (flags) Cada bandera (flag) es un bit y se usa para registrar la información de estado y de control de las operaciones del microprocesador. Hay nueve banderas (los 7 bits restantes del registro no se utilizan): . Seis banderas de estado. Registran el estado del procesador, normalmente asociado a una comparación o a una instrucción aritmética: N CF (Carry Flag) OF (Overflow Flog) ZF (Zero Flag) SF (Sign Flag) PF (Parity Flag) AF (Auxiliar Flog) Bandera de acarreo. Indica acarreo en las instrucciones aritméticas. Bandera de desbordamiento (aritmético). Bandera de resultado cero o comparación igual. Bandera de resultado o comparación negativa. Bandera de paridad (número par de bits). Bandera auxiliar. Indica si hay necesidad de ajuste en las operaciones aritméticas con números BCD (decimal codificado en binario). Tres banderas de control. Registran el modo de funcionamiento del procesador. DF (Direction Flag) - Bandera de dirección. Controla la dirección (hacia adelante o hacia atrás) en las operaciones con cadenas de caracteres incrementando o decrementando automáticamente los registros índices (SI y DI). lF (Interrupt Flag) - Bandera de interrupciones. Indica si están permitidas o no las interrupciones de los dispositi- TF (Trap Flag) vos externos. - Bandera de atrape. Controla la operación modo paso a paso (usada por el programa DEBUC). Las posiciones de las banderas dentro del registro son: 15 t4 13 12 ll l0 9 8 7 6 5 OF DF IF TF SF ZF 4 AF PF CF Segmentos y reg¡stros asociados Un programa consta de cuatro tipos de segmentos. Cada segmento se direcciona mediante un determinado tipo de registro de segmento. e Segmento código. Cada instrucción se direcciona mediante: registro de segmento: CS. registro de desplazamiento: IP. o Segmento datos. Los datos se direccionan mediante: registro de segmento: DS. registros de desplazamientos: BX, SI o DI. 41 . Segmento pila. Los datos se direccionan mediante: registro de segmento: SS. registros de desplazamiento: SP o BP. . Segmento extra. Igual que el de datos, sustituyendo DS por ES, es decir: registro de segmento: ES. registros de desplazamiento: BX, SI o DI. Estas asignaciones por defecto se pueden modificar, como veremos. 42 Contenido de un módulo fuente Tipos de sentencias fuentes Un programa fuente ensamblador contiene dos tipos de sentencias: I INSTRUCCIONES Son representaciones simbólicas del juego de instrucciones del microprocesador. , DIRECTIVAS, SEUDO-OPERACIONES o SEUDO-OPS Indican al ensamblador qué hacer con las instrucciones y los datos. Las instrucciones se aplican en tiempo de ejecución. Las directivas se aplican en tiempo de ensamblaje del programa. fnstrucciones _ El formato de una instrucción es el siguiente: [etiqueta] nombre_instrucción [operandos] [comentario] Los corchetes indican que el campo correspondiente es opcional. De estos cuatro campos, sólo "nombre_instrucción" es obligatorio. ¿|(l La instrucción se especifica en una sola línea. Los campos se separan entre sí por al menos un blanco. Ejemplo: MOVER: MOV AX,300 ; poner contador etiqueta .. .. : MOVER: nombre instrucción: MOV operandos ..:AXy300 comentario . .: ; poner contador CAMPO ETIQUETA Es el nombre simbólico de la primera posición de la instrucción. Puede tener hasta 31 caracteres. Los caracteres pueden ser: o Letras AaZ (las minúsculas se convierten a mayúsculas). ¡ Números 0 al9. o Caracteres especiales @ - . $ El primer carácter no puede ser un dígito. Si se usa el carácter ".", debe especificarse el primero. No se pueden usar los símbolos: AX, AH, AL, BX, BH, BL, CX, CH, CL, DX, DH, DL, DI, SI, DS, ES, SP, BP. No se pueden usar nombres de instrucciones ensamblador. La etiqueta puede tener o no el carácter "i" como sufijo. o Con "1", el atributo de la etiqueta es NEAR. Esto quiere decir que se va a referenciar a la instrucción desde dentro del mismo segmento de código. El microprocesador debe cargar sólo el registro IP (Instruction Pointer) al bifurcar a esa instrucción. . Sin ":", el atributo de la etiqueta es FAR. Esto quiere decir que se va a referir a la instrucción desde otro segmento de código. El microprocesador debe cargar los registros IP y CS al bifurcar a esa instrucción. Si se intenta transferir el control a una etiqueta FAR dentro del mismo segmento, se produce un error. 4 CAMPO NOMBRE Es el nombre simbólico de la instrucción. Es de dos a seis letras. Ejemplos: IN, ADD, PUSH, PUSHF, LOOPNE. CAMPO OPERANDOS Indica dónde se encuentran los datos. Puede haber 0, I ó 2 operandos. Si hay dos operandos, el primero se llama destino, y el segundo, fuente, y deben separarse por una coma. Ejemplos: PUSHF PUSH AX ; ningún operando ; un operando MOV AX,BX ; dos operandos (destino : AX, fuente: BX) CAMPO COMENTARIO Debe empezar por Ejemplo: ";". MOV AX,O ; borrar registro. También se puede especificar una línea completa de comentario si ";" se sitúa en la columna l. Tipos de operandos Los operandos de las instrucciones pueden ser: o Registro. Puede ser de 8 ó de 16 bits. Notación: reg8 indica registro.de 8 bits. regl6 indica registro de l6 bits. ¡ Memoria. puede r.. iltr.Til?ffi:istro de 8 ó de 16 bits' Notación: mem8 indica byte (8 bits). mem16 indica palabra (16 bits). mem indica b¡e o palabra (8 ó 16 bits). ¡ts o Valor inmediato (dato). Puede ser de 8 ó de 16 bits. Notación: valS indica valor que puede almacenarse en 8 bits. vall6 indica valor que puede almacenarse en 16 bits. val indica valor que puede almacenarse en 8 o en 16 bits. Los modos de direcc¡onamiento Los operandos de las instrucciones pueden ser de siete tipos distintos. Son los llamados modos de direccionamiento. En los ejemplos que siguen estos modos están expresados en el segundo operando (operando fuente). Los siete modos de direccionamiento son: N. o Modo Operando Reg. Ejemplos I registro registro MOV AX,BX 2 valor MOV AX.500 valor DS MOV AX,TABLA 3 directo variable 4 indirecto me- tBXl DS MOV AX,[BX] SS MOV AX,[BP] diante regis- tBPl DS MOV AX,[DI] tro [DII DS MOV AX,[ST tSI] 5 relativoabase [BX] + desp. DS MOV AX,[BX] + 4 SS MOV AX,[BP] + 4 [BP] + desp. DS MOV AL,TABLA[DI] 6 directo inde- [DI] + desp. DS MOV AL,TABLAISII xado [SI] + desp. 7 indexado a [BX][SI] + desp. DS MOV AX,TABLAIBXIISII base tBXltDIl + desp. DS MOV AX,TABLAIBXIIDII tBPltSIl + desp. SS MOV AX,TABLAIBPI[SI] tBPllDIl + desp. SS MOV AX,TABLAIBPI[DI] Observaciones: o La columna "Reg." se refiere al registro de segmento por defecto. o Como se ve, el microprocesador supone: . DS si el desplazamiento (offiel,/ se expresa con BX, SI o DL . SS si el desplazamiento (offsel,/ se expresa con BP o SP. o Los modos 3 a 7 se refieren a direcciones de memoria. o Especificar un nombre de variable (TABLA en este caso) es equiva- 6 lente a especificar el desplazamiento de la variable dentro del segmento en el que está definido. Por tanto, ejemplos alternativos de los modos 6 y 7 son, respectivamente: MOV AL,[DI] + 4 MOV AX,[BX][Sr] + 4 No se interpreta de la misma forma el modo 3, en que el operando es un valor inmediato (es decir, se especifica en la propia instrucción) y no una dirección de memoria. o En el modo 2, un valor inmediato puede ser: MOV AX,K si K se ha definido como un símbolo K EQU 500 ¡ En el modo 5, las siguientes instrucciones son equivalentes: MOV AX,[BX]4 MOV AX,[BX] + 4 MOV AX,4[BX] MOV AX,[BX + 4l o En el modo 7, las siguientes instrucciones son equivalentes: MOV AX,4[BX][Dr] MOV AX,[BX + DI + 4] MOV AX,[BX + 4][DU MOV AX,[BX][Dr + 4l Los prefiios de segmento Los modos de direccionamiento 3 a 7, es decir, los que se refieren a direcciones de memoria, pueden estar precedidos por un registro de segmen- to. Por ejemplo, MOV AX,ES:TABLAISII Esto quiere decir que el registro de segmento correspondiente al operan- do TABLA[SI], que por defecto es DS, será sustituido por el registro de segmento ES. El código que se genera para la instrucción está precedido por un byte, que se llama código de prefijo de segmento. La tabla siguiente relaciona las posibles combinaciones entre los cuatro registros de segmentos y los seis registros de desplazamiento. 47 CS SS DS ES IP SI no no no SP no SI no no BP prefijo por defecto prefijo prefijo BX prefijo prefijo por defecto prefijo SI prefijo prefijo por defecto prefijo DI prefijo prefijo por defecto por defecto (cadenas) Veremos que las operaciones relativas a cadenas (strings) utilizan ciertas combinaciones de registros, como son DS:SI y ES:DI. Existe una directiva (ASSUME) que asocia un registro de segmento con un determinado segmento de código o datos, de modo que en las instrucciones cuyos operandos hagan referencia a campos de ese segmento les incluye automáticamente el prefijo de segmento, a menos que coincida con el registro de segmento por defecto, en cuyo caso no se incluye. Directivas El formato de una sentencia directiva es: [nombre] nombre-directiva [operandos] [comentario] De estos cuatro campos, sólo "nombre_directiva" es obligatorio. La directiva se especifica en una sola línea. Los campos se separan entre sí por al menos un blanco. Ejemplo: CIR EQU 13 ; retorno de carro (asigna el nombre CR al valor 13) La sintaxis de "nombre" se corresponde con "etiqueta" de las instrucciones, sólo que no existe el sufijo ":". El campo "comentario" es análogo al de las instrucciones. ¡tB Gonstantes y operadores en sentencias fuentes Las sentencias fuentes (tanto las instrucciones como las directivas) pueden contener constantes y operadores. Constantes Existen cinco tipos: l. Binario. Ejemplo: l0l lb 2. Decimal. Ejemplo: l29d (la letra "d" es opcional). i5. Carácter. Ej:ilif; ?trii.$:.r::!;.'Ji,?;"'3;?:;,l'l'?);,,, "ABC" Hexadecim"' Ejemplos: (las comillas pueden ser simples o dobles). "Dije 'Buenos días' " 'Dije "Buenos dias" ' El sufijo puede ser en mayúscula o minúscula. Es posible especificar números negativos. Si el número es decimal, se precede del signo menos. Si es binario, hexadecimal u octal, hay que especificar su complemenia a2'. Ejemplo: 32 = 00100000b : 20h:40q : : -32, = I I 100000h EOh 340q ¡t9 Operadores Un operador es un modificador que se usa en el campo de operandos de una sentencia ensamblador. Se pueden utilizar varios operadores y combinarse entre sí en una misma sentencia. Hay cinco clases de operadores: ¡ Aritméticos. Operan sobre valores numéricos. . Lógicos. Operan sobre valores binarios bit a bit. o Relacionales. Compara dos valores numéricos o dos direcciones de memoria del mismo segmento y produce: 0 - si la relación es falsa. 0FFFFh - si la relación es verdadera. o De retorno de valores. Son operadores pasivos que suministran información acerca de las variables y de las etiquetas del programa. o De atributos. Permiten redefinir el atributo de una variable o de una etiqueta. Los atributos para variables de memoria son: BYTE : b}4e. WORD : palabra. DWORD: doble palabra. TBYTE : diez bytes. Los atributos para etiquetas son: NEAR: se puede referenciar desde dentro del segmento en que está definida. FAR : se puede referenciar desde fuera del segmento en que está definida. OPERADORES ARITMETICOS Operador: t Formato: valorl + valor2. Función: Suma valorl v valor2. Ejemplo: TABLA*MAS-2 DW TABLA + 2 50 (desplazamiento de TABLA) + 2 l Operador: - Formato: valorl - valor2 Función: Resta valor2 de valorl. Ejemplo: DIFER DW TABLAI-TABLA2 ; (desp. de TABLAI) ; (desp. de TABLA2) Operador: * Formato: valorl * valor2 Función: Multiplica valor2 por valorl. Ejemplo: MINS-DIA EQU 60*24 ; minutos de un día Operador: / Formato: valorl / valorZ Función: Divide valorl entre valor2 y retorna el cociente. Ejemplo: PLCOCIEN EQU 31416/1C0l00 ; el valor es 3 Operador: MOD Formato: valorl MOD valor2 Función: Divide valorl entre valor2 v retorna el resto. Ejemplo: PI-RESTO EQU 31416/10000 ; el valor es 1416 Operador: S}{L (SHift Left) Formato: valor SHL expresión. Función: Desplaza a la izquierda "valor" el número de bits que indica "expresión". Ejemplo: MASCARA EQU I l00l0b MASCARA-IZQ-2 EQU MASCARA SHL 2 ; 11001000b 51 Operador: SHR ls¡Irl Right) Formato: valor SHR expresión. Función: Desplaza a la derecha "valor" el número de bits que indica "expresión". Ejemplo: MASCARA EQU MASCARA_DER_2 EQU I l00l0b MASCARASHR2 : ll00b OPBRADORES LOGICOS Operador: AND Formato: valorl AND valor2 Función: Calcula el valor lógico "Y" de valorl y valor2. Ejemplos: BTNARTO EQU 00ll0l00b AND ll0l0lllb HEXADEC EQU 34h AND 0D7h ;00010100b ; l4h Operador: OR Formato: valorl OR valor2 Función: Calcula el valor lógico "O" exclusivo de valorl y valor2. Ejemplos: BTNARIO EQU 00il0100b OR ll0l0lllb HEXADEC EQU 34h OR 0D7h ; llll0lllb ; F7h Operador: XOR (eXclusive OR) Formato: valorl XOR valor2. Función: Calcula el valor lógico "O" inclusivo de valorl v valor2. Ejemplos: BINARIO EQU 001l0l00b XOR I10101I lb HEXADEC EQU 34h XOR 0D7h Operador: NOT Formato: NOT valor. Función: Obtiene el valor opuesto de cada bit. 52 ; I I10001lb ; E3h Ejemplos: BTNARTO EQU NOT 00110100b HEXADEC EQU NOT 34h ;1l00l0llb ; CBh OPERADORES RELACIONALES Operador: EQ (EQuol) Formato: operandol EQ operando2. Función: Verdad si los dos operandos son iguales. Ejemplo: VALOR EQU 20 MOV AX,VALOR EQ 20 ; equivale a MOV AX,OFFFFh Operador: NE (Nol Equal) Formato: operandol NE operando2. Función: Verdad si los dos operandos son distintos. Ejemplo: VALOR EQU 20 MOV AX,VALOR NE 20 ; equivale a MOV AX,0 Operador: LT (Less Than) Formato: operandol LT operando2. Función: Verdad si operandol ( operando 2. Ejemplo: VALOR EQU 20 MOV AX,VALOR LT 20 ; equivale a MOV AX,O Operador: GT (Greoter Than) Formato: operandol GT operando2. Función: Verdad si operandol ) operando2. Ejemplo: VALOR EQU 20 MOV AX,VALOR GT 20 ; equivale a MOV AX,O 53 Operodor: LE (Less or Equal) Formato: operandol LE operando2. Función: Verdad si operandol g operando2. Ejemplo: VALOR EQU 20 MOV AX,VALOR LE 20 ; equivale a MOV AX,OFFFFh Operador: GE (Greater or Equal) Formato: operandol GE operando2. Función: Verdad si operandol ) operando2. Ejemplo 1: VALOR EQU 20 MOV AX,VALOR GE 20 ; equivale a MOV AX,OFFFFh Ejemplo 2: Si VALOR ) 20, mover a AX el valor 5; en caso contrario, 6: VALOR EQU 20 MOV AX,((VALOR GE 20) AND 5) OR (VALOR LT 20) AND 6) Las formas intermedias serían: MOV AX,(0FFFFh AND 5) OR (0 AND 5) MOV AX,5 OR O Y la forma final ensamblada sería: MOV AX.5 OPERADORES DE RETORNO DE VALORES Operudor: SEG Formato: SEG variable o SEG etlqueta. Función: Devuelve el valor del segmento de la variable o de la etiqueta. Ejemplo: MOV AX,SEG TABLA il ; AX: segmento de TABLA Operodor: OFFSET Formato: OFFSET variable u OFFSET etiqueta. Función: Devuelve el valor del desplazamiento (offset) de la variable o de la etiqueta. Ejemplo: MOV AX,OFFSET TABLA ; AX: desplazamiento de TABLA Operador: TYPE Formato: TYPE variable o TYPE etiqueta. Función: Si el operando es una variable, devuelve: I - si byte 2 - si palabra 4 - si doble palabra 8 - si cuádruple palabra 10 - si variable definida con DT (directiva para reservar diez bytes) Si el operando es una etiqueta, devuelve: -l = 0FFFFh -- sisi NEAR FAR -2:OFFFEh Ejemplo: NUMERO DW 20 MOV AX.TYPE NUMERO ; equivale a MOV A){'z Operador: SIZE Formato: SIZE variable. Función: Devuelve el número de bytes reservados de "variable". Sólo se aplica a variables que se definen con DUP. Ejemplo: NUMERO DW 20 DUP(O) MOV AX,SIZE NUMERO 20 palabras inicializadas con cero equivale a MOV AX,40 55 Operador: LENGTH Formato: LENCTH variable. Función: Devuelve el número de unidades ('bytes o palabras) reservadas 'en "variable". Sólo se aplica a variables que se definen con DUp. NUMERO DW 20 DUP(O) MOV AX,LENGTH NUMERO 20 palabras inicializadas con cero equivale a MOV AX,20 Operador: MASK Formato: MASK nombre_campo. Función: Devuelve la configuración en bits del registro al que pertenece "nombre_campo", con valor I en los bits del campo especificado y 0 en los restantes bits del registro. Ejemplo: REGISTRO RECORD A:3,B: l,C:2,D:4,E:6 ; definición registro con esta sentencia se define un registro (o estructura de bits) con los campos A XXX X MOV AX.MASK C c D XX XXXX XXXXXX ; equivale a MOV AX,0000110000000000b OPERADORES DE ATRIBUTOS Operador: POINTER Formato: Tipo PTR expresión. Función: Redefine el atriburo de tipo (BYTE, WORD, DWORD, QWORD, TBYTE) o el arriburo de disrancia (NEAR o FAR) de un operando de memoria. Tipo: nuevo atributo. Expresión: identificador cuyo atributo se va a sustituir. Ejemplo l: TABLA DW 56 100 DUP(?) ; reserva 100 palabras PRIMER-BYTE EQU BYTE PTR TABLA ; asigna nombre al primer byte QUINTO-BYTE EQU BYTE PTR TABLA + 4 ; asigna nombre al quinto byte QUINTO-BYTE EQU BYTE PTR PRIMET{-BYTE + 4 : asigna nombre al quinto byte Ejemplo 2: Primer segmento: EMPEZAR: MOV AX,IOO JMP EMPEZAR ; el atributo de distancia de la ; etiqueta es NEAR (los dos ; puntos lo indican) ; se puede bifurcar si esta ; instrucción está en el mismo ; segmento Segundo segmento: LEJANO EQU JMP FAR PTR EMPEZAR ; redefine la etiqueta ; con atributo FAR LEJANO : bifurca a la instrucción ; del primer segmento Operadores.' DS:, ES: y SS: Formato: Registro-segmento:etiqueta o registro_segmento:variable o registro-segmento:expresión de dirección. Función: Sustituye el atributo de segmento de una etiqueta, variable o expresión de dirección. Este operador genera como código un prefijo de un byte. El microprocesador supone: DS si el desplazamiento se expresa con BX, SI o DI. SS si el desplazamiento se expresa con SP o BP. Si el registro especificado coincide con el registro de segmento por defecto, no se genera el byte de prefijo. Con la directiva ASSUME se puede especificar el registro de segmento asociado a un determinado segmento, que se insertará como prefijo en las instrucciones cuyos operandos que hagan referencia al segmento, a menos que coincida con el registro de segmento por defecto (en cuyo caso no se incluye). 57 Ejemplos: MOV AX,ES:[BP] MOV AL,uThl MOV AL,DS:[7h] ; el ES sustituye al SS para calcular la ; dirección de memoria ; genera un error, necesita el prefijo de ; segmento ; genera bien el código Operador: SHORT Formato: JMP SHORT etiqueta. Función: Modifica el atributo NEAR de una etiqueta para indicar que se encuentra entre + 127 y -128 de la siguiente instrucción. Con esta información, el ensamblador codifica la instrucción con sólo dos bytes, en lugar de tres. Ejemplo: *" SHORT ETIQUETA ETIQUETA' Operador: THIS Formato: TF{IS atributo o THIS tipo. Función: Asigna a un operando de dirección de memoria un atributo de distancia (NEAR o FAR) o de tipo (BYTE, WORD, DWORD, QWORD, TBYTE) a un desplazamiento igual al contador de posiciones y un atributo de segmento igual al del segmento que lo incluye. Ejemplo l: PRIMELBYTE EQU THIS BYTE TABLA DW 100 DUP(?) Se crea PRIMER-BYTE y le asigna un atributo BYTE con los mismos atributos de segmento y offset que TABLA. Esto es equivalente a: PRIMER-BYTE EQU BYTE PTR TABLA Ejemplo 2: EMPEZAR EQU THIS FAR MOV X,IOO Le asigna a la instrucción MOV un atributo FAR, que permite a las instrucciones JMP de otro segmento bifurcar directamente a EMPEZAR. 58 Operador: $ Formato: $. Función: Este operador es otra manera de referirse al valor del contador de posiciones dentro del segmento. Con "$" nos referimos al valor del contador de posiciones antes de que la sentencia se ensamble. Ejemplo l: .ESTO ES UN TEXTO' TEXTO DB LONGITUD EQU $ - TEXTO reserva memoria y la inicializa longitud de TEXTO antes de ensamblarse. $ apunta a la posición siguiente a TEXTO Ejemplo 2: JE s+) ; bifurcar si igual a la posición: contador de ; posiciones + 5 (la instrucción JE ocupa ; 2 bytes) XX XXXIX $+s Operador: HIGH Formato: HIGH valor o HIGH expresión. Función: Devuelve el byte superior de un valor numérico de 16 bits o expresión de dirección. Ejemplo: CONSTANTE EQU OABCDh MOV AH,HIGH CONSTANTE ; equivale a ; MOV AH,0ABh Operador: LOW Formato: LOW valor o LOW expresión. Función: Devuelve el byte inferior de un valor numérico de 16 bits o expresión de dirección. Ejemplo: CoNSTANTE EQU OABCDh MOV AL,LOW CONSTANTE ; equivale a MOV ; AH,OCDh El aspecto de un programa ensamblador. Un programa eiemplo A efectos de centrar las ideas, vamos a hacer un recorrido por un programa en ensamblador muy simple, el más simple. Se trata de escribir un texto por pantalla. Esto nos va a permitir apuntar los conceptos más importantes que aparecen en el desarrollo de un programa mediante este lenguaje. Véase el listado que aparece al final del capítulo. En este programa lo primero que llama la atención es la gran cantidad de caracteres ";" que aparecen. Se trata simplemente de comentarios, que se van a ignorar durante el ensamblaje. Otro aspecto que aparece es la división (mediante líneas de guiones) del programa fuente en segmentos. En este programa hay tres segmentos que se llaman DATOS, PILA y CODIGO. El nombre del segmento se especifiba en la sentencia SEGMENT. Cada segmento empieza con SEGMENT y acaba con ENDS (fin de segmento). . El segmento llamado DATOS contiene las variables de memoria que utiliza el programa. En este caso, el texto a escribir por pantalla. ¡ El segmento llamado PILA contiene la definición de la pila que va a utilizar el programa. Se reservan 128 elementos de 4 bytes cada uno e inicializados con los caracteres 'PILA'. ¡ El segmento llamado CODICO contiene las instrucciones del prosrama. 60 La división de un programa en segmentos se corresponde con el modo de direccionamiento de la memoria mediante los registros de segmento y de desplazamiento. En este punto debemos decir la forma en que se inicializan los registros de segmento al comenzar a ejecutar el programa: o En los programas EXE: a a DS y ES apuntan al PSP (Prefijo de Segmento de Programa). CS, IP, SS y SP los inicializa el Montador (linker). o En los programas COM: . Los cuatro registros de segmento (CS, DS, ES, SS) apuntan al PSP. . IP: 100h. . SP apunta al final del segmento del programa + l00h (pila de l00h bttes). En nuestro caso, se trata de un programa normal (tipo EXE). El PSP es un bloque de 256 posiciones que se crea en el momento de cargar el programa en memoria y que contiene información tal como los parámetros de la llamada al programa. Vamos a comentar a continuación cada una de las sentencias del programa: .CR LF EQU 13 EQU l0 ; retorno de carro : salto de línea Estas dos sentencias sirven para definir símbolos. Un símbolo es un nombre que se asigna a una constante. Es decir, a lo largo del programa, los nombres CR y LF serán sustituidos por los valores l3 y 10, respectivamente. Estas sentencias no generan código ejecutable. Son "directivas", es decir, sirven para dirigir al programa ensamblador, pero no son instrucciones, las cuales sí generan código. Las instrucciones de comienzo y fin de segmento (SEGMENT y ENDS) son también directivas. DATOS SEGMENT ; comienzo segmento DATOS Directiva que indica el comienzo del segmento DATOS. TEXTO DB 'ABCDEFGHIJKLMNOPQRSTUVWXYZ"CR,LF : texto a escribir Directiva que sirve para reservar memoria para la variable TEXTO. DB quiere decir "definir blte". En este caso, se reservan 28 bytes (26 letras, un byte con el valor 13 y otro con el valor l0). 61 DB '$' : delimitador fin de texto Se reserva otro byte a continuación con el valor'$'. Este carácter se va a utilizar como delimitador del texto a escribir. Es decir, cuando vayamos a escribir TEXTO por pantalla se escribirán todos los caracteres hasta encontrar el carácter '$'. DATOS ENDS ;fin segmento DATOS Directiva que indica el final del segmento DATOS. . PILA SEGMENT STACK ; comienzo segmento PILA Directiva que indica el comienzo del segmento PILA. Si se compara con las otras sentencias SECMENT, en ésta se especifica STACK (pila). Todo programa debe contener un segmento de este tipo, que sirve como área de trabajo del programa. En los otros segmentos no se indica (en la sentencia SECMENT) el tipo de información que va a contener (datos o código). o DB 128 DUP ('PILA') ; inicialización pila Directiva que sirve para reservar memoria parala pila. En este caso, se reservan 128 elementos de 4 bytes cada uno e inicializados con los caracteres 'PILA'. Los elementos de la pila son realmente palabras (2 bytes); por tanto, se reservan 256 palabras. o PILA , ENDS ;fin segmento PILA Directiva que indica el final del segmento PILA. . CODIGO SEGMENT ; comienzo segmento CODIGO Directiva que indica el comienzo del segmento CODIGO. Fn este segmento es donde se van a incluir las instrucciones del programa. . EJEMPLO PROC FAR ; comienzo procedimiento : EJEMPLO Directiva que indica el comienzo del procedimiento EJEMPLO. ¿Qué es un procedimiento? Un procedimiento es un conjunto de instrucciones que puede ser invocado desde dentro del propio programa o desde el sistema operativo. El comienzo de un procedimiento se especifica mediante la directiva PROC y el final mediante la directiva ENDP. Un procedimiento se invoca mediante la instrucción CALL. 62 Dentro del procedimiento, la instrucción RET hace que se retorne a la instrucción siguiente a la CALL. En este caso, el procedimiento EJEMPLO es llamado desde el DOS, es decir, no existe instrucción CALL dentro del programa, aunque si la utilice el propio DOS. Más adelante aparece CALL ESCRIBIR, llamar al procedimiento ESCRIBIR. Obsérvese que dentro del segmento de código hay, pues, dos procedimientos: EJEMPLO y ESCRIBIR; el primero, llamado por el DOS, y el segundo, llamado por el primero. ¿Y la palabra FAR que aparece en esta directiva? Quiere decir que cuando se invoqug a este procedimiento salve la dirección de retorno completa (segmento: CS y desplazamiento: IP) sobre la pila. En este caso es claro, porque, cuando retorne (con RET), volverá al DOS. Recuérdese que CS:IP contiene siempre la dirección de la instrucción siguiente a la que se está ejecutando. Un procedimiento NEAR (que es la opción por defecto si no se especifica nada) sólo salvará el desplazamiento (es decir, el valor del registro IP). o ISSUME CS:CODIGO,DS:DATOS,SS:PILA Esta directiva sirve para indicar los registros de segmento por defecto que se van a utilizar para direccionar los segmentos del programa. El registro CS se asocia con el segmento CODIGO, el registro DS con el segmento DATOS y el registro SS con el segmento PILA. PUSH DS ; segmento a pila Esta es la primera instrucción ejecutable del programa (¡por fin!). Quiere decir salvar el registro de segmento DS sobre la pila. Lo salva para poder retornar al DOS cuando acabe el procedimiento principal (EJEMPLO) con la instrucción RET. La dirección de retorno la tomará la instrucción RET de la pila. Como se trata de un procedimiento FAR, deberá recuperar la dirección completa (segmento y desplazamiento). La dirección de retorno al DOS es DS:O. Esta dirección es la de comienzo del PSP, que contiene la codificación de la instrucción INT 20h, función de servicio del DOS que sirve para terminar el programa. SUB AX.AX ;AX:O Esta instrucción resta el contenido de AX de sí mismo y guarda el resultado en AX. es decir. cero. PUSH AX ; desplazamiento (0) a pila 6:t Almacena el contenido de AX sobre la pila, es decir, 0. En este momento tenemos sobre la pila la dirección DS:O de retorno al DOS. MOV AX, DATOS ; AX: dirección del segmento DATOS Almacena la componente segmento de la dirección del segmento DATOS sobre el registro AX. Como el registro DS apunta al comienzo del PSP, es necesario cambiarlo para que se puedan acceder los datos (en el segmento de datos) mediante el registro DS. La instrucción MOV no permite mover directamente a DS, por lo que se utiliza el registro AX como registro intermedio. MOV DS.AX ; DS:AX Mueve el contenido del registro AX sobre el registro DS. En este momento las variables del segmento DATOS pueden accederse mediante el registro de segmento DS, es decir, hemos direccionado el segmento DATOS mediante DS. Al segmento de código no hace falta direccionarlo con CS, pues lo hace el DOS. Tampoco hace falta inicializar el registro SS para acceder a la pila, pues el DOS lo inicializa también. En este programa no existe segmento extra. LEA DX,TEXTO ; DS:DX: dirección del texto Esta instrucción carga el desplazamiento de la variable TEXTO (respecto al segmento en que está definido) sobre el registro DX. ¿Para qué? Pues porque el procedimiento ESCRIBIR que se va a invocar a continuación necesita que DS:DX apunte al texto que se va a escribir. CALL ESCRIBIR ; llamar al procedimiento ESCRIBIR Instrucción que llama al procedimiento ESCRIBIR. Como se trata de un procedimiento NEAR, la instrucción CALL carga sobre la pila sólo el registro IP. RET ; volver al DOS Mediante esta instrucción la dirección de retorno al DOS se recupera de la pila y bifurca a ella. Termina la ejecución del programa. EJEMPLO ENDP ; fin del procedimiento EJEMPLO Directiva que indica el final del procedimiento EJEMPLO. 64 . ESCRIBIR PROC : comienzo Drocedimiento ESCRIBIR lndica el comienzo del procedimiento ESCRIBIR. Es un procedimienro NEAR, pues no se ha especificado ningún operando. PUSH AX ; salvar registro AX sobre la pila Esta instrucción almacena el contenido del registro AX sobre la pila. Sirve para poderlo recuperar después, al final del procedimiento EiC.RIBIR, pues este procedinliento modifica el registro AX y queremos que cuando retorne cie cste procedimiento los registros se conser!üll ;omo üstaban ¿ntes de invocarlo. JVIOV AH,9 ; tlnción: escribir texto por pantalla Esta instrucción mueve un 9 al registro AH. Lo que se pretende es ¡.-lecutár ilna interrupción en la instrucción siguiente (la interrupción Jlh, que eorresponde ¿ urla rutina de servicicl del DOS). Esta rutlna tivne varias funciones, dependiendo del valor de AH. Con el valor 9 k: inclicamos que queremos escribir un texto por pantalla. La rutina iufiLrne que el tcxto se encuentra en la dirección DS:DX y que el deli¡rritador del texto a escribir es un carácter '$'. iNT 2IH : llamar al DOS b.¡ecuta la rutina de servicio numero 2lh. Escribe el texto. En realidad itna interrupción es muy similar a un procedimiento. Los parámetros .le un pro':rdimiento normalmente se pasan mediante la pila. Los parámetros de una interrupción son siempre registros del microprocesador. POP AX ; recuperar registro AX de la pila Resraura AX con el valor salvado previamente con PUSH. RET ; volver Devuelve rl control a la instrucción siguiente a la CALL ESCRIBIR. Para ello recupera de la pila sólo el valor del desplazamiento, pues la llamada fue clentro del mismo segmento. ESCRI}IIR ENDP ; fin del procedimiento ESCRIBIR Directiva que indica el final del procedimiento ESCRIBIR. CODICO ENDS ; fin del segmento CODIGO. Directiva que indica el final del segmento CODICO. . END EJEMPLO ; empezar a ejecutar el procedimiento EJEMPLO Directiva que indica el final del módulo fuente y que la primera instrucción ejecutable es el comienzo del procedimiento EJEMPLO. PROGRAMA EJEMPLO: ESCRIBIR UN TEXTO POR PANTALLA. CR LF EQU EQU l3 l0 ; retorno de carro : salto de línea Segmento de Datos DATOS SECMENT ; comienzo segmento DATOS TEXTO DB 'ABCDEFGHIJKLMNOPQRSTUVWXYZ"CR,LF ; texto a escribir DB '$' : delimitador fin de texto DATOS ENDS ; fin segmento DATOS t Sesmento Pila SECMENT STACK ; comienzo segmento PILA DB 128 DUP ('PILA') ; inicialización pila ENDS ; fin segmento PILA ; ; Segmento de Código , CODICO SEGMENT ; comienzo segmento CODIGO EJEMPLO PROC FAR ; comienzo procedimiento EJEMPLO ASSUME CS:CODIGO.DS:DATOS.SS:PILA ; poner dirección de retorno al DOS en la pila 66 ; PUSH DS SUB AX,AX PUSH AX ; segmento a pila ;AX:O ; desplazamiento (0) a pila ; ; direccionar segmento de datos con DS ; MOV AX,DATOS MOV DS,AX ; AX: dirección del segrnento DATOS ; DS: AX ; escribir texto LEA DX,TEXTO CALL ESCRIBIR ; DS:DX : dirección del texto ;llamar al procedimiento ESCRIBIR RET ; volver al DOS t ; EJEMPLO ENDP ; fin del procedimiento EJEMPLO ESCRIBIR PROC ; comienzo procedimiento ESCRIBIR ; procedimiento para escribir texto ; Entrada: DS:DX : dirección texto a escribir PUSH AX ; salvar registro AX sobre la pila MOV AH,9 ; función: escribir texto por pantalla : llamar al DOS POP AX RET ; recuperar registro AX de la pila ; volver ESCRIBIR ENDP ; fin del procedimiento ESCRIBIR CODIGO ENDS ; fin del segmento CODIGO END EJEMPLO ; empezar a ejecutar el procedimiento ; EJEMPLO INT zIH ; 67 El iueso de instrucciones Clasificación de las instrucciones La lista siguiente corresponde a los codigos mnemoti'cnicos o sin¡i¡i'i¡, ;,': todas las instrucciones del microprocesador 8088/8086. de LaS inStruCCiOneS marcadaS COn "*" sOn nOmbres SlmbÓlicos ahernati vos. Existen 92 instrucciones. Para aprender el funcionamiento de cada una de ellas. vamül ;¡ iJ¡i.'ldirlas en siete grupos. El lector deberá acudir a la descripcion detall¡¡da ri¡, cada instrucción en el capitulo "Instrucciones". o Instrucciones de tonsferencia de datas (14\ Mueven información entre registros y posiciones de memo¡|3 r' ¡'trr I tos de entrada/salida. IN LAHF LDS LEA LES MOV OUT POP 68 Entrada de byte o palabra. Cargar AH con las banderas Cargar puntero usando DS. Cargar dirección sfsc¡iva, Cargar puntero usando ES. Mover. Salida de byte o palabra. Recuperar palabra de la pila. POPF PUSH PUSHF SAHF XCHG XLAT - Recuperar banderas de la pila. - Depositar palabra en la pila. - Depositar banderas en la pila. - Almacenar AH en banderas. - Intercambiar dos operandos. - Traducir. I ns t rucciones ori t méticas (20') Realizan operaciones aritméticas sobre números binarios o números BCD (decimal codificado en binario). AAA AAD AAM AAS ADC ADD CBW CMP CWD DAA DAS DEC DIV IDIV IMUL INC MUI, NEC SBB SUB - Ajuste ASCII en suma. - Ajuste ASCII en división. - Ajuste ASCII en multiplicación. - Ajuste ASCII en resta. - Sumar con acarreo. - Sumar (sin acarreo). - Convertir byte en palabra. - Comparar operandos. - Convertir palabra a doble palabra. - Ajuste decimal en suma. - Ajuste decimal en resta. - Decrementar destino en uno. - Dividir, sin signo. - Dividir, con signo. - Multiplicar, con signo. - lncrementar destino en uno. - Multiplicar, sin signo. - Negar/formar complemento a 2. - Restar con acarreo. - Restar (sin acarreo). Inslrucciones de manejo de bits (t2¡ Realizan operaciones de desplazamiento, rotación y lógicas sobre registros o posiciones de memoria. AND NOT OR RCL RCR ROL ROR SAL SAR SHL SHR - Y lógico. - No lógico. - O lógico inclusivo. - Rotar a la izquierda a través de acarreo. - Rotar a la derecha a través de acarreo. - Rotar a la izquierda. - Rotar a la derecha. - Desplazamiento aritmético a la izquierda. - Desplazamiento aritmético a la derecha. * Desplazamiento lógico a la izquierda (igual a SAL). - Desplazamiento lógico a la derecha. TEST XOR - Test/comparación lógica de dos operandos. - O lósico exclusivo. Instrucciones de transferencia de control (23) Sirven para controlar la secuencia de ejecución de las instrucciones del programa. CALL Llamar a un procedimiento. Bifurcar si superior. Bifurcar si superior o igual. JB Bifurcar si inferior. JBE Bifurcar si inferior o igual. JC* Bifurcar si acarreo (igual a JB). Bifurcar si CX es cero. JCXZ JE Bifurcar si igual. Bifurcar si mayor. JC Bifurcar si mayor o igual. JGE Bifurcar si menor. JL Bifurcar si menor o igual. JLE JNA * Bifurcar si no superior (igual a JBE). JNAE * Bifurcar si no superior ni igual (igual a JB). Bifurcar si no inferior (igual a JAE). JNB JNBE * Bifurcar si no inferior ni igual (igual a JA). JNC Bifurcar si no acarreo (igual a JAE). JNE Bifurcar si no igual. JNG Bifurcar si no mayor (igual a JLE). JNGE * Bifurcar si no mayor ni igual (igual a JL). JNL Bifurcar si no menor (igual a JGE). JNLE Bifurcar si no menor ni igual (igual a JG). JNO Bifurcar si no desbordamiento (overflow). JNP Bifurcar si no paridad. JNS Bifurcar si no signo/si positivo. {. Bifurcar si no cero (igual a JNE). JNZ JMP Bifurcar incondicionalmente. JO Bifurcar si desbordamiento (overflow). JP Bifurcar si paridad. JPE Bifurcar si paridad par (igual a JP). * Bifurcar si paridad impar (igual a JNP). JPO Bifurcar si signo. JS JZ* Bifurcar si igual a cero (igual a JE). LOOP Bucle hasta que se acabe el contador. LOOPE Bucle mientras igual. LOOPNE - Bucle mientras no igual. LOOPNZ * Bucle mientras no cero (igual a LOOPNE). LOOPZ * Bucle mientras cero (igual a LOOPE). RET Retornar de un procedimiento. JA JAE x< {< *< {< {< {< 70 . Instrucciones de manejo de cadenas (strings) (8) Realizan operaciones sobre series de bytes o palabras como mover, comparar y explorar. CMPS - Comparar cadenas de bytes o palabras. CMPSB * Comparar cadenas de bytes (igual a CMPS). CMPSW x Comparar cadenas de palabras (igual a CMPS). LODS - Cargar cadena de bytes o palabras. LODSB x Cargar cadena de bytes (igual a LODS). LODSW * Cargar cadena de palabras (igual a LODS). MOVS - Mover cadena de b¡es o palabras. MOVSB x Mover cadena de b¡es (igual a MOVS). MOVSW x Mover cadena de palabras (igual a MOVS). REP - Repetir operación de cadena. REPE - Repetir operación de cadena, mientras igual. REPNE - Repetir operación de cadena, mientras no igual. REPNZ x Repetir operación de cadena, mientras no cero (igual a REPNE). REPZ x Repetir operación de cadena, mientras cero (igual a REpE). SCAS - Explorar cadena de bytes o palabras. SCASB x Explorar cadena de bytes (igual a SCAS). SCASW x Explorar cadena de palabras (igual a SCAS). STOS - Almacenar cadena de bytes o palabras. STOSB x Almacenar cadena de bytes (igual a STOS). STOSW x Almacenar cadena de palabras (igual a STOS). o Instrucciones de interrupción (3) Provocan la interrupción del microprocesador para que realice un servicio determinado. INT INTO IRET - Interrupción. - Interrupción si desbordamiento (overflow). - Retorno de interrupción. o lnstrucciones de control del microprocesador (12) Activan y desactivan banderas y cambian el estado de ejecución del microprocesador. CLC CLD CLI CMC ESC HLT LOCK NOP - Borrar bandera de acarreo. - Borrar bandera de dirección. - Borrar bandera de interrupción. - Complementar bandera de acarreo. - Escape (transmitir información a un coprocesador). - Parar el procesador. - Bloquear el bus. - No operación. 71 - Poner bandera de acarreo. - Poner bandera de dirección. - Poner bandera de permitir interrupciones. - Esperar que acabe un coprocesador. STC STD STI WAIT El total de instrucciones es: Instrucciones de transferencia de datos Instrucciones aritméticas . . . Instrucciones de manejo de bits lnstrucciones de transferencia de control Instrucciones de manejo de cadenas . . . Instrucciones de interrupción Instrucciones de control del procesador Total t4 20 lz ¿J 8 a J t2 92 lnstrucclones tnstrucciones de transferenc¡a de datos {14} Mueven información entre registros y elementos de memoria o puertas de entrada/salida. La información que se transfiere es de 8 o de l6 bits. Se dividen en las cuatro categorías siguientes: DE PROPOSITO GENERAL (5) MOV PUSH - Mover. - Depositar palabra en la pila. - Recuperar palabra de la pila. POP XCHG - Intercambiar dos operandos. XLAT - Traducir. DE ENTRADA/SALIDA (2) - Entrada de byte o Palabra. IN OUT - Salida de bYte o Palabra. DE TRANSFERENCIA DE DIRECCIONES (3) LEA LDS LES 72 Cargar dirección efectiva. Cargar puntero usando DS. Cargar puntero usando ES. DE TRANSFERENCIA DE BANDERAS (4) LAHF - Cargar AH con las banderas. POPF - Recuperar banderas de la pila. PUSHF - Depositar banderas en la pila. SAHF - Almacenar AH en banderas. LAS INSTRUCCIONES PUSH Y POP Estas instrucciones se utilizan para acceder a la pila, área de la memoria que se utiliza como espacio temporal para almacenar direcciones y datos. Cada elemento de la pila es una palabra (16 bits)" La pila está direccionada mediante SS:SP. El registro SP apunta siempre al último elemento depositado en la pila (el elemento más alto). El crecimiento de la pila es en el sentido decrecrente de la memoria. es decir, a medida que se deposi:an elementos sobre la pila, el contenido del registro Sir va disminuvendo. Y a l::. lnversa. Ai hacei F,USH tc:posirar). SF debe apunrar a la posición inmediatarnenie superioi (r:ara lo ,--uai irac¿ SP: SP__2) r, a continuación mueve el icnlenidt dr i¿ ira.i¿¡bla r"rspe,Jificaili por" el operando fuente a SS:Sp. Ai nar:e: POF t:c;":i-r'ra:!. cturr SIr aFu*la a, ui;irnc e'iementci deposriaú.' sohrr, la;ri1¡,. sr'::G.:..:J e: novinlicnto d: ia paiabra SS:SP ai operandi.. ürtlitltl. A c*nli::ua.cii''1. allualize r, iirlrtffi,l dr. le pila. fiara indicar e! ú11," :': :r: -. SS :i; -\\ ¡ +:() ": n l:: AX i:|:,;' ii.\ i':l,E x-Ai.l" l_ ) \'!i-. l---"--.----.----."-----r 'I-.(i:-1 ¿i !.1 L_-_ I r,-',9 C\' __ ¡ Es importante señalar que, si se hace PUSH de un operando, es necesa- rio hacer POP en otro punto del programa, para evitar el crecimiento in- controlado de la pila, que podría destruir los propios códigos del programa. PUSH y POP son, pues, instrucciones complementarias que deben usarse por parejas. Si se depositan sobre la pila dos o más valores, es necesario recuperarlos en orden inverso. Por ejemplo: PUSH AX PUSH BX POP POP f BX AX : salvar AX ; salvar BX ; recuperar BX ; recuperar AX nstrucciones de manejo de bits l12l Se dividen en las dos categorias siguientes: INSTRUCCIONES LOGICAS (5) AND - l'lógico. OR - Ológicoinclusivo. NOT - No lógico. XOR - O lógico exclusivo. TEST - Test/comparación Iógica de dos operandos. INSTRUCCIONES DE DESPI-AZAMIENTO Y ROTACTON DE BITS (7) Desplazan o rotan el contenido de un registro o posición de memorla (8/16 bits), a la izquierda o a la derecha, un cierto número de bits. El CF actúa como un bit adicional del operando destino: . Operación a la derecha - CF: bit 0. . Operación a la izquierda - CF: bit 7 o bit 15. Las operaciones aritméticas preservan el signo; las lógicas, no. El número de bits a desplazar /rotar puede ser de uno (valor inmediato) o especificarse en el registro CL (sin signo). Las instrucciones son: 74 SAL - Desplazamiento aritmético a la izquierda. SAR - Desplazamiento aritmético a la derecha. SHL x Desplazamiento lógico a la izquierda (igual a SAL). SHR - Desplazamiento lógico a la derecha. RCL - Rotar a la izquierda a través de acarreo. RCR - Rotar a la derecha a través de acarreo. ROL - Rotar a la izquierda. , ROR - Rotar a la derecha. Los esquemas siguientes ilustran el funcionamiento de estas instrucciones: o Desplazamiento: CF sAL/sHL Desplazamiento lógico o aritmético a la izquierda ffio CF Desplazamiento aritmético SAR a la derecha" CF SHR o . Rotación: lógico a la G ?..rr.o.f;"-iento CF ROL Rotación a la izquierda ROR Rotación a la derecha . Rotación a través de acarreo: 7-rrl t{.{. I l Rotación a la rzquierda a través de acarrer: ll CF T-' i_- Ro¡ación a la rierecha a través de acarrecr 75 nstrucciones aritméticas l20l I Aunque todas las operaciones se realizan en binario, las instrucciones aritméticas operan sobre: . Números binarios (con o sin signo) de 8 ó 16 bits' o Números decimales sin signo (empaquetados o no). Empaquetados: Dos dígitos BCD por byte. Desempaquetados: Un dígito BCD por byte. f nstrucciones de transferencia de control l23l Transfieren el control a otro punto del programa. No afectan a las banderas. Se dividen en tres categorías: incondicionales, condicionales e iterativas. INCONDICIONALES (3) Transfieren el control de modo incondicional. JMP - Bifurcarincondicionalmente. RET - Retornar de un procedimiento. CALL - Llamar a un procedimiento. CONDICIONALES (17) Transfieren el control si se cumple una condición determinada. Si no se cumple, se ejecuta la instrucciÓn siguiente. La forma general de estas lnstrucciones es: Jr.xr desplazamlrnl{l en donde xxx es un modificador de una a tres letras. El desplazamiento o etiquel:r corta (short iabel) correspcnde a una etiqueta que debe estar en el intervair¡ l-127,+ 128) de la instrucción de bifurcación. La iabla siguiente indica la condición asociada a cada instrucción de bifurcar:lon condicional: 76 Descripción JA JAE -B furcar si superior. .B furcar si superior o igual. -B furcar si inferior. -B furcar si inferior o igual JB JtsE JC JC.XZ .IE JC JGE JL JLE JNA JNAE JNB JNBE JNC JNE JNC JNCE JNIJNT-E JNO JNP JNS JNZ JO JP JPE JPO JS .tz Condición Equiv. Nornbre . *,8 furcar si acarreo. -B furcar si CX es cero. -ts furcar si igual. CF:0 y ZF:0 CF: O CF: I CF:1 o AF: I CF: I CX: O ZF:I ZP :0 y SF: OF ,t .B furcar si mayor. -B furcar si mayor o igual. SF: OF SF <> OF -ts furcar si menor. -B furcar si menor o igual. *,B furcar si no superior. *B furcar si no superior ni igual. *B furcar si no inferior. *B furcar si no inferior ni igual. *B furcar si no acarreo. ,B furcar si no igual. *B furcar si no mayor. *B furcar si no mayor ni igual. ¡.B furcar si no menor. xB furcar si no menor ni igual. .B furcar si no desbordamiento -B furcar si no paridad. -B furcar ri no signo/si positivo. *B furcar si no cero. -B furcar si desbordamiento. -B furcar si paridad. r¡B furcar si paridad par. xB furcar si paridad impar. -B furcar si signo. ¡.8 furcar si igual a cero. ,tt JB JAE, JA JAE JLE JL JCE JC ñu J" JNP ZF:loSF()OF CF:loAF:l CF: I CF: O CF:0 y ZF :0 CF: O ZF :0 ZF:loSF<>OF SF <> OF SF: OF ZF :0 y SF: OF OF:0 PF: O SF: O ZF:0 OI.: I PF: I PF: I PF:0 SF: ZF:I 1 JE L,as instruccicnü\ ccndicionales se utilizan junto con la instrucción de Jonlpari"rulrin ( C I\t P). La tabla siguiente indica el tipo de instrucción condi,.:ional a urilizar tras la instrucción CMP,Jestino,fuente: Números con sign.) Para bil'urcar ,si f iJair ie i |., ite I risrl Lt: JB JE Jt.¡E J¡\ JC lu¡;.rie .ItsE JLE li.ii:':li,: JAE JGE i''¡t ", .: JNE JNE TT ITERATIVAS (3) Permiten la ejecución de bucles. El número de iteraciones se determina mediante el valor del registro CX (contador). CX: CX-l y bifurcar si CX É 0. LOOPNE : LOOPNZ - CX : CX-l y bifurcar si CX * 0 y ZF : 0. LOOPE :LOOPZ - CX:CX-l y bifurcar si CX *0y ZF = L LOOP LOOP - Bucle hasta que se acabe el contador. LOOPE - Bucle mientras igual. LOOPNE - Bucle mientras no igual. LOOPNZ * Bucle mientras no cero (igual a LOOPNE). LOOPZ x Bucle mientras cero (igual a LOOPE). Instrucciones de manejo de cadenas (8) Una cadena es una serie {e bytes o palabras de hasta 64 Kb de longitud. Por defecto, estas instrucciones suponen que: o Cadena fuente: en el segmento de datos y desplazamiento SI (DS:SI). o Cadena destino: en el segmento extra y desplazamiento DI (ES:DI). Los registros SI y DI se actualizan automáticamente después de cada operación: ¡ Si el(los) operando(s) son de tipo byte, el incremento es l. o Si el(los) operando(s) son de tipo palabra, el incremento es 2. A su vez, este incremento puede ser positivo o negativo, según el estado de la bandera de dirección (DF): .si DF = 0, el incremento es positivo. .si DF : l, el incremento es negativo. PREFTJOq DE REPETTCTON (3) Puesto que las instrucciones operan sobre un elemento individual de la cadena (bfte o palabra), existen lcs llamados prefijos de repetición, que permiten actuar sobre la cadena completa: - repetir nrientras CX * 0. - repetir mientras CX + 0 y ZF : l. REPNE : REPNZ - repetir mientras CX /0 y ZF.=0. REP REPE : REPZ 78 REP - Repetir operación de cadena. REPE - Repetir operación de cadena, mientras igual. REPNE - Repetir operación de cadena, mientras no igual. REPNZ * Repetir operación de cadena, mientras no cero (igual a REPNE). REPZ x Repetir operación de cadena, mientras cero (igual a REPE). MOVER CADENAS (1) Sirve para mover un elemento de una cadena a otra. Mediante el prefijo REP es posible mover una cadena completa. El número de elementos a transferir se especifica en CX. MOVS - Mover cadena de bytes o palabras. MOVSB * Mover cadena de bytes (igual a MOVS). MOVSW x Mover cadena de palabras (igual a MOVS). COMPARAR CADENAS (I) Sirve para comparar dos operandos de memoria. Con los prefijos de repetición REPE: REPZ y REPNE: REPNZ es posible comparar dos cadenas hasta encontrar dos valores iguales o distintos. CMPS - Comparar cadenas de bytes o palabras. CMPSB x Comparar cadenas de bytes (igual a CMPS). CMPSW x Comparar cadenas de palabras (igual a CMPS). BUSCAR EN LA CADENA (I) Permite explorar una cadena para buscar un elemento que contenga un determinado valor. Los prefijos de repetición que se aplican son REPE : REPZ o bien REPNE : REPNZ. SCAS - Explorar cadena de bytes o palabras. SCASB * Explorar cadena de bytes (igual a SCAS). SCASW x Explorar cadena de palabras (igual a SCAS). TRANSFERENCIAS ENTRE CADENAS Y REGISTROS (2) Una vez posicionado en un elemento de la cadena, estas instrucciones permiten transferir dicho elemento (byte o palabra) al acumulador (AL o AX) y viceversa. 79 En este caso no se aplica ningun rlrefilo de rcpetii.:r'':ri. LODS - C.argar cadena dc byles (r pa.i;ilir;rs. I-ODSB * Cargar cadena de b-vtc:, (igual r i (ii-i\ll L.ODSW x Cargar cadena rie palah'a.' ílsr.rti a i ¡-]i)Sl STOS - Almacenar cadena dc bvte. (r i' ,.-il-'::: STOSB * Almacenar cadena de byt.;s (rgü:,i íi S i üli¡. STOSW x Almacenar cadena de nalabra,i {rprrai a Sl Oiil lnstrucc¡ones de control del rr¡ ic rüF.i i úu,*3 & ci,; í OPEITACIONES {lflhr I}ANl}t t¡Ac 1¡'' 1i ¡1':('! /,rl PCfnilr:i CiO<ili;:lr,: ]'.,: i::t-r:J -l ,.'!t t..:-':, . '\ ;\r) :," 4--: .)- ;''-.'!l\l\ ' li' i.b¡.rdt'-^. lr i.1¡,---'1".. ! ''- .\ I i i-\.': í::, !,'::::r :, .x.-"j ' - i.ii' ¿: ;ii. ,,-l ¿ 4.,. r 1: .llr. - lll tFñT'Rti(.tlf(fN lll. \(l tlP;'l¡4f i{tt\ (lt I.r i¡ rli.t,, a\ ti\li ¡1!,r! (,'rrr !i!ú rir 1,'rilá: l.:,1 c0tJigtr üllc É(lli¡''!':. , ' d. un :'.;t \ ;. ¿ü10o. Ir':.1 i i.¡ i'-:üil)f"teS üg iilr t.i t"tin,-"iáff i3l bI pieta Cod¡ficación de las instrucciones Notación Vanros a utilizar la notación siguiente: reg indica registro de 8 ó 16 bits. bits. reg8 indica registro de 8 reg16 indica registro de 16 bits. mem indica variable de memoria de 8 ó 16 bits. bits. memS indica variable de memoria de 8 meml6 indica variable de memoria de 16 bits. val indica valor inmediato de 8 ó l6 bits. bits. val8 indica valor inmediato de 8 bits. vall6 indica valor inmediato de 16 des indica desplazamiento de 8 ó l6 bits. bits. desS indica desplazamiento de 8 des16 indica desplazamiento de 16 u, bits. Formato general de una instrucción El formato general de una instrucción es el siguiente: código mod reg r,/m des vai El código de la operación aparece en el primer byte. Es el único que existe siempre. Los demás campos pueden aparecer o no, dependiendo del tipo de instrucción. Los operandos de la instrucción se reflejan en el byte "mod reg r/m" . Un operando se especifica mediante "mod" y "r/m". El operando puede ser un registro o una dirección de memoria. El otro operando se especifica mediante "teg" .El operando debe ser un registro. El campo "des" es el componente desplazamiento de una dirección de memoria. Puede ser uno o dos bytes. Si ocupa dos bytes, el byte menos significativo se almacena primero. El campo "val" es un valor inmediato. Puede ocupar uno o dos bytes. Como en el caso anterior, si ocupa dos bytes, el b¡e menos significativo se almacena primero. Los campos que aparecen en la codificación de una instrucción ensamblador son: : bit que indica la longitud de los operandos. Aparece dentro del byte de código. 0 - byte. I - palabra. un bit que indica el destino. Aparcce también dcntro de I bvte de ioiligc 0 el operando dc:-¡iii;., -i\:t ii\ pcclt I {-¡¡ ilictli;ill t t itl,,l,." ''nloclt' ¡"'1"til". 1- el operartdo tic'iir¡i, "rcg". reg ¡¡i i r íirt .,r' .- rf)r-Cliir(¡ rilr. dl.rttr. ¡: ..ttrrrl/\ : dos o tres bits que indrc.rir r:l ttpo tlt-l i(j¡ilslr(r i{ucr ri{. vrr ¡1 tlIli. zar cotno rtperarido. 83 r<'8 yg 00rl AL 001 CL 010 i)i I DL ::!_il__:3 itL AH ! {)(.} i0l CH DH ll0 ill tsH AX Ii CX DX 00 II rrx L ;t" #, re g ist ro tle seg tne n f tt i] 0l t0 ll ES CS S5 DS I 1 (/m : tres bits que indican el tipo de direccionamiento del operand<; registro buse I registro índice BX BX SI t01 vJ0 BP SI üri tsP DI 100 nin.guno SI r01 ninguno 110 ftP BX DI ninguno (*) 000 ill DI ningu!lo i-) Si mo<j - 00, entoncer ia in-struccrón contiene ei desplazarrienro en dos bytes ¿dicionales. irüi: .. rfos blts que indican el trpo de desplazarrllenfo: I ma¿ | úespluzstnienro cCI í.) 0l 8 bits *n el byte slgr:iente (hay expan-<iri:r Cel :;::gno a i6 bits) l6 bits en l0s ,,':al ...'l'f :'5 :,i:, :. rq:: j I ii! l0 ll tldiCa ,;;re r/m ':S r:,'l fegrsf r/J i¡r., ',,rcf i{:.r.r; l'41¡t/ ,{t-, ¡.¿h ...i.',!r : it ! * i'i!: r',cl qil¡.".tlc ,Se rrt,liZt aqtii !'ar 1 .,jj...r r : ..iji-ira\t lCl l). !r¡ -. pues el ,rperandcl destlno lAL,) ¿s rn i)":,trj reg : 000, pues se trata del registro AL. val : valor inmediato l2h : 0001 0010b. La codificación es, pues: l0l I 0000 0001 0010 : B0 l2 (hexadecimal) Ejemplo 2: Instrucción : MOV AX. l23h Codificación: l0l lw reg I val w : l, pues el operando destino (AX) es una palabra. reg : 000, pues se trata del registro AX. val : valor inmediato 0123h, que se almacena'Jomo: 2301 (hexadecimal) : 0010 001I r)000 0001 La codificación es, pues: l0l l 1000 0010 0011 0000 0001 : 88 23 0l (hexadecrmal) Ejemplo 3: Instrucción: MOV AX,BX Codificación: 1ü)0l0dw I mod reg t /m d :0, pues el operando destino se especifica medianlc lt;s ialltpcr mod y r/m. : w 1, pues el operando destino (AX) es una paiabra' mod: 11, pues el registro se especifica en r/mr/m :000: número del registro AX' reg :011, pues el operando fuente es el BX. La codificación es, pues: 10001001 ll 011 000: 1000 l00l 1l0l 1000..,iJ9 D8 {i¡e:<:.¡.ri3r.::r:;)} Ejemplo 4: Instrucción: MOV CX,C{}NTAD{}F.lgXilSIl Suponemos que CON'IADOR el) llia ^''a¡i;r¡tii"-i.r ":'..';¡1 r1;r ,".'r.'' labra con desplazamiento = 1234h. Codificacion: l{)0010c1w I c;r1reg r¡m I cies d : l, pues el operari;l cles¿ino le espec;lica ,ileg)aÍi:.l),:: -.:,'r',-,rr reo 85 w : I, pues el operando destino (CX) es una palabra. mod: 10, pues el desplazamiento (CONTADOR) es de 16 bits. r/m:000, pues el direccionamiento se hace mediante BX y SI. reg :001, pues el operando destino es CX. des : desplazamiento de CONTADOR : 1234h, que se almacena como 3412 (hexadecimal). La codificación (a falta del desplazamiento) es: l000l0ll l0 001 000:1000 l0ll 1000 1000:88 8g (hexadecimal) Y con desplazamiento: 88 88 34 12 (hexadecimal) Ejemplo 5: Instrucción: MOV WORD PTR CONTADORIBX]lSIl,56Tgh Suponemos que coNTADoR es una variable de memoria tipo palabra con desplazamiento : 1234h. Codificación: I l0001lw mod 000 r/m val I w : l, pues el operando destino es unaI palabra. mod: 10, pues el desplazamiento (CONTADOR) es de 16 bits. rfm :000, pues el direccionamiento se hace mediante BX y SI. desplazamiento de CONTADOR: 1234h, que se almacena como 3412. val : valor inmediato : 5678h, que se almacena como 7g56. I-a codificación (a falta del desplazamiento y valor inmediato) es: I 10001I I lt) 000 000 - I100 0I il t000 0000 =. c7 80 (hexadecimal) 't '-ori Li.:sp¡., ' ,tn ento y vaior inmediatcl: {- ¿ Sij j4 L ,S ió (hexadecimal) Clasif¡cación de las d¡rectivas Las directivas o seudooperaciones se pueden dividir en cuatro grupos funcionales: ¡ Directivas de datos. o Directivas condicionales. o Directivas de listado. o Directivas de macros. Se recomienda que el estudio de las directivas se ajuste al orden funcional establecido aquí, acudiendo a la descripción detallada de cada una de ellas en el capítulo "Directivas". Directivas de datos A su vez, se dividen en las seis categorías siguientes: DEFINICION DE SIMBOLOS Sirven para asignar nombres simbólicos a expresiones' Una vez definido el símbolo, se puede usar dicho símbolo en lugar de la expresión equivalente. lQLi - Asigna un sinrlr*ir a un¿l exPresión fija. r!I'tl,'l\ ICION D[, I]AT(]S ¡r;'..'i. ;-1i,¡r¡ l'fsi*\;,. rricmori,i p¿ra las variables del programa. Op- \ i,)Ilitimcnr(' ir plll:,iii. dar un vaiot inicial a cada variable. :.ti' ., i " il. : i-:r... I i)r:l;iili t*:'i".. i _r,-. I r.lt. lt:.: iil:'¡\i ;1 i:t I r i l:-í' . i),.,;'ij; !,i,-.ili; i-:., ;ii)la. i,,rri'i;1t' r'l):r.,] i:l'i:.' piilatlra ,..-. ,-l . : '.' !.i i,FiN as "r:{-L,q¡. modulos c ficheros ,' :rit:i::,i)!i) pi;i:rti,: ,.','., '¡,; ¡.;nnOi* exi.(:i;i.¡ ' ' - rl;.:a::* t'r;gnil : ',-'q t \f t],l:..4IX}I; : --- - :^ ::^¡:.r.!:ii i¿c,.'.¿. '. : ..,:: .r i :..¡- ." lt...,t'' :n. ;. ,."'. rlll ,'t',t..' - i'i ".1 -.,\:,-.rr.-\ | ¡.'. ': ' : - 1. t'.'|i "r[-G]l Fll','T ü: ] irlanr{.ii. i l}lI'1"ii ! I { !} .l ..', :r ia:..i :-..,;'-::.,:' '!f ' I: " .. .,..-.". .r e¡r '..,,t1 ..¡: . !_ .-- (' ' ; i., T¡ -,a "i ,:i'i.i'. - _.::'r,.1-,';' , il1C.l . 1, ': LABEL - Asigna un atributo a un nombre. RECORD t)cfinir registro. STRUC - Definir estructura. Directivas condicionales Sirven para que el ensamblaclor írtctuyd rr igrrt¡rr: ;:ri'r'1:rs '',;¡.::i.rl:r:r Jct programa fuente, según que una cí*rta iondictr,:n \cir alrt.Lr 'r I ;i:.r'.:r) :t{iIltpo de ensamblaje. La porción del programa a incluir ü ni). trnr{-rrr':'¡r pr;f j:.r¡'-} \.¡il!-,.tiv-r i:.pL) y IF acaba con la directiva F.NDIF. Puede incluirse también El-SE {opciirn sr lon¡-tciiin f;¡lsr). Las directivas de este grupo .son; fFx,xx, Et-SE v FNDIF. lFrr'..r i'nr¡f.r a una directiva que comienza por IF-. La dstructur;l gcnrtnl r's: IFx,rx.. fcondiciónl ELSE .., ENDIF' Es conveniente despla¿ar dos posieitlrics las sf nLtr¡¡r:i;ir ';iri '!i' :;,t.itrv-ln dentro de cada hloque IF o Et"SFl, plrcs sd gana cn ,,1:rr:,i.:.,! Directivas de listado Indican al ensamblador la infbrmación a obtencr *n,;l li:.i.r¡.kr Jc 'airdit y el tbrmato de esa información. F'ORMA'TO DEI, I,ISTADO PACE L'ormato cle la phgina del listado. TI'ILE - 'fitulo del listaclo. SUts'fTL - Subtitulo del lisrailo. LTSTADO DE MACROS .LALL - Listar macros y expansiones. .SALL - Suprimir el listado de las macros y las expan\iones .XALL - Listar sólo las rn¿rcr()s que gencrrn eorlrgo ch¡cttr. tó CONTROL DEL LISTADO .XCREF - Suprimir referencias cruzadas. .CREF - Restaurar listado de referencias cruzadas. .XLIST - Suprimir listado ensamblador. .LIST - Restaurar listado ensamblador. COMENTARIOS COMMENT - Comentario. MENSAJES 9oOUT - Emitir mensaie durante el ensamblaie. CONTROL DEL LISTADO DE LOS BLOQUES ASOCIADOS A UNA CONDICION FALSA .LFCOND - Listar bloques asociados a una condición falsa. .SFCOND - Suprimir el listado de los bloques asociados a una condición falsa. .TFCOND - Invertir el modo de listado de los bloques asociados a una condición falsa. Directivas de macros Una macro es un conjunto de sentencias ensamblador (directivas e instrucciones) que pueden aparecer varias veces en un programa con algunas modificaciones opcionales cada vez que se usan. A cada macro se le asigna un nombre. Especificar este nombre en el programa es equivalente a la inclusión del conjunto de instrucciones. Un ejemplo de definición de una macro es el siguiente: t t S ZZ:XX+YY UMAR MACRO XX,YY,ZZ ;definicron macro MOV ADD MOV ENDM 90 AX,XX AX,YY ZZ,AX ;fin macro SUMAR es el nombre de la macro. XX, YY y ZZ son los parámetros de la macro. Un ejemplo de utilización es: SUMAR PEPE.JUAN.LUIS que equivale a: MOV AX.PEPE ADD AX.JUAN MOV LUIS,AX Este proceso de sustitución de los parámetros de la macro por los argumentos utilizados en la invocación se llama expansión de la macro. Estructura de una macro: Una macro se define mediante tres partes: o Cabecera (la directiva MACRO indica el nombre y los parámetros). o Cuerpo (conjunto de sentencias que definen Io que hace la macro). o Terminador (la directiva ENDM marca el final de la definición). Parómetros de una macro: Como se ve en el ejemplo, una macro requiere normalmente una serie de parámetros. Pero pueden existir macros sin parámetros. Si se especifican menos de los definidos, se ignoran las sentencias que hacen referencia al parámetro omitido. ¡ Si se especifican más de los definidos, se ignoran los parámetros de exceso. Macros y procedimientos: ¡ El código asociado a un procedimiento es único" En una macro, se repite cadavez (el ensamblador expande la macro). o Después de la ejecución de un procedimiento, se retorna a la instrucción siguiente a la que lo llamó. Después de la ejecución de la macro, se continúa con la instrucción siguiente (ejecución en línea). o Las macros son más flexibles que los procedimientos. Una macro se modifica cambiando los parámetros de entrada. Los parámetros de los procedimientos son sólo zonas de memoria o registros. o Las macros se ejecutan con más rapidez que los procedimientos, al no existir instrucciones de llamada ni de retorno. 91 i.¿ri ni;rcro" se pur:derl crear en una librería de macros, de la que los prograrnadores pueden tirar para hacer sus programas. r.¡: dr¡'cetn¡as üe r¡acroí" se divlderr en dos catesorías: definición de r¡,;:. t{\' I (r¡rg¡¿6atc". d,. mat.ros. IX"]r'T}üICION DE MA CROS MA{-RT; . f --[rl-íilgnr:ii l¡¡a{iro * litr¡ macro. ENf-IM I,OCAL - Define etiq¡rrri¿rs denlro de una macro. EXTTM - Termin¿r¡ ei,p;ansión de la macro. i'i, f(t-' L - IJartar ias rnacros de la memoria. REPl - Repetir bloque de sentencias un cierto número de veces. IRP - Repetir bloque de sentencias con un valor cada vez. - Repetir bloque de sentencias con un carácter cad.a vez. It(PC {IPA.,RAT'OR};S DI] MACROS l'. - ()pt:rador para coücaler¡a:- lexl.os o símbolos. - Opcrador paia col¡tenlarir¡,r. que no aparecen en la expansión. - l.)¡.lcraciur ira,;r rntcrpr(:lÍrJ caracler en sentido literal - Operador parü convertir una expresión en un número. . (/,, 92, 1(} Directivas llirt't lrvx. & (Aui¡-,crsatld,l. *r¡rrni¡irr: lexto&texto llr'sunpcirrn: I:.. ut: opcradLi¡ qut st ui¡l¡z¿r clt:¡itr(i clr iu deltntclón clr trr¡i¡ tir¿¡(riL, li;tr;i ctncAlcnar t(:xto-! o simboltls. ()hst'rvaclonrs: Si st utiliza un palámetro de la macro dentro de una caden;l d{: r-',,, rar--tcrrs lcntrr: comili:r*)" debt' ir ¡rrecerdido por el caráctet antp(rr:,ítn(i (&) par¿i que se sustrtriya cn la expansiirn de la macro. I'ara forntar un sinrbolo a partir de texto y de un parámclri,rír'lli ntr( ro. cq nr'r'f '\¿rri( ' inlr.'r n0lrr-r un amp('rsand cnl rr' cl ltr' f l,.icmpkr l: . t I{RCFN MACR{-) x t HR()l{&X: Pl.lSH F{\ AttX M(rV [i]n."6tr" AIJ&X .IIVI[' E'RROR L'NDM ; comicnzo macrtl : fin macrc 93 La expansión de la macro para ERRCEN A será: ERRORA: PUSH BX ABX MOV BX,"A'' ABA Ejemplo 2: JMP ERROR MENSAJE MACRO COND,SUBRUT ;comienzo macro J&COND FIN CALL SUBI FTN: ; fin macro ENDM La expansión de la macro para MENSAJE GE,SUBI será: JGE FIN CALL SUBI FIN: Ejeñplo 3: HACER MACRO COND,TEXTO J&COND FIN ; comlenzo macro TEXTO FIN: Con ENDM ; HACER GE, <MOV AX,BYTE PTR [Dr]> la expansión de la macro será: JCE MOV FIN: 94 fin macro FIN AX,BYTE PTRIDI] Directiva: Formato: Descripción: Es un operador que se utiliza dentro de la definición de una macro o de una declaración repetitiva (REPT, IRP, IRPC) para insertar comentarios que se desea que no aparezcan en la expansión. Observaciones: utilizar estos dos caracteres, los comentarios no aparecerán en el - Al listado, incluso aunque se incluya la directiva .LALL. Ejemplo: Los comentarios precedidos por ";" aparecerán en la expansión. Macro para hacer Z: X + Y: SUMAR MACRO X,Y,Z ; comienzo macro :Z:X+Y MOV MOV ADD MOV ENDM AX,X BX,Y AX,BX Z,AX ;; AX: X ;;BX:Y ;;Z :AX ;; AX: AX + BX ; fin macro Expansión para SUMAR PEPE,JUAN,LUIS: , ;Z:X+Y t MOV MOV ADD MOV AX,PEPE BX,JUAN AX,BX LUIS,AX 95 ! : llirectiva¡ I lSigno de c.rcl¿m;rcion). t r¡rrlr,rto: lcar¿icter llt'rr'rrpr'ir)n: Es un operador de macro que se utiliza para tnclicar que ci carácler .¡rr'; viene a ¡;ontinuación ilebe interpretarse en sentido literai, y no c{lrrlo srntholo. tltrrt'rr:rtiones: - Las cntradas lx y (¡) I jtrtt¡rlo; ion equtvalentes. jVI.\L-R()l lVf.\CRO X ivfov .\x.x ; L()ntlenzo lll¿lcrt) \,{.\CRO2 lX ENDIVI l\lA{'RO2 MACRO Y PL]SH Y ENDM : ñrr macro : comienzo macro tru ¿flacrü Lr expansión para MACROI PFPE rierá: N,IOV AX,PEPh. PUSH \ 96 o/o Directiva: 9o (Tanto por ciento). Formato: 9oexpresión Descripción: Es un operador de macro que sirve para convertir una expresión (normalmente, un símbolo) a un número (en la base de numeración activa). Observaciones: - Ejemplo: MACROI MACRO X LB:0 REPT X LB:LB+l Este operador (90) sólo puede usarse como argumento de una macro. Permite usar números como argumentos al invocar a macros, en lugar del argumento interpretado como texto. ; comienzo macro ; comienzo bloque REPT MACRO2 VILB ENDM ENDM MACRO2 MACRO Y ERROR&Y DB ENDM "ERROR &Y" ,0 ; fin bloque REPT ; fin macro ; comienzo macro ;fin macro Con MACROI 3, se generará: ERRORI DB ERROR2 DB ERROR3 DB "ERROR I" ,0 "ERROR 2" ,0 "ERROR 3" ,0 97 ASSUME Directiva: ASSUME - Suponer. Formato: ASSUME registro segmento:nombre-segmento[,...] o ASSUME NOTHINC Descripción: Indica al ensamblador el registro de segmento que se va a utilizar para direccionar cada segmento dentro del módulo. Para acceder al segmento de código debe usarse siempre el registro de segmento CS. Para acceder a los segmentos de datos, se utilizan por defecto los registros DS, ES y SS, según el modo de direccionamiento del operando de la instrucción. ASSUME sigue normalmente a la sentencia SEGMENT. Si no se usa ASSUME, se debe especificar explicitamente el registro de segmento en las instrucciones. Operandos: - "registro-segmento" puede ser: DS, CS, SS o ES. - "nombre-segmento" puede ser: o el nombre asignado por la sentencia SEGMENT. . el nombre de un grupo (sentencia GROUP). . SEG variable. . SEG etiqueta. o la palabra NOTHING. Con NOTHING se anula la ASSUME anterior, debiéndose especificar un registro de segmento como prefijo en los operandos de memoria de las instrucciones. Observaciones: - El ASSUME mínimo requerido en un programa es ASSUME CS:segmento-de-código 98 Sin esta declaración, el ensamblador da error cada vez que aparece en una instrucción de transferencia de control una etiqueta o un nombre de procedimiento. Esto ocurre porque no es capaz de saber si la dirección es dentro del mismo segmento o en otro distinto. Lo mismo es cierto para el acceso a las variables de memoria. Con ASSUME al comienzo del segmento de código, el ensamblador genera automáticamente un código de un byte como prefijo de la ins- trucción, para indicar el registro de segmento a utilizar en la instrucción, en lugar del registro de segmento por defecto, según el modo de direccionamiento. Si el registro de segmento definido en ASSUME coincide con el registro de segmento por defecto, no se genera el código de sustitución del segmento. Por ejemplo, supongamos que TABLA ha sido definido en el segmento de datos. Si en el segmento de código aparece una instrucción con el operando TABLAIDI], se utiliza por defecto el registro de segmento DS, de acuerdo con el tipo de direccionamiento, y no se genera código de prefijo de registro de segmento. Pero si TABLA se ha definido dentro del segmento de código, es necesario especificar como operando CS:TABLAIDI]. En este caso, el ensamblador generará el código correspondiente (un byte como prefijo de la instrucción) para indicar el segmento a utilizar (CS) en lugar del segmento por defecto (DS). La directiva ASSUME no inicializa los registros de segmentos. Para inicializar el registro DS, se utilizan las instrucciones MOV AX,DATOS ; DATOS : nombre del segmento de datos MOV DS.AX Análogamente, para inicializar el segmento extra, MOV AX,EXTRA ; EXTRA: nombre del segmento extra MOV ES.AX Los registros SS y CS los inicializa el cargador de programas del DOS. Es recomendable colocar los segmentos de datos delante del segmento de código. Si se colocan detrás, el ensamblador puede dar errores por dos motivos: No conoce el atributo de los datos durante el proceso del segmento de código (sería necesario, por ejemplo, incluir operadores BYTE PTR, etc.). En el primer paso del ensamblador, se procesan todas las referencias de memoria como si no hubiera sustitución del registro de segmento. En el segundo paso, al incluir los códigos de sustitución del registro de segmento por defecto, puede provocar que los desplazamientos subsiguientes en la tabla de símbolos estén mal alineados. Ello puede dar lugar a un mensaje de "Phase Error" (Error en la Fase). 99 Ejemplo 1: Módulo con segmento de datos y segmento de código: :ATOS SEGMENT ;comienzo segmento DATOS ENDS ; fin segmento CODIGO SEGMENT ; comienzo segmento ASSUME CS:CODIGO,DS:DATOS,ES:NOTHING CODIGO ENDS Ejemplo 2: ; fin segmento Módulo con datos y código en un solo segmento: UNICO SEGMENT ; comienzo segmento ASSUME CS :UNICO,DS:UNICO UNICO ENDS 100 ; fin segmento COMMENT Directiva: COMMENT - Comentario. Formato: COMMENT delimitador texto delimitador. Descripción: Permite insertar comentarios en el programa sin tener que especificar el carácter ":" en cada línea. El primer carácter no blanco actúa como delimitador inicial del comentario. El delimitador final es otro carácter igual al delimitador inicial. Observaciones: - Ejemplo: COMMENT x Esto es un comentario que puede ocupar muchas líneas de Un COMMENT definido dentro del cuerpo de una macro no se lista, a menos que se haya especificado .LALL. :::'" :: hasta que vuelva a aparecer el carácter inicial, en este caso, * 101 .CREF/.XCREF Directiva: .CREF .XCREF Formato: .CREF .XCREF Descripción: Estas directivas controlan la salida o no en el listado ensamblador de la información de las referencias cruzadas. .XCREF suprime el listado de las referencias cruzadas hasta que se encuentre el próximo .CREF (si lo hubiera). .CREF restaura el listado de las referencias cruzadas. Es la opción por defecto. Las referencias cruzadas se usan como ayuda en la depuración de un programa. Consta de un listado (por orden alfabético) de los símbolos y de los números de las líneas donde es referenciado o definido. Ejemplo: .iCngp ; suprime listado referencias cruzadas. .ónpp ; restaura listado referencias cruzadas. 102 DB Directiva: DB - Definir byte (Define Byte). Formato: lnombre-variable] DB expresión[,...] Descripción: Reserva memoria para una variable tipo byte (8 bits), inicializando o no dicho b¡e y los posteriores. "nombre variable" es opcional y es el nombre asignado al primer byte. Operandos: - "expresión" es el valor inicial de la variable, y puede ser: o Una constante positiva o negativa o expresión de constantes. El rango de constantes con signo es: 80h: (mínimo). 7Fh: -128 127 (máximo). El rango de constantes sin signo es: 00h : 0 (mínimo). FFh :255 (máximo). o Un signo "?", que indica indefinición del valor. ¡ Una cadena de caracteres delimitada por comillas simples o dobles. o nl DUP(n2), que indica repetición nl veces de la expresión n2. La expresión n2 tiene la misma definición que "expresión" (podría, por tanto, contener otra DUP). El número de expresiones está limitado por la longitud de la línea. Observaciones: - Ejemplos: VALORES DB 30,-15,20 MAXSS DB 255 ; número máximo sin signo MINSS DB 0 ; número mínimo sin signo MAXCS DB 127 ; número máximo con signo MINCS DB -128 ; número mínimo con signo DB ODh ; retorno de carro DB 11110000b ;equivalente a DB FOh DB 12 x 3 ; expresión de constantes DB DB DB 4 DUP(O) ; es equivalente a DB 0,0,0,0 4 ; es equivalente a DB ?,?,?,? 4 DUP(3 DUP(4),7); es equivalente a DB 4DUP(4,4,4,7) DUP(?) lGf TABLA DB MENSAJE DB MENSAJE DB MENSAJE DB MENSAJE DB TABLA 104 4,?,65 ; no se define el segundo valor ..ERROR" "ERROR",l3,"$" ..PETER'S HOUSE'' .PETER''S HOUSE' cadena de caracteres cadena de caracteres comillas dobles delimitan comillas simples delimitan DB 4 DUP(?),"ERROR",32,-15 DD Directiva: DD - Definir doble palabra (Define Double word). Formato: [nombre_variable] DDexpresiónl,...] Descripción: Reserva memoria para una variable tipo doble palabra (2 palabras: 4 b¡es : 32 bits), inicializando o no dicha doble palabra y las posteriores. "nombre-variable" es opcional y es el nombre asignado a la primera doble palabra. Operandos: - "expresión" es el valor inicial de la variable y puede ser: o Una constante positiva o negativa o expresión de constantes. El rango de constantes con signo es: 80000000h - -2 147 483 648 (mínimo). TFFFFFFFh : 2147 483 647 (máximo). El rango de constantes sin signo es: 00000000h : 0 (mínimo). FFFFFFFFh: 4 294 967 295 (máximo). o Un signo "?", que indica indefinición del valor. o Una dirección completa de memoria (segmento y desplazamiento). o nl DUP(n2), que indica repetición nl veces de la expresión n2. La expresión n2 tiene la misma definición que "expresión" (podría, por tanto, contener otra DUP). Observaciones: orden de almacenamiento de una doble palabra en memoria es el - El slgulente: o primero, la palabra menos significativa; o segundo, la palabra más significativa. A su vez, como cada palabra se almacena con el b¡e menos significa- tivo en primer lugar, el orden resultante es el inverso a nivel byte. Es decir. DD 12345678h se almacena como 78 56 34 12. El número de expresiones está limitado por la longitud de la línea. Ejemplo l: VALORES DD MAXSS DD MINSS DD MAXCS DD 300,-150,2000 4294967295 O 2147483647 MrNCS DD -2147483648 DD 120x3 numero maxlmo sln slgno número mínimo sin signo número máximo con sisno número mínimo con siino expresión de constantel 105 DD 4 DUP(0) ; es equivalente a DD 0,0,0,0 DD 4 DUP(?) ; es equivalente a DD ?,?,?,? DD 4 DUP(3 DUP(4),7); es equivalente a DD 4 DUP(4,4,4,7) TABLA DD 4,?,650 ; no se define el segundo valor TABLA DD 4 DUP(?),320,- 1500 DIREC DD TABLA ; DIREC: desplazamiento y segmen; to de TABLA (en este orden) DIRECS DD TABLA1,TABLA2,TABLA3 Ejempfo 2: Si la dirección de TABLA es 1234h:5678h, es decir, segmento :1234h y desplazamiento : 5678h, DIREC DD TABLA es equivalente a cada una de las siguientes sentencias: DTREC DD 12345678h DrREC DW 5678h.r234h DIREC DB 78h,56h,34h,12h es decir, se almacena primero el desplazamiento (palabra menos significa- tiva) y después el segmento (palabra más significativa). 106 DO Directiva: DQ - Definir cuádruple palabra (Define Quod word). [nombre-variable] DQ expresión[,...] Reserva memoria para una variable tipo cuádruple palabra (4 palabras:8 bytes: 64 bits), inicializando o no dicha cuádruple palabra y las posteriores. "nombre-variable" es opcional y es el nombre asignado a la primera cuádruple palabra. Esta directiva se usa principalmente en aplicaciones de punto flotante. Operandos: - "expresión" es el valor inicial de la variable y puede ser: o Una constante positiva o negativa o expresión de constantes. El rango de constantes con signo es: 8000000000000000h : -9 223 372 036 854 775 808 (mín.) TFFFFFFFFFFFFFFFh : 9 223 372 036 854 775 807 (máx.) El rango de constantes sin signo es: 0000000000000000h : 0 (mínimo). FFFFFFFFFFFFFFFFh : l8 446 774 073 709 551 615 (máx.) o Un signo "?", que indica indefinición del valor. ¡ nl DUP(n2), que indica repetición nl veces de la expresión n2. La expresión n2 tiene la misma definición que "expresión" (podría, por tanto, contener otra DUP). Observaciones: - El orden de almacenamiento de una cuádruple palabra en memoria es el siguiente: . primero, la doble palabra menos significativa. o segundo, la doble palabra más significativa. A su vez, como cada doble palabra se almacena con la palabra menos significativa en primer lugar, y cada palabra también se almacena con el byte menos significativo primero, el orden resultante es el inverso a nivel byte. Es decir, DQ 0123456789ABCDEFh se almacena como EF CD AB 89 67 45 23 0t. El número de expresiones está limitado por la longitud de la linea. 107 Ejemplos: VALORES DQ 300,-150,2000 MAXSS DQ 18446744073709ss16t5 MINSS DQO MAXCS DQ 92233720368s477s807 MINCS DQ - 922337 203 68 5 47 7 5808 DQ 120x3 TABLA TABLA 108 numero maxlmo sln slgno número mínimo sin sisno número máximo .o.r rigno número mínimo con sisno expresión de constantei DUP(O) DUP(?) DQ DQ DQ 4 4 DQ DQ 4,?,650 ; es equivalente a DQ 0,0,0,0 ; es equivalente a DQ ?,?,?,? 4 DUP (3 DUP(4),7); es equivalente a DQ 4 DUP(4,4,4,7) 4 DUP(?),320,-1500 ; no se define el segundo valor DT Directiva: DT - Definir diez bytes (Define Ten bytes). Formato: [nombre-variable] DTexpresión[,...] Descripción: Reserva diez bytes de memoria para almacenar dígitos decimales empa- quetados (dos dígitos decimales por b¡e). El primer byte se reserva para el signo y los otros nueve para almacenar l8 dígitos decimales. El signo se almacena como 00h (si positivo) o 80h (si negativo) en el pri- mer byte. "nombre-variable" es opcional y es el nombre asignado al primer byte. Operandos: - "expresión" es el valor inicial de la variable, y puede ser: o Una constante positiva o negativa o expresión de constantes. r Un signo "?", que indica indefinición del valor. o nl DUP(n2), que indica repetición nl veces de la expresión n2. La expresión n2 tiene la misma definición que "expresión" (podría, por tanto, contener otra DUP). Observaciones: Ejemplo 1: - El número de expresiones está limitado por la longitud de la línea. NMAS DT 0123456789 ; reserva l0 bytes. Esta sentencia es equivalente a: Ejemplo 2: NMAS DB 00h,4DUp(?),OIh,23h,45h,67h,99h NMENOS DT -0123456789 ; reserva l0 bytes. Esta sentencia es equivalente a: NMENOS DB 80h,4 DUp(?),01h,23h,45h,67h,89h 109 DW DW - Definir palabra (Define Word). [nombre-variable] DW expresión[,...] Reserva memoria para una variable tipo palabra (2 bytes o 16 bits), cializando o no dicha palabra y las posteriores. "nombre variable" es opcional y es el nombre asignado a la primera palabra. Operandos: - "expresión" es el valor inicial de la variable y puede ser: ¡ Una constante positiva o negativa o expresión de constantes. El rango de constantes con signo es: (mínimo). 8000h : TFFFh : -32768 32'767 (máximo). El ranso de constantes sin sisno es: 0 (mínimo). 0000h FFFFh: 65535 (máximo). o Un signo "?", que indica indefinición del valor. . El desplazamiento (offset) de una variable. ¡ nl DUP(n2), que indica repetición nl veces de la expresión n2. La expresión n2 tiene la misma definición que "expresión" (podría, por tanto, contener otra DUP). Observaciones: orden de almacenamiento de una palabra en memoria es el si- El guiente: o el byte menos significativo (byte 0 : bits 0 a 7). . el byte más significativo (byte 1 : bits 8 a l5). Es decir. DW 1234h se almacena como 34 12. - El número de expresiones está limitado por la longitud de la línea. Ejemplos: 110 VALORES DW 300,-150,2000 MAXSS DW 65535 MINSS DW 0 MAXCS DW 32767 MINCS DW -32768 DW 120 * 3 ; número máximo sin signo ; número mínimo sin signo ; número máximo con signo ; número mínimo con signo ; expresión de constantes DW DW t234h ; es equivalente a DB 34h, l2h 1l I1000011110000b ; equivalente a DW F0F0h DW 4 DUP(0) ; es equivalente a DW 0,0,0,0 DW 4 DUP(?) ; es equivalente a DW ?,?,?,? DW 4 DUP (3 DUP(4),7); es equivalente a DW 4DUP(4,4,4,7) TABLA DW 4,?,650 TABLA DW 4 DUP(?),320,- 1500 ; no se define el segundo valor DIREC DW TABLA ; DIREC : desplazamiento de TABLA DIREC DW TABLA + l0 ; DIREC: desplazamiento de TABLA + l0 DIRECS DW TABLAI,TABLA2,TABLA3 DIRECS DW TABLAI-TABLA2+4 END Directiva: END - Fin. Formato: END [expresión] Descripción: Indica el final del programa fuente. El operando "expresión" indica la dirección de comienzo del programa fuente. Normalmente, se especifica una etiqueta. Observaciones: - Si el programa consta de un solo módulo fuente, entonces "expresión" es opcional. - En el caso de varios módulos fuentes que se montan juntos para formar un solo programa ejecutable, sólo el módulo principal puede especificar "expresión". Si dicho módulo principal no lo utiliza, entonces no se pasa la dirección de comienzo del programa al montador (linker). Ejemplo 1: END fin del módulo fuente Ejemplo 2: END EMPEZAR fin del módulo fuente principal 112 ENDM Directiva: ENDM - Fin de macro ,(END Macro) Formato: ENDM Descripción: Indica el final de una de las directivas siguientes: MACRO, REPT, IRP e IRPC. Ejemplo 1: Macro para hacer Z: X + Y: SUMAR MACRO X,Y,Z ; comienzo macro MOV AX.X : AX: X MOV BX,Y : BX: Y ADD AX,BX i AX: AX + BX MOV Z,AX ; Z: AX ENDM : fin macro Ejemplo 2: Macro para reservar cinco palabras inicializadas, respectivamente, con los cuadrados de los cinco primeros números naturales. CUADS MACRO IRP DW ENDM ENDM ; comienzo macro VALOR, <1,2,3,4,5> ; comienzo bloque IRP VALOR x VALOR ; fin bloque IRP ; fin macro La expansión de la macro será: DWI DW4 DW9 DW t6 DW 25 113 ENDP Directiva: ENDP - Fin de procedimiento (END Procedure). Formato: nombre-procedimiento ENDP Descripción: Indicael finaldelprocedimiento "nombre-procedimiento". Observaciones: - El bloque de sentencias de un procedimiento es: nombre-procedimiento PROC atributo ; comienzo procedimiento. ::: nombre-procedimiento ENDP Ejemplo: 114 PROCI PROC FAR .:. RET PROCI ENDP ; fin procedimiento. ; comienzo procedimiento ; cuerpo del procedimiento ; retorno del Procedimiento ; fin Procedimiento ENDS Directiva: ENDS - Fin de segmento (END Segment). ENDS - Fin de estructura (END Structure). Formato: nombre-segmento ENDS nombre-estructura ENDS Descripción: Indica el final del segmento "nombre-segmento", o bien indica el final de la estructura "nombre estructura". Observaciones: - El bloque de sentencias de un segmento eS: nombre-segmento SEGMENT ; comienzo segmento ná-Ur"-r.gmento ENDS ; fin segmento - El bloque de sentencias de una estructura es: nombre-estructuraSTRUC :comienzoestructura ,rá-U..-.rtructura ENDS Ejemplo l: SEGMENTOI SEGMENT ; fin estructura ; comienzo segmento ; cuerpo del segmento Ejemplo 2: SEGMENTOl ENDS ; fin segmento ESTRUCl ; comienzo estructura STRUC ; cuerpo de la estructura ESTRUCl iñps ; fin estructura 115 EOU Directiva: EQU - Equivalencia (EQUivalence). Formato: nombre EQU expresión Descripción: Asigna un nombre simbólico al valor de una expresión. "expresión" puede ser: una constante numérica: una referencia de dirección (utilizando cualquier modo de direccionamiento); o cualquier combinación de símbolos y operaciones que pueda evaluarse como un valor numérico: . otro nombre simbólico. La utilidad de esta directiva reside en hacer más claras las sentencias fuentes ensamblador. Observaciones: contrario que la directiva (' :", "nombre" no puede redefinirse, - Al es decir, no puede cambiarse la expresión asociada al nombre a lo largo de todo el módulo fuente. EQU no puede usarse dentro de una estructura (entre las directivas STRUC y ENDS). EQU es útil en el caso de acceder a una variable o etiqueta con un atributo diferente. Mediante el operador PTR, se puede asignar un nombre nuevo, dándole un nuevo atributo: LONCITUD DW O BYTE-I EQU BYTE PTR LONGITUD BYTE-2 EQU BYTE PTR LONGITUD+I variable tipo palabra primer byte segundo byte ETIQUE EQU FAR PTR ETIQUETA Ejemplos: 116 CoLUMNAS EQU 80 FILAS EQU 2s PANTALLA EQU FILAS * COLUMNAS EQU BYTE PTR ES:[SI] CARAC K EQU 1024 ;'l Kbyte longitud de una línea número de filas tamaño de la pantalla CR LF CONTADOR MOVER EQU EQU EQU EQU l3 l0 CX MOV retorno de carro alimentación de línea nombre alternativo de CX nombre alternativo de MOV 717 EVEN Directiva: EVEN - Par. Formato: EVEN Descripción: Fuerza al contador de posiciones a un valor par, es decir, a una frontera de palabra. Si el contador de posiciones es un número par, EVEN no hace nada. Si el contador de posiciones es un número impar, EVEN añade una instrucción NOP (no operación), que ocupa un byte. Con esta directiva se asegura que el código o los datos que vienen detrás de esta sentencia están en una dirección de memoria par. Observaciones. residen en una direc8086 tarda más tiempo en transferir datos - El ción par que en una impar. La utilidad de EVEN en este caso es obvia. Ejemplo: Si el contador de posiciones es 0025h, que EVEN hace que se genere NOP (l byte con 90h) y que el contador se convierta en 0026h. 118 EXITM Directiva: EXITM - Salir de la macro (EXIT Mauo). Formato: EXITM Descripción: Esta directiva se usa en el caso en que un bloque MACRO, REPT, IRP o IRPC, y eue, como consecuencia de una directiva condicional anterior, se desee terminar con la expansión. Ejemplo: Macro para reservar N bytes con valores I a N. El valor de N deberá ser menor o igual a 5. Si es mayor que este número, se reservarán sólo 5 bytes. ALOCAR MACRO N VALOR :0 VALOR VALOR + I IF VALOR EQ 6 EXITM ENDIF DB VALOR ENDM ENDM REPT N comlenzo macro comienzo bloque REPT si VALOR es 6 salir del bloque REPT fin bloque REPT fin macro Si se invoca mediante la sentencia TABLA1 ALOCAR 4 la expansión de la macro será: TABLAI DB I DB2 DB3 DB4 Pero si se invoca mediante la sentencia TABLA2 ALOCAR 20 la expansión de la macro será: TABLA2 DB DB2 DB3 DB4 DB5 1 119 EXTRN Directiva: EXTRN. Formato: EXTRN nombre:tipo[,...] Descripción: Identifica a los símbolos que fueron definidos (y declarados PUBLIC) en otro módulo. Operandos: - "nombre" es el símbolo definido en otro módulo, que puede ser: un nombre de variable; una etiqueta (inclusive un nombre de procedimiento). - "¡ip6" puede ser BYTE, WORD, DWORD, NEAR, FAR o ABS. ¡ BYTE, WORD, DWORD para variables tipo byte, palabra o doble palabra. o NEAR, FAR para etiquetas o nombres de procedimientos del mismo o de diferente seqmento. . ABS se utiliza para definir constantes de 16 bits. Una declaración EXTRN X:ABS es lo mismo que X EQU expresión, excepto que la expresión es aportada por el montador (linker) a partir del valor PUBLIC de un módulo externo. 0bservaciones: - La declaración EXTRN puede aparecer: ¡ dentro del mismo segmento en que se utiliza la referencia a "nombre"; o fuera de todos los segmentos. En este caso, para acceder a las va- riables es necesario especificar un prefijo de segmento en el acceso a los datos, o bien usar ASSUME DS:SEG variable Ejemplo 1: Si se quiere acceder al procedimiento PROC1, que reside en otro módulo y en el mismo segmento, hay que incluir EXTRN PROCI:NEAR Ejemplo 2: Si se quiere acceder al procedimiento PROCI, que reside en otro módulo y en distinto segmento, hay que incluir EXTRN PROCI:FAR 120 Ejemplo 3: Si se quiere acceder a la variable TOTAL (de una palabra) de otro módu- lo, hay que incluir la sentencia EXTRN TOTAL:WORD Ejemplo 4: Si se desea bifurcar a la instrucción de etiqueta ETIQ de otro módulo y del mismo segmento, hay que incluir EXTRN ETIQ:NEAR Ejemplo 5: Si se desea bifurcar a la instrucción de etiqueta ETIQ de otro módulo y de distinto segmento, hay que incluir EXTRN ETIQ:FAR 121 GROUP Directiva: CROUP - Grupo. Formato: nombreGROUPnombre-segmento[,...] Descripción: Agrupa dos o más segmentos lógicos en un solo segmento físico, bajo un nombre que es el del segmento físico. El conjunto de los segmentos agrupados debe ocupar como máximo 64Kb, aunque este límite no lo comprueba el ensamblador. "nombre" es el nombre del grupo de segmentos. Este nombre puede ser el mismo que uno de los "nombre-segmento" definidos a continuación. "nombre-segmento" puede ser: . un nombre de segmento (definido en SEGMENT). . un operador SEG variable. . un operador SEC etiqueta. Observaciones: - Para direccionar a todos los segmentos del grupo, basta con inicializar el correspondiente registro de segmento. Por ejemplo, MOV AX,GRUPO-DATOS ; CRUPO-DATOS es el nombre del ; grupo MOV DS,AX Se puede usar el nombre del grupo en la directiva ASSUME: ASSUME DS:GRUPO-DATOS El nombre del grupo puede utilizarse como prefijo de un operando: MOV AX, GRUPO-DATOS :TABLA DW GRUPO-DATOS:TABLA El operador OFFSET necesita como prefijo el nombre del grupo si la variable referenciada está dentro de un grupo: MOV AX.OFFSET GRUPO-DATOS :TABLA LEA AX,TABLA ;equivalente Mediante la directiva GROUP se puede combinar datos con código sin privar al programador de los segmentos. Esta instrucción se utiliza en los programas COM y en los drivers de dispositivos, pues ambos tipos de programas deben ocupar un solo segmento físico. 122 Una alternativa para crear un programa de un solo segmento es mezclar código y datos dentro del segmento. La desventaja es que se pierde la ventaja de los segmentos, y además todas las referencias a los datos deben llevar prefijo de segmento. Ejemplo 1: Agrupación de tres segmentos de código, dos de ellos en un módulo y el tercer segmento en otro módulo. Primer módulo: GRUPO GROUP SEG1,SEG2 ; SEGI y SEG2 en el grupo ; GRUPO SEGI SEGMENT ASSUME CS:GRUPO ; comienzo segmento SEGI ..: SEGI iÑls ; fin segmento SEGI SEC2 SEGMENT ; comienzo segmento SEG2 ASSUME CS:GRUPO : SEG2 ENDS ; fin segmento SEC2 END Segundo módulo: GRUPO GROUP SEG3 SEG3 SEGMENT jjttt" SEG3 ENDS END Ejemplo 2: cS:GRUPo ; SEG3 en el grupo GRUPO ; comienzo segmento SEG3 ; fin segmento SEG3 Agrupación de dos segmentos de un mismo módulo, uno de código y otro de datos. GRUPO GROUP SEG1,SEG2 ; SEGI y SEG2 en el grupo : GRUPO 123 SEGI SEGMENT ; comienzo segmento SEGI ASSUME CS:GRUPO.DS:GRUPO código SEGI iños fin segmento SEGI SEG2 SEGMENT comienzo segmento SEG2 datos SEG2 Éños END 124 fin segmento SEG2 IF Directiva: Formato: IFxxx - Si (condicional). T*" [condición] l:*" [condición] iÑorp ::tu Éñorr Descripción: Las directivas que comienzan por "IF" son directivas condicionales. Sirven para que el ensamblador incluya o no las sentencias que vienen a continuación, según se cumpla o no una determinada condición. Si la condición es cierta, se incluye el bloque IF (sentencias comprendidas entre lF y ELSE). Si la condición es falsa, se incluye el bloque ELSE (sentencias comprendidas entre ELSE y ENDIF). El bloque ELSE es opcional. Si no existe, es necesario incluir la sentencia ENDIF. Directiva IF IFE expresión expresión IFI TF2 IFDEF símbolo IFNDEF símbolo IFB (arg) IFNB (arg) IFIDN largl>-,{arg2} IFIDF largl),1arg2) Observaciones: Condición expresión distinta de cero expresión igual a cero paso I del ensamblador paso 2 del ensamblador símbolo definido o declarado externo símbolo no definido ni declarado externo argumento en blanco argumento no en blanco argumentol idéntico a argumento2 argumentol diferente de argumento2 IFB e IFNB se usan para chequear la existencia de argumentos en una macro. Hay que incluir los paréntesis angulares. Se pueden anidar directivas condicionales. Es conveniente, para dar mayor claridad al programa, desplazar dos posiciones a la derecha las sentencias dentro de un bloque IF o ELSE. En el caso de directivas condicionales anidadas se hace imprescindible. Un aplicación de las directivas condicionales es la posibilidad de hacer diferentes versiones de un programa, poder incluir sentencias con resultados intermedios para depuración del programa, etc. 125 Ejemplo 1: Incluir sentencias de prueba del programa si símbolo PRUEBA es igual cero. PRUEBA: O IF PRUEBA EQ O ; instrucciones que se utilizan sólo en pruebas ENDIF Ejemplo 2: Directivas condicionales anidadas (sin opción ELSE): IF condición1 IF condición2 :: :)"'u ENDIF Ejemplo 3: Directivas condicionales anidadas (con opción ELSE): IF condiciónl IF condición2 :: ELSE :)"" ENDIF 126 : Formato: : (Signo igual). nombre : expresión Descripción: Asigna un nombre simbólico al valor de una expresión' Directiva: "expresión" puede ser: . una constante numérica: . una referencia de dirección (utilizando cualquier modo de direccionamiento); . ::*:"i:'r;lTlffi?nde símbolos y operaciones que pueda evaluarse . otro nombre simbólico. Observaciones: - Esta directiva es similar a EQU, excepto que "nombre" puede redefinirse, es decir, puede cambiarse la expresión asociada al nombre a lo largo de todo el módulo fuente. La directiva ":" es muy útil en operaciones iterativas y en macros' Ejemplo 1: VALOR : IO Ejemplo 2: DIREC : BYTE PTR ES:[SI] ; definición DIREC : WORD PTR ES:[SI] ; cambia la definición Ejemplo 3: Reservar 3 bytes inicializados respectivamente con los cuadrados de los cuatro primeros números naturales (véase directiva REPT). VALOR:VALOR+l :O N REPT 4 :N+l N DB N*N ENDM nombre de la constante 10 utiliza la definición anterior, es decir, ahora VALOR es 1l ; comienzo bloque REPT ; fin bloque REPT El ensamblador genera: DBI DB4 DB9 DB 16 1n INCLUDE Directiva: INCLUDE - Incluir. Formato: INCLUDE nombre-de-fichero Descripción: Incluye un fichero de sentencias fuentes. "nombre-de-fichero" es el nombre completo del fichero de sentencias fuentes a incluir. El conjunto de sentencias fuentes que constituyen el fichero se incluyen a continuación de esta sentencia. Cuando se encuentra el fin del fichero. se continúa el ensamblaje con la sentencia que sigue a INCLUDE. Mediante la utilización de esta directiva se elimina la necesidad de repetir un conjunto de sentencias comunes en el mismo o en diferentes módulos fuentes. 0bservaciones: - No se permiten INCLUDEs anidados, es decir, uno dentro de otro. En el listado ensamblador las sentencias incluidas se marcan con una "C" en la columna 30 de cada línea. La columna 31 se deja en blanco. Las sentencias incluidas empiezan en la columna 32. Las macros que residen en ficheros separados deben incluirse en el - mer paso del ensamblador con: IFI INCLUDE nombre-fichero ENDIF Ejemplo 1: Si PROLOGO.ASM contiene: ASSUME CS:CODIGO.DS:DATOS MOV AX,DATOS MOV DS,AX entonces, DATOS SEGMENT ÍNcr-uoe PRoLoGo.ASM DATOS ENDS 1n pri- es equivalente a: DATOS SEGMENT ASSUME CS:CODIGO.DS:DATOS MOV AX.DATOS MOV DS,AX DATOS ENDS Ejemplo 2: Incluir fichero MACROI.ASM en el primer paso del ensamblador. IFI INCLUDE MACROI.ASM ENDIF 129 IRP Directiva: IRP. Formato: IRP nombre,(lista-de-argumentos) Descripción: Hace que el bloque de sentencias comprendidas entre IRP y ENDM se repita una vezpara cada argumento, sustituyendo "nombre" por el corres- pondiente argumento. Observaciones: Ejemplo 1: - La lista de argumentos debe delimitarse con los caracteres "(" y ">" (paréntesis angulares). - Los argumentos se separan por comas. - El bloque IRP-ENDM no es necesario que resida dentro de una definición MACRO. Si la lista de argumentos es nula (()), el bloque de sentencias se repite una vez. eliminando "nombre". Reservar cinco palabras inicializadas respectivamente con los cuadrados de los cinco primeros números naturales. IRP VALOR,<l,2,3,4,5> ;comienzo bloque IRP DW VALOR*VALOR ; fin bloque IRP ENDM El ensamblador genera: DWI DW4 DW9 DW 16 DW 25 Ejemplo 2: El mismo ejemplo anterior como macro. CUADS MACRO IRP VALOR,<I,2,3,4,5> DW VALOR*VALOR ENDM ENDM ; comlenzo macro ; comienzo bloque IRP ; fin bloque IRP ; fin macro Utilización: CUADS El ensamblador genera lo mismo que en el caso anterior. 130 IRPC Directiva: IRPC. Formato: IRPC nombre, cadena-de-caracteres o IRP C nombre,(cad ena-de-caracteres) Descripción: Hace que el bloque de sentencias comprendidas entre IRPC y ENDM serepita una vez por cada carácter de la cadena, sustituyendo "nombre" por el correspondiente carácter. Observaciones: directiva es similar a IRP, excepto - Esta sustituye por una cadena de caracteres. que la lista de argumentos se - Los caracteres "1" y ")t' son opcionales. Si la lista de argumentos es nula (()), el bloque de sentencias se repite - una vez, eliminando "nombre". bloque IRPC-ENDM no es necesario - El nición MACRO. Ejemplo l: que resida dentro de una defi- Reserva cinco bytes con los valores de los cuadrados de los cinco primeros números naturales. IRPC NUM,<12345> ; comienzo bloque IRPC DB NUM*NUM ENDM ;fin bloque IRPC En este caso, el ensamblador generará: DBI DB4 DB9 DB 16 DB 25 Ejemplo 2: El mismo ejemplo anterior como macro: CUADS MACRO ; comienzo macro IRPC NUM,<12345> ; comienzo bloque IRPC DB NUM*NUM ENDM ENDM ; fin bloque IRPC ; fin macro La expansión de la macro, cuando se invoque, será la misma que en el caso anterior. 131 LABEL Directiva: Formato: LABEL - Etiqueta. nombre LABEL tipo Descripción: Define el atributo de "nombre". "nombre" puede ser: . el nombre de una estructura: . una etiqueta. "tipo" puede ser: - para áreas de datos: O BYTE; . WORD (palabra); . DWORD (doble palabra); o el nombre de una estructura: o el nombre de un registro. - para código ejecutable: . NEAR (mismo segmento); . FAR (distinto segmento). Sirve para asignar diferentes nombres a variables o etiquetas, con posibilidad de cambiar el atributo definido en la sentencia siguiehte. Observaciones: La directiva LABEL no puede utilizarse dentro de una definición de - estructura (bloque STRUC-ENDS). Los nombres de estructura y de registro son tipos de datos definidos por el usuario con las directivas STRUC y RECORD. Ejemplo 1: Definiendo la variable TABLA con atributo WORD (palabra): TABLA DW 0 ; una palabra con valor cero para poder referenciar a esta variable con atributo BYTE, se define: TABLAB LABEL BYTE ; TABLAB definida como BYTE TABLA DW 0 ;una palabra con valor cero Ambas sentencias deben ir seguidas y se refieren a la misma dirección, pero sus atributos son distintos. Ejemplo 2: Definiendo la etiqueta ETIQ con atributo NEAR (lleva como sufijo ":"): ETIQ: para poder bifurcar a esta etiqueta desde distinto segmento (atributo FAR), se define: ETIQF LABEL FAR ETIQ: ; ETIQF definida como FAR ; ETIQ definida como NEAR Ambas sentencias deben ir seguidas y se refieren a la misma dirección dentro del código ejecutable, pero tienen atributos distintos. Ejemplo 3: TABLAB LABEL WORD : TABLAB nombre alternativo de : TABLA TABLA DW O ; una palabra con valor cero 1:¡:t . LALL/.SALL/.XALL Directiva: .LALL .SLALL .XALL Formato: .LALL .SLALL .XALL Descripción: Estas directivas controlan la aparición o no en el listado de salida del ensamblador de las expansiones de las macros, .LALL lista las macros y sus expansiones. .SLALL suprime el listado de las macros y sus expansiones. .XALL lista sólo las sentencias fuentes de las macros que generan código objeto. Es la opción por defecto de las tres. Ejemplo: .LALL ; lista marcos y expansiones :: .SLALL ; suprime listado macros y expansiones :: .XALL 1g ; lista sentencias que generan código objeto . LFCON D /.SFCON D /.TFCON D Directiva: .LFCOND .SFCOND Listar bloques condicionales falsos. (List False CONDitionals). Suprimir el listado de los bloques condicionales falsos (Suppress False CONDitionols). .TFCOND Invertir el modo de listado de los bloques condicionales falsos. (Toggle Folse CONDitionals). Formato: .LFCOND .SFCOND .TFCOND Descripción: Estas directivas controlan la aparición o no en el listado de salida del ensamblador de los bloques condicionales falsos. Un bloque condicional falso es el conjunto de sentencias asociadas a una condición que no se cumple. Por ejemplo, si MODO es cero, el bloque condicional falso es el bloque ELSE-ENDIF. Si MODO no es cero, es el bloque IFE-ELSE: :0 rF MODO EQ 0 : si MODO ELSE : en caso contrarlo ENóiF ; fin bloque IF .LFCOND lista los bloques asociados a una condición falsa. .SFCOND suprime el listado de los bloques asociados a una condición falsa. .TFCOND invierte el modo de listado de los bloques asociados a una condición falsa; es decir, si está activa, lo desactiva, y viceversa. ; listar bloques condicionales falsos Ejemplo: ,i"ao*" 135 ; suprimir listado bloques condicionales falsos ,:,OaO*" .TFCOND ;invertir el modo de listado de los bloques condicionales : falsos 136 .LIST /.XLIST Directiva: .LIST .XLIST Formato: .LIST .XLIST Descripción: Estas directivas controlan la generación o no del listado de salida del ensamblador. .XLIST suprime el listado de las sentencias fuentes y del código objeto hasta que se encuentre el próximo .LIST (si lo hubiera). LIST restaura el listado. Es la opción por defecto. Ejemplo: ... ; suprime listado .:tttt .i-fSf : restaura listado. 137 LOCAL Directiva: LOCAL - Local Formato: LOCAL etiqueta[,...1. Descripción: Indica al ensamblador las etiquetas que debe cambiar cadavez que expan- de la macro. Con ello se evitan las definiciones rnúltiples de estas etiquetas. Si se usa, debe ser la primera sentencia del cuerpo de la macro, es decir, debe ir a continuación de la directiva MACRO. Observaciones: - LOCAL sólo puede usarse dentro de la definición de una macro. No se permiten comentarios (ni directiva COMMENT ni secuencias ";") entre las directivas MACRO y LOCAL. Los símbolos creados por el Assembler para las etiquetas declaradas LOCAL son de la forma: ..0000 a ..FFFF Ejemplo: Definición macro: esperar hasta que NUMERO sea igual a 0. ESPERAR MACRO NUMERO LOCAL SEGUIR MOV : comienza macro CX,NUMERO SEGUIR: LOOP SECUIR ENDM ; fin macro Utilización de la macro en varios puntos del programa: MOV CX.500 ESPERAR iüov cx,6oo ESPERAR Al expandir la macro, la etiqueta SECUIR aparecería dos veces si no se hubiera declarado LOCAL. 138 MACRO Directiva: MACRO. Formato: Nombre MACRO lista-de-parámetros iñornl Descripción: Especifica el nombre y los parámetros de |a macro. Los parámetros se separan por comas. Esta sentencia es la cabecera de la macro. El final de la macro se indica mediante la directiva ENDM. Entre ambas directivas se incluyen las sentencias que constituyen el cuerpo de la macro. Una macro es un bloque de sentencias ensamblador que utiliza una serie de parámetros. La invocación de la macro consiste en especificar el nombre de Ia macro, junto con los argumentos: nombre lista-de-argumentos Cada argumento se corresponde con cada parámetro. Hace que se incluya el bloque de sentencias que constituyen el cuerpo de la macro, sustituyen- do los parámetros de la macro por los argumentos. A este proceso se le llama "expansión" de la macro. Las líneas generadas se indican mediante el signo " + " en la columna 31. La columna 32 se deja en blanco. La columna 33 se corresponde con la I del módulo fuente. Observaciones: - - Ejemplo 1: Pueden existir macros sin parámetros' El número de argumentos en la invocación de una macro no tiene por qué coincidir con el número de parámetros. Si hay más argumen- tos que parámetros, se ignoran los argumentos que sobran. Si hay menos argumentos que parámetros, los parámetros que faltan se convierten en nulos. El nombre de una macro puede ser el de una directiva o el de una instrucción ensamblador. En este caso, se utiliza la definición de la macro, sustituyendo al significado normal. Si se utiliza la directiva PURGE, se restaura el significado original. Macro para hacer Z:X+Y: SUMAR MACRO X,Y,Z MOV AX,X MOV BX.Y comlenzo macro AX: X BX: Y 139 ADD AX.BX MOV Z,AX AX=AX+BX ENDM fin macro Z =AX Expansión para SUMAR PEPE,JUAN,LUIS: MOV MOV AX,PEPE ; AX: X BX,JUAN ;BX:Y ADD AX,BX ; AX : AX + BX MOV LUIS,AX ;Z :AX Ejemplo 2: Macro sin parámetros: DOS MACRO INT zlh ; comlenzo macro ; llamar al DOS INT 2lh : llamar al DOS ENDM ; fin macro Expansión: 1¡t0 NAME Directiva: NAME - Nombre del módulo objeto. Formato: NAME nombre-del-,rnódulo-objeto Descripción: Asigna un nombre al módulo objeto. Observaciones: El nombre del módulo objeto no puede ser una palabra reservada. Esta directiva no puede tener etiqueta. No puede haber más que una NAME por módulo fuente. El nombre del módulo objeto se pasa al montador (LINK). El ensamblador selecciona el nombre del móduio objeto de acuerdo con el criterio siguiente: o Si existe NAME, de esta directiva. o Si no existe NAME, de la directiva TITLE. El nombre son los seis primeros caracteres del texto especificado en esta sentencia, siempre que sean legales como nombre de fichero. o Si no existe ni NAME ni TITLE (o existe pero los caracteres son ilegales), entonces el nombre del módulo objeto se forma a partir del nombre del módulo fuente. Por ejemplo, si el módulo fuente es MODULO.ASM, el módulo objeto es MODULO.OBJ. Ejemplo: NAME MODULOI ; asigna el nombre MODULOI al módulo objeto. 141 ORG Directiva: ORG - Origen (ORiCin). Formato: ORG expresión Descripción: Pone el contador de posiciones con el valor de "expresión". "expresión" debe evaluarse como un número absoluto de 16 bits. El ensamblador almacenará el código a partir de esa dirección (desplazamiento a partir del origen del segmento). Observaciones: Es necesario especificar ORC l00h en programas que se vayan a con- vertir a tipo COM. "expresión" puede indicarse mediante el carácter "$", que indica el valor actual del contador de posiciones. ORG no puede usarse dentro de una estructura (bloque STRUC ENDS). Ejemplo 1: ORG l00h ; desplazamiento : l00h :256 respecto al origen del ; segmento Ejemplo 2: ORC $+¿ ; contador de posiciones+4 (reserva 4 bytes) Ejemplo 3: Saltar a una frontera de 256 bytes (véase directiva IF): RESTO : $ MOD 256 ; resto de la división contador/256 IF RESTO NE 0 ; si resto no cero (no alineado) ORG S+256-RESTO : alinear ENDIF 142 o/oOUT Directiva: 9oOUT. Formato: 9oOUT texto Descripción: Esta directiva sirve para escribir un mensaje por pantalla durante el ensamblaje del programa. Se utiliia a ménuáo para indicar qué camino ha sido elegido en una determinada condición. Observaciones: Si el listado completo del módulo ensamblador es por pantalla, se ignoran las sentencias 9oOUT. Ejemplo: IF MODO EQ 0 9oOUT MODO NORMAL '.: ; si MODO:0 ELSE 9oOUT MODO PRUEBAS : en caso contrarlo ENóir ; fin bloque IF 1¡lí| PAGE Directiva: Formato: PAGE - Página. PAGE [operandol][,operando2] Descripción: Define la longitud y el tamaño de la página del listado de salida del ensamblador. Cada página del listado producida por el ensamblador contiene un número de capítulo y un número de página, separados por un guión. El operandol puede ser: o Número de líneas por página (10 a 255). por defecto, supone 66. o El signo " *", que indica nuevo capítulo (se incrementa en l) y página igual a l. El operando2 es la anchura de la línea (60 a 132). Por defecto, supone 80. Observaciones: Si se usa PAGE sin operandos, se genera un salto de página y se incre- menta en uno el número de la página. El número de la página se incrementa cuando se completa una página o se encuentra PAGE sin operandos. El número del capítulo se incrementa sólo con pAGE +. En ambos casos hay salto de página. Ejemplos: PAGE ; 66 líneas de 80 caracteres PAGE 88,132 ; 88 líneas de 132 caracteres PAGE 88 ; 88 líneas de 80 caracteres PACE ,132 ; 66 líneas de 132 caracteres PAGE + ;nuevocapítulo 14 PROC Directiva: PROC - Procedimiento (PROCedure). Formato: nombre-procedimiento PROC [atributo] Descripción: Indica el comienzo del procedimiento "nombre- procedimiento". Un procedimiento es un bloque de instrucciones que sirve para realizar una tarea determinada y que puede invocarse desde varios puntos del programa. Puede considerarse como una subrutina. Un procedimiento puede ejecutarse: o En línea. o Por sentencia de transferencia. o Por sentencia CALL. Operandos: puede ser NEAR o FAR (supone NEAR). - "atributo" puede Un procedimiento NEAR sólo se llamar desde el segmento en que está definido o desde un segmento que tiene el mismo valor definido en ASSUME CS. Al llamar a un procedimiento NEAR, se guarda sólo el desplazamiento (valor de lP) de la instrucción siguiente en la pila, que se recupera al retornar de un procedimiento con la instrucción RET. Un procedimiento FAR se puede llamar desde cualquier segmento. Al llamar a un procedimiento FAR, se guarda el segmento y el desplazamiento (valor de IP) de la instrucción siguiente en la pila, en este orden, valores que se recuperan al retornar del procedimiento con la instrucción RET. Observaciones: - El bloque de sentencias de un procedimiento es: nombre-procedimientoPROCatributo ; comienzo prpcedimiento ná*Ur.-procedimiento ENDP ; fin procedimiento Si se desea que un procedimiento de un módulo sea accesible desde - otros módulos, debe utilizarse la directiva PUBLIC. es procedimiento principal de un programa, el atributo debe ser - Si FAR. 1¡15 Ejemplo: Procedimiento PROCI que quiere hacerse accesible desde otros módulos: PUBLIC PROCI PROCI PROC FAR ; comienzo procedimiento RET PROCI ENDP 16 ; fin procedimiento PUBLIC Directiva: PUBLIC - Público. Formato: PUBLIC símbolo[,...] Descripción: Permite que los símbolos especificados sean accesibles por otros módulos, que serán montados conjuntamente, es decir, procesados por el programa LINK. Operandos: - "símbolo" puede ser: o Un nombre de variable. o Una etiqueta (inclusive un nombre de procedimiento). o Una constante de 16 bits. Observaciones: - Ejemplo 1: El módulo que usa un símbolo definido con PUBLIC debe contener una sentencia directiva EXTRN. La sentencia PUBLIC puede aparecer en cualquier posición del programa fuente, pero es buena práctica situar todas las declaraciones PUBLIC al comienzo del programa. Esta es la estructura típica de un procedimiento que quiere hacerse accesi- ble desde otros módulos: PUBLIC PROCI PROCI PROC FAR PUSH BP You ; comienzo procedimiento BP''P ; cuerpo del procedimiento MOV SP,BP POP BP RET PROC1 ENDP ; fin procedimiento En el módulo que quiere invocar al procedimiento PROCI hay que incluir la sentencia: EXTRN PROCI:FAR Ejemplo 2: Supongamos que queremos acceder a la variable TOTAL (de una palabra) en dos módulos diferentes. 147 En el módulo que contiene TOTAL deben incluirse las sentencias: PUBLIC TOTAL TOTAL DW O ; cero es el valor El módulo que usa TOTAL debe contener la sentencia: EXTRN TOTAL:WORD Ejemplo 3: ; TOTAL es externo al módulo y ; es de tipo palabra Se desea bifurcar a la instrucción de etiqueta ETIQ desde otro módulo y desde el mismo segmento físico. El módulo que contiene la etiqueta es: SEG-A SECMENT PUBLIC ETIQ ETIQ: ; comlenzo segmento ; define ETIQ accesible ; desde otros módulos ; etiquera NEAR (tiene :) :.: SEG A ENDS ; fin del segmento El módulo desde el que se quiere bifurcar a ETIQ es: EXTRN ETIQ:NEAR SEG-B SEGMENT JMP ETIQ ; comienzo segmento ; bifurca a ETIQ : SEG B ENDS Ejemplo 4: ; fin del segmento Se desea bifurcar a la instrucción de etiqueta ETIQ desde otro módulo y desde otro segmento físico. El módulo que contiene la etiqueta es: ErIQ 3:ln'.?Ii3*ffii'"oJ' SEC-A SEGMENT lY"''' 1¿t8 ; comienzo segmento : ETIQ ; etiqueta FAR (no tiene :) ... SEG A ENDS ; fin del segmento El módulo desde el que se quiere bifurcar a ETIe es: EXTRN ETIQ:FAR SEC-B S.EGMENT JMP ETIQ ; comienzo segmento ; bifurca a ETIQ .:: SEG B ENDS ; fin del segmento 149 PURGE Directiva: Formato: PURGE - Purgar macro. PURGE nombre-macro[,...] Descripción: Borra las macros especificadas de las tablas internas del ensamblador, permitiendo que se reutilice el espacio. Observaciones: Ejemplo: - No es necesario purgar una macro antes de redefinirla. INCLUDE MACRO.LIB ; incluir macros MACROI y MACRO2 .:: PURGE MACROI,MACRO2 ; purgar macros MACROI y MACRO2 : MACROI 15() ; esto sería un error, pues ya se ha : borrado MACROI .RADIX Directiva: .RADIX. Formato: .RADIX expresión Descripción: Sirve para cambiar la base de numeración por defecto. Por defecto, los números sin sufijo se cónsidera que están en base 10. Los sufijos son: b - binario d - decimal o/q - octal h - hexadecimal "expresión" está siempre en base 10, independientemente del valor de la base de numeración activa. .RADIX no afecta a DD, DQ o DT, pues siempre suponen decimal, a menos que se especifique un sufijo de tipo de datos. Si se especifica.RADIX 16, hay que tener cuidado con los números en hexadecimal terminados en D, pues el ensamblador los considera como valores decimales. Observaciones: - Ejemplos: .RADIX 16 ; base: 16 (hexadecimal) DB I I ; se interpreta como el valor llh : l7 DB llD ; se interpreta como el valor lld: l1 DB OIAD ; genera un error, pues A no es dígito decimal .RADIX 2 ; base:2 (binaria) DB I I ; se interpreta como el valor llb : 3 .RADIX l0 ; base: l0 (decimal) DB I I ; se interpreta como el valor I ld : I I 151 RECORD Directiva: RECORD - Registro. Formato: nombre-registro RECORD nombre-campo:longitud[ : e¡01,¡..., Descripción: Define una "plantilla" de campos a nivel de bits. Con RECORD no se reserva memoria, es sólo una definición de campos. Cada campo es definido mediante su nombre, su longitud (en bits) y un valor (opcional), que es su valor por defecto. Una vez definido, el nombre del registro se puede usar para reservar e inicializar memoria. Operandos: - "nombre-campo" es el nombre del campo dentro del registro. "longitud" es el número de bits del campo (de I a 16). Si es mayor que 8, el ensamblador usa 2 bytes. En caso contrario, se usa sólo un byte. Si el número total de bits es menor que 8 ó 16, los campos se ajustan a la derecha, es decir, al bit menos significativo del byte o de la palabra. "exp" (expresión) es opcional y corresponde al valor por defecto del campo. Observaciones: Para reservar memoria e inicializar los campos utilizando un registro se utiliza la sentencia siguiente: [nombre] nombre-registro([expl,[...]> o [nombre] nombre-registro expresión DUP(([exp])) "nombre" es opcional y es el nombre asignado al primer byte del área de memoria reservada. A continuación del nombre del registro se incluye, entre los paréntesis angulares (que siempre son obligatorios), las expresiones (opcionales) que son los valores iniciales de cada campo del registro o los valo- res que van a sustituir a los valores por defecto definidos en RECORD. - Ejemplo: La directiva RECORD es similar a la directiva STRUC. STRUC funciona a nivel byte y RECORD funciona a nivel bit. La reserva de memoria y la inicializaciín de un bloque STRUC es lo mismo que en RECORD. Definición del registro R (de l6 bits) con 4 campos: o Campo A de 7 bits. Valor por defecto, 5. o Campo B de 3 bits. Valor por defecto, l. 152 o Campo C de2 bits. Valor por defecto, ninguno. r Campo D de 4 bits. Valor por defecto, ninguno. R RECORD A:7 :5,B:3: l,C:2,D:4 Reserva de memoria e inicialización de la variable X, utilizando el regis- tro R: x R<6,,2> Se reservan 16 bits para X, inicializados con los valores siguientes: o Campo A : 00001l0b : 6 (valor de la lista). ¡ Campo B : 001b : I (valor por defecto). ¡ Campo C : o Campo D : lOb : 2 (valor de la lista). xxxxb : indeterminado. La variable X será, pues: 0000 1100 0ll0 xxxxb :0C 6Xh que se almacenará, como en toda palabra, con el byte menos significativo primero: 6X 0C. Ejemplos de utilización: MOVE AX,OFFSET X ; el desplazamiento (offset) de la variable ; debe recogerse sobre un registro que no ; sea de tipo segmento AND DX,MASK B ; considerar sólo el campo B equivalente ; a AND DX,00000001I1000000b MOV CL,B ; obtener el desplazamiento en bits del ;campo B ; equivalente a MOV CL,7 MOV CL,WIDTH B ; obtener el número de bits del campo B ; equivalente a MOV CL,3 REPT Directiva: REPT - Repetir. (REPesT). Formato: REPT expresión Descripción: Hace que el bloque de sentencias comprendidas entre REPT y ENDM se repitan el número de veces que indica "expresión". Observaciones: - Ejemplo l: Reservar cinco palabras inicializadas respectivamente con los cuaciracios de los cinco primeros números naturales. El bloque IRP-ENDM no es necesario que resida dentro de una definición MACRO. N :O REPT 5 ; comienzo bloque REPT ENDM ; fin bloque REPT :N+l N DW NxN El ensamblador generará: DWI DW4 DW9 DW 16 DW 25 Ejemplo 2: Macro para reservar N bytes con valores 1aN. ; comienzo macro ALOCAR MACRO N VALOR : 0 REPT N VALOR+l VALOR : DB VALOR ENDM ENDM Utilización: TABLA ALOCAR 4 181 ; comienzo bloque REPT ; fin bloque REPT ; fin macro La expansión de la macro será: TABLA DBI DB2 DB3 DB4 156 SEGMENT Directiva: SEGMENT - Segmento. SEGMENT [alineamiento] lcombinación] ['clase'] Formato: L:*0." nombre ENDS Descripción: Indica el comienzo del segmento "nombre". El final del segmento se indica mediante ENDS. El "nombre" de ambas directivas debe ser el mismo. Un segmento es un bloque de sentencias que puede contener: o Definición de variables. ¡ Instrucciones, es decir, código ejecutable. o Una combinación de los dos anteriores. Un módulo fuente ensamblador puede ser: . Parte de un segmento. o Un segmento. . Partes de varios segmentos. e Varios segmentos. o Una combinación de los anteriores. Existen cuatro tipos de segmentos: ¡ De datos (el direccionado por el segmento DS). r De código (el direccionado por el segmento CS). ¡ Extra (el direccionado por el segmento ES). o Pila (el direccionado por el segmento SS). Operandos: "alineamiento" - la memoria. (opcional) es el tipo de alineamiento'del segmento en BYTE : ninguno; es decir, el segmento puede empezaÍ en cualquier posición. WORD : el segmento empieza en una frontera de palabra; es decir, su dirección es múltiplo de 2. : PARA el segmento empieza en una frontera de párrafo; es decir, su dirección es múltiplo de 16. Es el alineamiento por defecto. PAGE : el segmento empieza en una frontera de página; es decir, su dirección es múltiplo de 256. 156 La dirección del segmento, según el alineamiento, es: Alineamiento Dirección BYIC YYYYYYYY YYYYYYYYb : XXXXh Palabra YYYYYYYY YYYYYYY0b Párrafo YYYYYYYY YYYY0000b: XXX0 h Página YYYYYYYY 00000000b:XX00h - "combinación" (opcional) puede ser: PUBLIC : el segmento se concatenará a otros del mismo nombre en la fase de montaje (link). El nombre del segmento que reconoce el montador (linker) es "clase". COMMON : indica que este segmento y todos los del mismo nombre ("clase") que procese el montador (linker) empezarán en la misma dirección, solapándose entre sí. La longitud asignada por el montador es la longitud máxima de todos los segmentos COMMON procesados. AT expresión : el segmento se ubicará en la dirección cuyo segmento es "expresión". Esta dirección no se usa para forzar la carga del segmento en una dirección fija. Lo que sí se permite es que se definan variables dentro del segmento. Normalmente se utiliza para referenciar zonas de memoria, como los vectores de interrupción o la memoria ROM. STACK: define este segmento como pila (stack). La pila es una zona de memoria que se utiliza para almacenar datos temporales. Se uti- liza en las instrucciones PUSH, POP, PUSHF, POPF, CALL, RET, INT e IRET. Al menos debe haber un segmento tipo pila para crear un módulo ejecutable con el montador (linker). MEMORY : el segmento se ubicará en una dirección de memoria superior a la de los otros que aparecen durante el montaje (link) del programa. Se puede aplicar, por ejemplo, para utilizar la memoria más allá de los límites del programa. Sólo puede haber un segmento de este tipo. Si existieran varios, sólo se procesará el primero como tal, y el resto se procesará como COMMON. "clase" es el nombre que se utiliza para agrupar segmentos en fase de montaje (linker). Se especifica entre comillas simples. Observagiones: Los operandos "alineamiento", "combinación" y "clase" se pasan al montador (linker). 157 - Pueden existir segmentos anidados, uno dentro de otro. En este caso, el ensamblador los procesa como si no lo fueran, juntando la primera parte del segmento partido con la segunda. se permiten segmentos que se solapen (excepto los de alineamiento - No coMMoN). Ejemplo 1: Ejemplo 2: Segmento alineado a párrafo: SEGI SEGMENT ; comienzo de segmento Sf.Cf ENDS ; fin de segmento Segmento pila: :1t" PILA Ejemplo 3: SEGMENT STACK ; comienzo de segmento ENDS ; fin de segmento Segmentos anidados. Segmento DATOS dentro de segmento CODIGO. CODICO SEGMENT comienzo de segmento CODICO DATOS SECMENT comienzo de segmento DATOS : OO'O' ENDS fin de sesmento DATOS CODIGO ENDS ; fin de segmento CODICO ::: Ejemplo 4: Agrupación de los segmentos lógicos SEGI y SEG2 en un solo segmento físico. Dichos segmentos pueden pertenecer al mismo o a diferente módulo. SEGMENT PUBLIC 'DATOS' ; comienzo de segmento :.u,ot SEGI :'_o' SEG2 158 ENDS ; fin de segmento SEGMENT PUBLIC'DATOS' ; comienzo de segmento ENDS ; fin de segmento Ejemplo 5: Segmento correspondiente a la memoria de pantalla gráfica. La memode la pantalla gráfica comienza en la dirección B800h:0h = ,:J!ffi{! PANTALLA SEGMENT AT B800h : comienzo de sesmento iiNraI-lA ENDS Ejemplo 6: ; fin de segmenro Segmento correspondiente a los vectores de interrupción del BIOS. La dirección es igual a 0. INTERRPS SEGMENT AT 0 ; comienzo de segmento INTERRPS ENDS : fin de sesmento 159 STRUC Directiva: Formato: STRUC - Estructura (STRUCture). :.:-Or. estructura STRUC [nombre-variable] directiva-definición-datos expresión :: nombre-estructura ENDS Descripción: Define una plantilla de campos a nivel de bytes. Las directivas estándar de definición de datos son: . DB (definir byte). . DW (definir palabra). . DD (definir doble palabra). . DQ (definir cuádruple palabra). . DT (definir diez bytes). Mediante la directiva STRUC es posible establecer una nueva definición de datos basada en estas directivas originales o primitivas. Esta nueva definición de posiciones de memoria se llama una estructura. La definición en la estructura comienza con STRUC v acaba con ENDS. El nombre de la estructura debe ser el mismo en ambas sentencias. Entre ambas sentencias se incluyen sentencias de definición de datos, que definen la estructura. Una vez definida la estructura, su nombre se puede usar para reservar e inicializar memoria. Operandos: "nombre_variable" (opcional) es el nombre de cada campo de la es- tructura. - "directiva-definición-datos" es DB, DW, DD, DQ o DT. "expresión" es la parte correspondiente a la inicialización de cada - campo (simple o múltiple) definido. Si el campo está inicializado, el valor especificado es el valor por defecto de ese campo. Observaciones: - Para reservar memoria e inicializar los campos utilizando una estructura se utiliza la sentencia sisuiente: [nombre] nombre-estructura([expl,[...]> o [nombre] nombre-estructura expresión DUP(([exp] >) 160 "nombre" es opcional y es el nombre asignado al primer byte del área de memoria reservada. A continuación del nombre de la estructura se incluye, entre los parén- tesis angulares (que siempre son obligatorios), las expresiones (opcionales) que son los valores iniciales de cada campo de la estructura o los val<¡res que van a sustituir a los valores por defecto definidos en el bloque STRUC. Los carnpos pueden ser mociificables o no modificables. o Un campo simple es modificable. o IJn campo múltiple no es modificable. La refereneia a los campos se hace mediante: variable.campo La directiva S'IRI.JC es similar a la directiva RECORD' STRUC funciona a nivel byte y RECORD f.unciona a nivel bit. La reserva de memoria y la inicialización de un bloque STRUC es lo mismo que en RECORD, Bjemplo 1: Definición de la estructura S: S STRUC CAMPOI DB 1,2 ; comienzo estructura ; no modificable (campo múltiple) i0 DLIP(?) CAMPO2 DB ; no modificable (campo múltiple) DW 5 CAMPO3 ; sí modificable (campo simple) CAMPO4 DB 'ABC' ; sí modificable (campo simple) S hINDS ; fin estructura l.as carac¡eristicas de esta esfrlrclura son: r f,lonsta de cuatro campos (dos simples y dos múltiples). ¡ Su inngitud es de 2,+ l0 + 2 + 3: 17 bytes" ¡ L,q:s campos i, ii y 4 iienen lin valor por defecto' ¡ Fl campo 2 no riene ningún valor por defecto. Reserva rje mernoria e inici;¡lizaciÓ¡ rle la variable X, utilizando la estruc- tura S: x s<,,7,'xYZ'> Se reservan l7 bytes para X, inicializados con los valores especificados en la estn¡ct¡rra S, y sustifuyendo C.AMFO3 con el valor 7 y CAMPO4 con el valor r''YY'¿" . Ejemplo de utilización: MOV AX,[BX].CAMPO3 Esta instrucción es equivalente a MOV AX,IBX + l2l. El valor 12 corresponde al desplazamiento de CAMPO3 con respecto al comienzo de la estructura. Obsérvese que no se especifica el nombre de la estructura, sólo el nombre del campo. Otro ejemplo de utilización es: MOV AX,X.CAMPO3 Esta instrucción es equivalente a MOV AX,X + 12. Ejemplo 2: Un uso típico de STRUC es para definir parámetros de un procedimiento. PARAMS STRUC P2 PI comienzo estructura BP salvado dirección de retorno parámetro 2 parámetro I fin estructura DW? DD? DD? DD? PARAMS ENDS Las características de esta estructura son: o Consta de cuatro campos simples. ¡ Su longitud es de 2 + 3 x 4: 14 bytes. o Los campos no tienen un valor por defecto. Ejemplo de utilización: ; ES : segmento, SI : desplazamieirto LES SI,[BP].Pl Esta instrucción es equivalente a LES SI,IBP + 10]. Ejemplo 3: Definición estructura: VECTOR STRUC DB DW DW VECTOR ENDS ? ? ,| : comienzo estructura ; código (A o B) ; coordenada X : coordenada Y : fin estructura Reserva de memoria e inicialización: LISTA VECTOR<'A"0,0>,<',8"21,0>,<'B"0, 1 1> 162 SUBTTL Directiva: SUBTTL - Subtítulo (SUBTiTLe). Formato: SUBTTL texto Descripción: Especifica un subtítulo, que aparecerá en el listado como segunda línea de cada página, detrás del título (véase sentencia TITLE). La longitud máxima de "texto" es de 60 caracteres. Observaciones: Se puede especificar cualquier número de sentencias SUBTTL por mó- dulo. Si no se utiliza ninguna sentencia SUBTTL, la segunda línea del lista- do aparecerá en blanco. Si después de usar "SUBTTL texto", se desea que vuelva a salir en - blanco, hay que incluir la sentencia SUBTTL sin "texto" (en blanco). Ejemplo: SUBTTL CALCULO DE ESFUERZOS lGf TITLE Directiva: TITLE - Título. Formato: TITLE texto Descripción: Especifica un titulo, que aparecerá en el iistadc coniü prir,rera iinea en cada página" Con esta directiva se consigue que todas las páginas de un listadc¡ de un módulo tengan la misma identificación. La longitud máxima de "textoo' es de 60 earacteres. Observaciones: - No puede especificarse rnás que una sentencia TIT{-E por módulo. Los seis primeros caractere-c de "texto" se utilizan como nombre de módulo objetc, a menos qlle se liaya incluid* la directiva NAME. Si no se ha utilizadc ni TíTLE ni NAME, el nombre de módulo objeto es del rnóduio fuenie. Po'r ejempio, si ei módulo fuente es MODULO.ASM, el móduio objetc; se liamará MODUI-O.OE.í. Ejemplo: TiTLE ESTRUCTURAS DF i{OR.MIúCi\i El nonrbre del mód¡¡lo objet"r generado será FSTRUC.CBJ. 164 11 lnstrucciones Abreviaturas y símbolos utilizados Tipos de operandos acum : acumulador de 8ó 16 bits (AX, AL). acumS : acumulador de 8 acuml6: acumulador de l6 bits (AL). birs (AX). desp : desplazamiento mem : variable de memoria de 8 ó 16 bits. memS : variable de memoria de 8 bits. meml6 : variable de memoria de 16 bits. mem32 : variable de memoria de 32 bits. reg : registro de 8ó 16 bits. regS : registro de 8 bits. reg16 : registro de t6 bits. 165 I : registro de segmento (CS, SS, DS, ES). val : valor inmediato de 8 ó 16 bits. val8 : valor inmediato de 8 bits. val16 : valor inmediato de 16 bits. Codificación d : un bit que indica el destino (véase "codificación de instrucciones"). mod : dos bits que indican el tipo de desplazamiento (véase "codificación de instrucciones"). r/m : tres bits que indican el tipo de direccionamiento (véase "codificación de instrucciones"). reg : dos o tres bits que indican el tipo de registro (véase "codificación de instrucciones"). v : bit que indica el contador. 0, contador: l. I, contador en CL. w : bit que indica la longitud de los operandos. 0, b¡e. 1, palabra. Ejemplos MEM-BYTE : variable de memoria tipo byte. MEM-PAL : variable de memoria tipo palabra. MEM-DPAL: variable de memoria tipo doble palabra. Registros AX : registro acumulador (16 bits). (16 bits). BX : registro base CX : registro contador (16 bits). DX: registro de datos (16 bits). AH : parte superior de AX (8 bits). BH : parte superior de BX (8 bits). CH : parte superior de CX (8 bits). DH : parte superior de DX (8 bits). 166 AL : parte inferior de AX (8 bits). BL : parte inferior de BX (8 bits). CL : parte inferior de CX (8 bits). DL : parte inferior de DX (8 bits). SP = puntero de la pila (stack pointer). puntero BP (base pointer). : SI DI base : índice fuente (source index). : índice destino (destination index). : registro de segmento de código (code segment register). DS : registro de segmento de datos (data segment register). SS : registro de segmento de pila (stack segment register). ES : registro de segmento extra (extra segment register). CS Banderas OF : bandera de desbordamiento (overflow ftas) DF : bandera de dirección (direction flas) IF : bandera de activar interrupciones (interrupt enable flag) TF : bandera de atrape (trop flqs) SF : bandera de signo (sign flas) ZF : bandera de cero AF : bandera auxiliar PF : bandera de paridad CF : bandera de acarreo (zero (auxiliar (parity (carry "flag) flae) flos) flsg) x : bandera afectada ? : bandera indefinida : bandera no afectada 167 AAA Instrucción: AAA - Ajuste ASCII en suma (Ascii Adjust for Addition). Formato: AAA Descripción: Corrige el resultado en AL de una suma de dos números decimales desempaquetados, convirtiéndolo en un valor decimal desempaquetado. Lógica: sibits3a0deAL>9óAF=1 AL:AL +6 AH:AH+l AF:l CF:AF bitsTa4deAL:0000b Banderas: OF, DF, IF, TF, SF, ZF, AF, PF, CF ? 't 'l x?x AL :08h BL :06h AH :00h ADD AL,BL AL :OEh BL :06h AF :0 AAA AX:0104h BL :06h AF:I AL :08h BL :09h AH:00h ADD AL,BL AL : llh BL :09h AF :1 AAA AX:0107h AF : I CF: I Ejemplo l: Ejemplo 2: CF:I BL :09h Tipos de operandos, codificación y ejemplos: Operandos 168 Codificación Ejemplo 001 101 I I AAA AAD Instrucción: AAD - Aiuste ASCII en división (Ascii Adjust for Division). Formato: AAD Descripción: Realiza un ajuste del dividendo en AL antes de hacer la división de dos números decimales desempaquetados, para que el resultado de esta división (cociente) sea un valor decimal desempaquetado. Lógica: AL : AH x l0 + AL AH :0 Banderas: OF, DF, IF, TF, SF, ZF, AF, PF, CF ?-xx?x? ; AX : 0103h :259 Ejemplo: ; BL:04h -4 AAD : AX :000Dh i eL : oztr DIV BL ; AH :03h (resto) ; AL :40h (cociente) : BL :02h Tipos de operandos, codificaciírn ¡ eiemplos: Operandos Codificación Ejemplo il0l0l0l | 00001010 AAn 169 AAM Instrucción: AA"M - Ajuste ASCII en multiplicación (Ascii Adjust for Multiply). Formato: AAM Descripción: corrige el resultado en AX del producto de dos números decimales desempaquetados, convirtiéndolo en un valor decimal desempaquetado. Lógica: AH: cociente de ALl10 AL : resto de AL/10 Banderas: OF, DF, IF, TF, SF, ZF, AF, PF, CF Ejemplo: ?-xx?x? ; AL :09h :9 ; BL : 07h:7 : ----------------MUL BL I AX:003Fh :63 ; BL :07h AAM ; AX:0603h ; BL :07h Tipos de operandos, codificación y ejemplos: Operondos Codi"ficación Ejemplo 11010100 | 00001010 AAM 170 AAS Instrucción: AAS - Ajuste ASCII en resta (Ascii Adjust for Subtraction). Formato: AAS Descripción: Corrige el resultado en AL de la resta de dos números decimales desempaquetaáos, convirtiéndolo en un valor decimal desempaquetado. Lógica: si bits 3 a0de AL>.9ó AF AL:AL -6 AH:AH -l AF:l : I CF:AF bitsTa4deAL:0000b Banderas: OF, DF, IF, TF, SF, ZF, AF, PF, CF Ejemplo 1: ; AL :08h ; BL :06h ?-??x?x : ------------SUB AL,BL ; AL :02h ; BL :06h AAS Ejemplo 2: AH:00h AF :0 ; AX :0002h AF :0 ; BL :06h : AH:08h AH:01h iBr-= oqh : ------------SUB AL,BL ; AL : FFh AF : ; BL :09h AAS 1 : AX :0009h AF : I CF: : BL :09h 1 Tipos de operandos, codificación y ejemplos: Operondos Codificáción Ejemplo 00l1lill AAS ADC Instrucción: ADC - Sumar con acarreo (ADd with Carry). Formato: ADC destino,fuente Descripción: Suma los dos operandos. Suma uno si está activada la bandera de acarreo (CF). El resultado se almacena en el operando destino. Los operandos deben ser del mismo tipo (byte o palabra). Lógica: destino : destino + fuente si CF: I destino:destino+1 Banderas: Ejemplo l: OF, DF, IF, TF, SF, ZF, AF, PF, CF X-XXXXX AL: FEh: llll lllOb BL : l2h :0001 0010b lOh = 0001 0000b lb CF 0001 0001b ADC Ejemplo 2: AL,BL ; AL: 1lh . BL:l2h suma de r,.r¡rleros de 32 bits fuente en DX,CX (palabras superior e inferior) destino en BX,AX (palabras superior e inferior) ADD AX,CX ; sumar palabras inferiores ADC BX,DX ; sumar palabras superiores con acarreo Tipos de operandos, codificación y ejemplos: Destino Fuente Codificación reg 172 reg 000100dw I mod regr/m Ejemplos ADC BL,CL ADC BX,CX ADC BL,MEM-tsYTE reg !:lefq mFm i Pu acum val 000101üw j vai ADC AL,12h ADC AX,I234h reg val 100000sw I rnod0ll r/m I val ADC BL,12h ADC BX,I234h mem val ADC-BX,MEM-FAL ADC MEM-BYTE,BL ADC MEM-_PAL,BX ADC MEM-BYTE,I2h ADC MEM-PAL,IZ34h 173 ADD Instrucción: ADD - Sumar (ADDition). Formato: ADD destino,fuente Descripción: Suma los dos operandos. El resultado se almacena en el operando destino. Los operandos deben ser del mismo tipo (byte o palabra). Lógica: destino : destino + fuente Banderas: OF, DF, IF, TF, SF, ZF, AF, pF, CF xxxxxx Ejemplo: ; AL:FEh:llll lll0b ; BL : l2h :0001 0010b ; ------------ ; lOh :0001 0000b ADD AL,BL ; AL : lOh ; BL:l2h Tipos de operando-s, codificación y ejemplos: 174 Destino Fuente Codificación Ejemplos reg reg ADD BL,CL ADD BX,CX reg mem ADD BL,MEM-BYTE ADD BX,MEM-PAL mem reg ADD MEM-BYTE,BL ADD MEM-PAL.BX acum val 0000010w I val ADD AL.12h ADD A)(,I234í reg val 100000sw I mod 000 r/m I val ADD BL,l2h ADD BX,I234í mem val 000000dw I mod regr/m ADD MEM-BYTE.I2b ADD MEM-PAL.IZ346 AND Instrucción: AND - Y lógico (logical AND). Formato: AND destino,fuente Descripción: Operación "y lógica" a nivel de bit entre los dos operandos. El resultado se almacena en destino. La tabla de la operación AND (para las cuatro combinacioñes posibles de bits) es: 00-0 Lógica: 0l-0 l0-0 I l-l destino : destino "y lógico" fuente CF:0 oF:0 Banderas: Ejemplo: OF, DF, IF, TF, SF, ZF, AF, PF, CF 0-xx?x 0 ; AX: FEDCh : 1111 1110 1101 1100b ; BX : 123 4h :0001 0010 0011 0100b l2l4h : 0001 0010 0001 0100b ; AND AX,BX ; AX: l2l4h ; BX = 1234h Tipos de operandos, codificación y ejemplos: Destino Fuente Codfficación reg reg reg mem 001000dw I mod regr/m Ejemplos AND BL,CL AND BX,CX AND BL,MEM-BYTE AND BX,MEM-PAL 175 176 InCII TCg acum val 0010010w I val AND AL.0lh AND AX.OIO2h reg val 1000000w I mod 100 r/m I val AND BL,30 AND BX,3O mem val AND MEM-BYTE,BL AND MEM-PAL.BX AND MEM_BYTE,OIh AND MEM-PAL.OIO2h CALL Instrucción: CALL - Llamar a un procedimiento (CALL a procedure). tr'ormato: CALL destino Descripción: Bifurca a un procedimiento fuera de linea, salvando previamente en la pila la dirección de la instrucción siguiente, para poder volver a esta instrucción una vez ejecutado el procedimiento. El procedimiento llamado puede estar: - Dentro del mismo segmento (llamada NEAR). En este caso, se almacena en la pila el desplazamiento de la instrucción siguiente. - En otro segmento (llamada F'AR). En este caso, se almacena en la pila primero el segmento y segundo el desplazamiento de la instrucción siguiente, en este orden. La llamada puede ser, a su vez: ._ Directa, es decir, a etiquetas relativas a CS, no a variables. Se supone siempre NEAR, a menos que se especifique FAR en la. declaración de destino. - Indirecta, es decir, a variables, pudiendo especificarse WORD PTI{ o DWORD PTR para llamadas NEAR o FAR, respectivamente. Si se especifica una variable tipo WORD, el contenido de esa palabra es la nueva dirección (desplazamiento)" Si se especifica una dirección tipo DWORD, la primera palabra contiene el desplazamiento y la segunda el segmento. También se pueden usar registr<ls de l6 tlts entre corchetes. Para retr:rn;rr elc un procedimientr: se utiliza la inslrueción Rll-l-. Lógica: sl dlshnl() segrnento 5Ir:5P-'2 ( ,i. ., pil;¡ (.'!i :- r¡¡¡gf¡lgnto rft' destlno 5P : Sl' -') ¡p -* prla lP : tlesplaz,arruento de destino lTT Banderas: T, T, tU, T, T, t:, lU, T, T Ejemplos: CALL PROCl ; llamada directa al procedimiento PROCI CALL WORD PTR MEM-DPAL ; llamada NEAR indirecta CALL WORD PTR [BX] CALL DWORD PTR MEM-DPAL ; llamada FAR indirecta CALL DWORD PTR [BX] Tipos de operandos, codificación y ejemplos: Segmerito Llamoda Codificación Ejemplos mismo directa I 1101000 | desp CALL PROCI mismo indirecta llllllll I mod 010 r,/m CALL WORD PTR MEM-PAL distinto directa l00ll0l0 ldesp I r"g CALLPROC1 distinto indirecta llllllll I mod 011 r/m CALI- DWORD PTR MEM-DPAL 178 CBW Instrucción: CBW - Convertir byte en palabra (Convert Byte to Word). Formato: CBW Descripción: Copia el bit.7 del registro AL en todos los bits del registro AH; es decir, expande el bit de signo de AL. Lógica: si AL ( 80h AH :00h en caso contrario AH : FFh Banderas: T, T, tu, T, T, t:, T, T, g Ejemplos: ; AL:CZh CBW i AX: FFC2h : AL :5lh CBW : AX:0051h Tipos de operandos, codificación y ejemplos: Operandos Codificación Ejemplo 10011000 cBw 179 cLc lnstrucción: CLC - Borr¿ir bar:dera de acarreo {CLear Carry fla$. Forrnato: CLC Oescripción: Borra ia bandera de acarreo (CF) sin afectar ;:. *inguna r¡tra bandera. Lógica: CF: Ci Banderas: OF, DF, IF, TF, SF, ZF, AF, PF, CF 0 Ejemplo: CLC ; L-F:0 Tipos de operandos, codificación y ejemplos: Operandos Codificación Ejemplo 1 11 f80 11000 cLC CLD Instrucción: CLD - Borrar bandera de dirección (CLear Direction flqd" Formato: CLD Descripción: Pone a 0la bandera de dirección {DF), por lo que en ia eiecucion de ias instrucciones de manejo de cadenas los registros lneiices 5I :f ,'¡: DI se autoincrementan de modo automático: o en I si el(los) operando(s) son de tipo byte; o en 2 si el(los) operando(s) son de tipo palabra. Lógica: DF':0 Banderas: OF, DF, IF, TF, SF, ZF, AF, PF, CF Ejemplo: CLD ; incrementar indices en instrucciones de manejo de cadenas n_ Tipos de operandos, codificación y ejemplos: Operandos Codificación Ejemplo llllll00 cLD 181 cLl Instrucción: CLI - Borrar bandera de interrupciones, desactivar (CLear Interrupt flag, disable). l'ormato: CLI Descripción: Borra la bandera de activación de interrupciones (IF) y desactiva las interrupciones enmascarables (las que aparecen sobre la línea INTR del procesador). Las interrupciones enmascarables se pueden activar (permitir) o desactivar (no permitir). Las interrupciones no enmascarables (las que aparecen sobre la línea NMI) no se pueden desactivar. Lógica: lF :0 Banderas: T, T, á., T,.T, t:, T, T, T Ejemplo: CLI ; desactivar interrupciones enmascarables Tipos de operandos, codificacién y ejemplos: Operandos Codificación Ejemplo lllll0l0 cLI 1U. cMc Instrucción: CMC - Complementar bandera de acarreo (CoMplement Carcy .flsd. Formato: CMC Descripción: Complementa la bandera de acarreo (CF); es decir, la pone en el estado contrario. Lógica: si CF:0 CF: I en caso contrario CF: I Banderas: g' T, tr' T' T' ?,T' T' :' Bjemplo: CMC ; complementar CF Tipos de operandos, codificación y ejemplos: Operandos Codificación Ejemplo llll0l0t cMc ltxl CMP Instrucción: CMP - Comparar dos operandos (CoMPsre two operands). Formato: CMP destino,fuente Descripción: Resta fuente de destino, pero no retorna el resultado. Los operandos quedan inalterados, pero las banderas se actualizan, pudiéndose consultar a continuación mediante una instrucción de bifurcación con- dicionai. Los operandos pueden ser tipo byte o palabra, pero ambos del mismo tipo. Lógica: destino - fuente Banderas: OF, DF, IF, TF, SF, ZF, AF, PF, CF x-xxxxx Ejemplo: CMP AX,BX JL ; comparar AX con BX MENOR : bifurcar a MENOR si AX < BX Tipos de operandos, codificación y ejemplos: Destino Fuente Codificsción Ejemplos reg reg CMP BL,CL CMP BX,CX reg mem CMP BL,MEM-BYTE CMP BX,MEM-PAL menr reg CMP MEM-BYTE,BL CMP MEM-PAL.BX acum vai 001 I I lOw rr¡r. val 100000sw I mod lll r/m I val nr{itlt val iistl 00lll0dw I mod regr/m I val CMP AL.OIh CMP AX,OIO2h CMP 8L,30 CMP BX,3O CMP MEM-BYTE,OIh CMP MEM-PAL.OIO2h CMPS ICMPSB/CMPSW Instrucción: CMPS - Comparar cadena (CoMPare String). CMPSB - Comparar cadena de bytes (CoMPare Byte String). CMPSW - Comparar cadena de palabras (CoMPore LVord String). Formato: CMPS cadena destino.cadena-fuente o CMPSB o CMPSW Descripción: Sirve para comparar dos operandos de rnemoria (tip<i byte o paiabra). Para ello realiza la operación cadena--fuente - cadena-destino afectando a las banderas, pero sin almacenar el resultado. La cadena fuente está direccionada por SI en el segmento de datos, es efecir, DS:ISI]. La cadena destino está direccionada por DI en el segmento extra, es declr, ES:[DI]. Por tanto, se realiza la operación DS:[SI] - ES:[DI]. Los registros SI y DI se actualizan para que apunten al siguienle elemento de la cadena: o Si el atributo de los operandos es BYTE, ia resta es a nlvei byte y los registros SI y DI cambian una unidad. o Si el atributo de los operandos es WORD, la resta es a nivel paiabra y los registros SI y DI cambian dos unidades. Si la bandera de dirección es cero {DF:0), ambos SL i'Dl se incrementan. Si DF: 1, ambos se decrementan (véase las instrucciones CLD y STD). En la instrucción CMPSB, se realiza la resta entre bytes: DS:[SI] - ES:[DI]. En ia instrucción CMPSW. se realiza la resta entre palabras: DS:[SI] - ES:[DIl. 't85 Los operandos especificados en cMPS los utiliza el ensamblador únicamente para verificar el tipo (byte o palabra) y ver si se ha especificado un registro de segmento. CMPS realiza la operación DS:[SI] - ES:tDIl sin usar realmente los operandos de la instrucción. cuando se usa con REPE (REPZ) o REPNE (REPNZ), puede hacerse la comparación entre dos cadenas completas (de bytes o de palabras), siendo el número de elementos a comparar el especificado en el registro CX. Fn cMPS se puede ¡easignar el elemento fuente, pero no el de destino; es decir, se puede especificar, por ejemplo CMPS DESTINO.ES:FUENTE En este caso, habría una comparación entre elementos del segmento direccionado por ES. Para comparar elementos dentro del segmento direccionado por DS, habría que hacer ES : DS. Hay que observar que la operación fuente - destino es justamente la contraria que en CMP, que es destino - fuente. Esto hay que tenerlo en cuenta en la instrucción de bifurcación condicional posterior. Lógica: cadena destino-cadena_fuente delta : TYPE de cadena_fuente (l 6 2) si DF:0 SI:SI +delta DI:DI+delta en caso contrario SI: SI-delta DI: DI - delta Banderas: OF, DF, IF, TF, SF, ZF, AF, PF, CF X-XXXXX Ejemplo 1: LEA SI,FUENTE LEA DI,DESTINO CMPS [Dr],[Srl JL PEPE ; SI : desplazamiento de FUENTE ; DI: desplazamiento de DESTINO ; comparar FUENTE con DESTINO ; bifurca si FUENTE < DESTINO La penúltima instrucción puede sustituirse por CMPS DESTINO,FUENTE ;comparar FUENTE con DESTINO Ejemplo 2: 186 ; comparar 100 bytes o palabras de FUENTE, en el segmento de datos, con ; DESTINO en el segmento extra CLD LEA SI,FUENTE LEA DI,DESTINO MOV CX,IOO REPE CMPS [Dr],[Sr] JE IGUAL ; DF :0 (incrementar SI y DI) ; SI : desplazamiento de FUENTE ; DI : desplazamiento de DESTINO ; CX: 100 (número de elementos) ; comparar los elementos ; bifurca si FUENTE es igual a DESTINO Si los elementos son tipo byte, la penúltima instrucción se puede sustituir por: ; comparar los elementos tiPo bYte REPE CMPSB Si los elementos son tipo palabra, la penúltima instrucción se puede sustituir por: ; comparar los elementos tipo palabra REPE CMPSW Ejemplo 3: ; comparar 100 bytes o palabras de FUENTE, en el segmento de datos, con ; DESTINO, también en el segmento de datos ; DF :0 (incrementar SI y DI) : ES: DS CLD PUSH DS POP ES LEA SI.FUENTE LEA DI,DESTINO MOV CX,IOO REPE CMPS [Dr],[SI] JE IGUAL ; SI : desplazamiento de FUENTE ; DI : desplazamiento de DESTINO ; CX: 100 (número de elementos) ; comparar los elementos ; bifurca si FUENTE es igual a DESTINO Tipos de operandos, codificación y ejemplos: Cadena-destino CadenoJuente mem mem Codificación Ejemplos l0l00l lw CMPS DEST-BYTE,FUEN-BYTE CMPSB CMPS DEST-PAL.FUEN-PAL CMPSW 1gI CWD Instruceñom: CWl, - Convertir paiabra en doble palabra (Convert Word to Doublewordi. S'ormato: CWI, l¡escripciónr Expan'le ei bit" de signo del registro AX (bit l5) sobre el registro DX. Lógica: s; AX < 8000h IJX .= 0000h e;1 caso üor'tlf&nr: D};: F'FFFi: Banderas: OF, I)F, I*-, TFt, SF, ZF, AF, PF, CF bjempios: , /rfi =- C200h {lWil , I)}"'. FFFFh : ¡rri., =.5100h CWL ,: [)){:0{}00h Tif¡r¡s de: operandosn rndifícación 3, ejemplos: ()¡sera"nrla:; {}odificaciórt Ejempict lrl0l1001 188 CWD DAA fnstrucción: DAA - Aiuste decirnai en surna (iiecimai Ar),,iust far Additionj. Formato: üAA Descripción: Cornge r:'i resi;¡tadc' *r Al, de ia suma o¡: dúi: núr:teros decirnales emp:a quet.acios. convlrtiéndoio en un r,alor decrrnai ernpaque¿acio,. {,égica: s: bír 3 a f¡ d* A;,. > i¡ i; AFi: i A).-4.-*á Al ==i siAL>9FhóCF=.Í A{ ' ='AL' -r- 60h arl -r = " Banderas: OF, Dff, Il-', TF', SFj, Zb', A.F, PF, Ci' "i -*v.v.xx:r Aj-. -,68h B[. -, iTtr Ejempl<i 1: AH : [úh TFir AF : ú AL}T) Ai,,Bi .Jri-, -- DAA A: ' E5l. ;\f" Bi, .. l7h '. fií. = i7i¡ AL =.61h AF{:0{i'. Bi, : 57h Ejemplo 2: ADD Ai,,F[, AL : B8h AF :0 BL =. "571¡ DAA Ai:l8h CF=. j iBi. -, 57i¡ Tipos de operandos, codificaeión y ejemplos: Operandos {-odificacién Ejemplct 00t0011i üÁ1r t8s DAS lnstrucción: DAS - Ajuste decimal en resta (Decimal Adjust for Subtroction). Formato: DAS Descripción: Corrige el resultado en AL de la resta de dos números decimales empaquetados, convirtiéndolo en un valor decimal empaquetado. Lógica: sibits3a0deAL>9óAF:l AL : AL-6 AF: I siAL>9FhóCF:l AL: AL-60h CF: I Banderas: T' o--t' tu' T' :u' 7'' f;t' :t' :u Ejemplo l: AL :68h BL : l9h AH:00h SUB AL,BL AL :4Fh BL : I9h AF :0 DAS AL :49h BL : I9h AF:l AL :57h , BL :68h AH:00h Ejemplo 2: , SUB AL,BL AL : EFh ' BL :68h AF:O AL:89h CF: I DAS BL :68h Tipos de operandos, codificación y ejemplos: Operandos Codificación Ejemplo 00010111 DAS 190 DEC lnstrucción: DEC - Decrementar destino en uno (DECrement destinotion by one). Formato: DEC destino Descripción: Resta una unidad del operando destino. El operando puede ser byte o pa- labra. Lógica: Banderas: destino : destino- I OF, DF, IF, TF, SF, ZF, AF, PF, CF X-XXXX Ejemplo: ; AX:0123h DEC AX ; AX: AX-l :0122h Tipos de operandos, codificación y ejemplos: Destino Codificación Ejemplos regl6 01001 reg DEC AX regS 1llllllw I mod 001 r/m DEC AL DEC MEM-BYTE DEC MEM-PAL mem DIV DIV -Dividir, sin signo (DIVision, unsigned). Formato: DIV fuente Descripción: Divrde, sin considerar el signoo un número contenido en el acumulador y su extensión (AH,AL si el operando es de tipo bWe o DX,AX si el operando es de tipo palabra) entre el operando t'uente. El cociente se almacena en el acumulador (AL o AX, según que el operando fuente sea de tipo byte o palabra). El resto se aimacena en la extensión del acumulador (AH o DX, según que el operando fuente sea de tipo byte o paiabra). Si el cociente es mayor que el valor máximo que puede almacenarse (FFh o FFFFh), entonces el cociente y el resto quedan indefinidos, generándose una interrupción tipo cero. Si la mitad superior del resultado (AH para el caso de operando tipo byte o DX para el caso de operando tipo palabra) no es cero, se activan las banderas CF y OF, indicando que esta mitad superi¡;r contiene dígitos significativos del resultado. Lógica: si tipo fiiente .=. byte AX/fuente (división sin signo) AL : eociente {fl ,,.. ¡gg¡q si cociente > FFh INT Ü si ripo f'r¡ente : palabra DX,dXiJ'uente (división sin signo) (üX * palabra superior) (AX * palabra inferior) AX: cociente DX : nesto si eociente > FFFFh tlJT $ cF, DF, iF, TF, SF, ZF, AF-, PF, CF ,I ?-* bjemplo l: 9tj'l i AX.= 0013h ,= t9 (dividendo) 2 {divisor} DIV BL AX :0109h (resultado) AH:Olh : I (resto) AL :09h :9 (cociente) BL : l2h Ejemplo 2: DX,AX:0000 0013h : 19 (dividendo) DX:0000h AX:0013h BX :0002h (divisor) DIV BL DX,AX :0001 0009h (resultado) DX:0001h:l(resto) AX :0009h :9 (cociente) BL : I2h Tipos de operandos, codificación y ejemplos: Fuente Codificación reg I I I l0l lw I mod 110 r/m mem Ejemplos DIC BL DIV BX DIV MEM-BYTE DIV MEM-PAL 198 ESC Instrucción: ESC - Escape (ESCape). Formato: ESC código-de-operación-externo,fuente Descripción: Esta instrucción suministra un mecanismo de comunicación con otros coprocesadores. El procesador 8088/8086 está diseñado para operar con una variedad de coprocesadores que ejecutan diferentes funciones. Por ejemplo, el 8087 (coprocesador matemático) y el 8089 (coprocesador de entrada/salida). ESC se usa para indicar a un coprocesador que comience arealizar alguna tarea. A su vez, el 8088/8086 continúa ejecutando la instrucción siguiente. Es decir, que, a menos que se le indique otra cosa, habría dos procesadores trabajando alavez. Es por esto que ESC se usa en combinación con WAIT. La instrucción WAIT sirve justamente para parar el 8088/8086 y hace que espere hasta que el coprocesador acabe con la instrucción en curso. Normalmente, WAIT se sitúa delante de ESC, para asegurarse de que el código de opeación es recogido por el coprocesador. El primer operando es un valor inmediato de 6 bits (0 a 63 - 3Fh) y sirve para denotar , alavez, al coprocesador y la operación a ejecutar. El segundo operando es tipo registro o memoria y especifica el dato a pasar al coprocesador. Si el segundo operando es un registro, el procesador no hace nada. Si el segundo operando es una dirección de memoria, el procesador envía el contenido apuntado por esa dirección al bus de datos, lo ignora, pero otro procesador externo puede capturarlo. Este dato de la memoria es capturado por el BIU (Bus Interfoce Unit), que es un componente del 8088/8086. Lógica: si fuente es un registro ninguna operación si fuente es una dirección de memoria bus de datos contenido de fuente : Banderas: g'T,tu' T' T' t:'T'T' g Ejemplo: WAIT 194 ; esperar a que el coprocesador acabe con la operación ; en curso ESC 2I,TABLA ; bus de datos: contenido de TABLA (pasar ; información a coprocesador) Tipos de operandos, codificación y ejemplos: Código Fuente Codificación val reg llOllxxx I mod yyy r/m Ejemplos val ESC 2I,MEM-BYTE mem ESC 2l,AL ESC 2I,AX El código de operación (6 bits) se divide en dos campos de 3 bits (xxx, yyy). 195 HLT Instrucción: HLT - Alto (HaLT). Formato: HLT Descripción: El procesador se para. Sólo abandona ese estado en uno de'estos casos: . Se restaura el sistema (activación de la línea RESET). o Se recibe una interrupción no enmascarable sobre la linea NML o Se recibe una interrupción enmascarable sobre la línea INTR (si las interrupciones están permitidas). Banderas: g, Ejemplo: T, t", T, T, t:, T, T, g HLT ; para el procesador Tipos de operandos, codificación y ejemplos: Operondos Codificación Ejemplo I 196 1110100 HLT IDIV Instrucción: IDIV - Dividir, con signo (Integer DIVision, signed). Formato: IDIV fuente Descripción: Divide, considerando el signo, un número contenido en el acumulador y su extensión (AH,AL si el operando es de tipo byte o DX,AX si el operando es de tipo palabra) entre el operando fuente. El cociente se almacena en el acumulador (AL o AX, según que el operando fuente sea de tipo byte o palabra). El resto se almacena en la extensión del acumulador (AH o DX, según que el operando fuente sea de tipo byte o palabra). Si el cociente es positivo y superior al valor máximo que puede almacenarse (7Fh : 127 o TFFFb:3276'7), o si el cociente es negativo e inferior al valor mínimo que puede almacenarse (8lh : -127 u 8001h : -32767), entonces el cociente y el resto quedan indefinidos, generándose una interrupción tipo cero. Lógica: si tipo fuente : byte AXlfuente (división con signo) AL : cociente AH : resto si cociente > 7Fh o cociente < 8lh TNT O si tipo fuente : palabra DX,AX/fuente (división con signo) (DX: palabra superior) (AX: palabra inferior) AX: cociente DX = resto si cociente > TFFFh o cociente < 8001h INT O Banderas: OF, DF, IF, TF, SF, ZF, AF, PF, CF ?-????? Ejemplo l: ; AX: FFEDh : -19 (dividendo) 02h: 2 (divisor) ; BL : IDIV BL AX :0lF7h (resultado) AH:01h : I (resto) AL : F7h : -9 (cociente) BL : Izh 197 Ejemplo 2: DX,AX: FFFF FFEDh : -19 (dividendo) DX: FFFFh AX : FFEDh BX :0002h :2 (divisor) DIV BL ; DX,AX:0001 FFFTh (resultado) ; DX :0001h : I (resto) ; AX : FFFTh : -9 (cociente) :BL:I2h Tipos de operandos, codificación y ejemplos: 198 Fuente Codificación reg llllOllw I mod lll r/m Eiemplos mem IDIV MEM-BYTE IDIV MEM PAL IDIV BL IDIV BX IMUL IMUL - Multiplicar, con signo (Integer MULtiply). Formato: IMUL fuente Descripción: Multiplica, considerando el signo, el acumulador (AL o AX) por el operando fuente, según que el tipo de este operando fuente sea byte o palabra. Si el operando fuente es de tipo byte, el resultado se almacena en AX. Si el operando fuente es de tipo palabra, el resultado se almacena en AX (palabra inferior) y DX (palabra superior). Si la mitad superior del resultado (AH para el caso de operando tipo byte o DX para el caso de operando tipo palabra) no es la expansión del signo del resultado, se activan las banderas CF y OF, indicando que esta mitad superior contiene dígitos significativos del resultado. Lógica: si tipo fuente: byte AX : AL x fuente (multiplicación con signo) si tipo fuente : palabra DX,AX: AX x fuente (multiplicación con signo) (DX: palabra superior) (AX: palabra inferior) si mitad superior del resultado : expansión del signo de la mitad inferior del resultado CF:0 en caso contrario CF: I OF: CF Banderas: Ejemplo 1: OF, DF, IF, TF, SF, ZF, AF, PF, CF x-? ???x AL: FEh: -2 BL:l2h: l8 FFDCh: -36 IMUL BL ; AX: FFDCh (resultado) ;BL : l2h : CF :OF:O 199 Ejemplo 2: AX: FFFEh : -2 BX :0012h : 18 ; FFFFFFDCh: -36 IMUL BX resultado : FFFF FFDCh DX:FFFFh AX:FFDCh BX :0012h CF:OF:0 Tipos de operandos, codificación y ejemplos: Fuente Codfficación Ejemplos reg I I I l0l lw I mod l0l r/m IMUL BL IMUL BX mem N IMUL MEM-BYTE IMUL MEM-PAL IN Instrucción: IN - Entrada de byte o palabra (INput byte or word). Formato: IN acumulador,puerta Descripción: Transfiere un byte o una palabra de una puerta de entrada del procesador al registro AL o AX, respectivamente. El número de la puerta se puede especificar mediante: ¡ Un valor fijo (de 0 a 255). o Un valor variable, el contenido en el registro DX (de 0 a 65535), pudiéndose acceder a 64K puertas de entrada. Lógica: si acumulador : AL . AL : dato de la puerta " "l]?YaXii ;.1,f puerta Banderas: OF, DF, IF, TF, SF, ZF, AF, PF, CF Ejemplos: IN AX,12h ; leer sobre AX una palabra de la puerta l2h IN AL,DX ; leer sobre AL un byte de la puerta especificada en DX Tipos de operandos, codificación y ejemplos: Acumulador Puerta Codificsción Eiemplos AL AX AL AX val val DX DX ll100l0w I val II l01l0w IN AL,lzh IN AX,12h IN AL,DX IN AX,DX 201 rNc Instrucción: INC - Incrementar destino en uno (INCrement destinotion by one). Formato: INC destino Descripción: Suma una unidad al operando destino. El operando puede ser byte o palabra. Lógica: destino : destino + I Banderas: OF, DF, IF, TF, SF, ZF, AF, PF, CF x-xxxx Ejemplo: ; AX: 1234h INCAX :AX:AX+l:1235h Tipos de operandos, codificación y ejemplos: Destino Codificación regl6 01000 reg regS mem 202 I 11 I I I lw I mod 000 r/m Eiemplos INC AX INC AL INC MEM-BYTE INC MEM PAL INT Instrucción: INT - Interrupción (INTerrupt). Formato: INT tipo-interrupción Descripción: INT activa el procedimiento de interrupción especificado por el operando. La dirección del vector de interrupción se calcula multiplicando por 4 el operando, que es un valor entre 0 y 255. El vector de interrupción se compone de dos palabras: o Primera palabra: desplazamiento. . Segunda palabra: segmento. Se bifurca a la dirección especificada por el vector de interrupción, salvan- do previamente las banderas (como en la instrucción PUSHF) y la dirección de retorno (CS, IP). El código generado es de 2 bytes, excepto cuando la interrupción es de tipo 3 (parar la ejecución en un punto del programa, breokpoint), en que el código que se genera es de un solo byte. Para retornar de una interrupción, se utiliza la instrucción IRET. Lógica: SP: SP-2 banderas + pila IF :0 TF:0 SP: SP-2 65 * pila CS : tipo-interrupción * 4 + 2 SP: SP-2 1p _ pila IP : tipo-interrupción x4 Banderas: T' T' lu' ru' T' T' f' T' g Ejemplo: INT 23 ; interrupciín 23 203 Tipos de operandos, codificación y ejemplos: 204 Tipo-de_interrupción Codificación Ejemplos valor distinto de 3 I 1001101 | tipo_interrupción INT 23 valor igual a 3 l 1001 100 INT 3 INTO Instrucción: INTO - Interrupción si desbordamiento (INTercupt if Overflow). Formato: INTO Descripción: Genera una interrupción tipo 4 si existe desbordamiento (overflow), es decir, si OF: l. En cáso conirario se continúa la ejecución con la instrucción siguiente, sin ejecutar el procedimiento de interrupción. Lógica: siOF=l SP: SP-2 banderas IF :0 * pila TF:0 65 _ pila SP: SP-2 : CS válor contenido en la palabra 4 * 4 + SP = SP-2 2: 18 : l2h ¡p _ pila IP : valor contenido en la palabra 4x 4: 16: lOh Es equivalente a: si OF: I INT 4 Banderas: T, O--', ", T, T' T,T, T' g Ejemplo: INTO ; interrupción si desbordamiento (overflow). Tipos de operandos, codificación y ejemplos: Operandos Codificación EjemPlo 11001110 INTO 205 IRET Instrucción: IRET - Retornar de una interrupción (Interrupt RETurn)., Formato: IRET Descripción: Devuelve el control a la dirección de retorno salvada en la pila por una operación de interrupción previa y restaura los registros de banderas (como en la instrucción POPF). IRET se utiliza para finalizar un procedimiento de interrupción. Es equivalente a la instrucción RET en un procedimiento: Interrupción Procedimiento Llamada Retorno Lógica: INT IRET CALL RET 1p _ pila SP:SP+2 gg _ pila SP:SP+2 Banderas - pila SP:SP+2 Banderas: OF, DF, IF, TF, SF, ZF, AF, PF, CF XXXXXXXX Ejemplo: X IRET ; retorno de una interrupción. Tipos de operandos, codificación y ejemplos: Operondos Codificación Ejemplo ll00llll M rRET JA/JNBE Instrucción: JA Formato: JA - Bifurcar si suPerior (Jump if Above). JNBE - Bifurcar si no inferior ni igual (Jump if Not Below or Equal). desplazamiento JNBE desplazamiento Descripción: Transfiere el control a la instrucción (IP + desplazamiento) si se cumple la condición CF:0 y ZF :0. Si CF:l o ZF:1, no hay transferencia de control' El desplazamiento debe estar comprendido entre -128 y + 127 bytes de esta instrucción, es decir, desplazamiento es un valor con signo de 8 bits (l byte). Above (por encima de) y Below (por debajo de) se refieren a la relación entre dos valores sin signo. Greoter (mayor que)-y less (menor que) se refieren a la relación entre dos valores con signo. Lógica: siCF:0yZF:0 IP:IP+desplazamiento (el signo del desplazamiento se extiende a l6 bits) Banderas: T' T' '', T' T' ':,T' T, T Ejemplo: CMP AX,BX JA ETIQUETA ; comparar AX con BX ; bifurcar a ETIQUETA si AX > BX : (sin considerar el signo) Tipos de operandos, codificación y ejemplos: Desplazamiento Codificación Ejemplos desp 0l 1l0l l0 | desp JA ETIQUETA JNBE ETIQUETA JAE/JNB Instrucción: JAE - Bifurcar si superior o igual (Jump if Above or Equal). JNB - Bifurcar si no inferior (Jump if Not Below). Formato: JAE desplazamiento JNB desplazamiento Descripción: Transfiere el control a la instrucción (IP + desplazamiento) si se cumple la condición CF:0. Si CF: 1, no hay transferencia de control. El desplazamiento debe estar comprendido entre -128 y + 127 bytes de esta instrucción, es decir, desplazamiento es un valor con signo de 8 bits (l btte). Above (por encima de) y Below (por debajo de) se refieren a la relación entre dos valores sin signo. Greater (mayor que) y zess (menor que) se refieren a la relación entre dos valores con signo. Lógica: si CF:0 IP:IP+desplazamiento (el signo del desplazamiento se extiende a l6 bits) Banderas: T' T' tr' T, T' t:,y' T' g Ejemplo: CMP AX,BX JAE ETIQUETA ; comparar AX con BX ; bifurcar a ETIQUETA si AX > BX ; (sin considerar el signo) Tipos de operandos, codificación y ejemplos: 208 Desplazamiento Codificación Ejemplos desp JAE ETIQUETA JNB ETIQUETA 0lll00lt I desp JB/JNAE /JC Instrucción: JB Formato: JB - Bifurcar si inferior (Jump if Below). JNAE Bifurcar si no superior ni igual (Jump if Not Above nor Equal). JC - Bifurcar si acarreo (Jump if Carry). desplazamiento JNAE desplazamiento JC Descripción: desplazamiento Transfiere el control a la instrucción (IP * desplazamiento) si se cumple la condición CF : l. Si CF:0, no hay transferencia de control. El desplazamiento debe estar comprendido entre -128 y + 127 bytes de esta instrucción, es decir, desplazamiento es un valor con signo de 8 bits (l byte). Above (por encima de) y Below (por debajo de) se refieren a la relación entre dos valores sin signo. Greoter (mayor que) y Zess (menor que) se refieren a la relación entre dos valores con signo. Lógica: si CF: I IP:IP+desplazamiento (el signo del desplazamiento se extiende a l6 bits) Banderas: OF, DF, IF, TF, SF, ZF, AF, PF, CF Ejemplo: CMP AX,BX ; comparar AX con BX JB ETIQUETA ; bifurcar a ETIQUETA si AX < BX ; (sin considerar el signo) Tipos de operandos, codificación y ejemplos: Desplozomiento Codificación Ejemplos desp 01110010 I desp JB ETIQUETA JNAE ETIQUETA JC ETIQUETA 209 JBE/JNA Instrucción: JBE - Bifurcar si inferior o igual (Jump i"f Below or Equal). JNA -Bifurcar si no superior (Jump i.f Not Above). Formato: JBE desplazamiento JNA desplazamiento Descripción: Transfiere el control a la instrucción (IP .t desplazamiento) si se cumple la condición CF: l o ZF :1. Si CF :0 y ZF : 0, no hay transferencia de control. El desplazamiento debe estar comprendido entre -128 y +127 bytes de esta instrucción, es decir, desplazamiento es un valor con signo de 8 bits (1 byte). Above (por encima de) y Below (por debajo de) se refieren a la relación entre dos valores sin signo. Greater (mayor que) y Zess (menor que) se refieren a la relación entre dos valores con signo. Lógica: siCF:loZF:l IP:IP+desplazamiento (el signo del desplazamiento se extiende a 16 bits) Banderas: OF, DF, IF, TF, SF, ZF, AF, PF, CF Ejemplo: CMP AX,BX JP ETIQUETA comparar AX con BX bifurcar a ETIQUETA si AX < BX (sin considerar el signo) Tipos de operandos, codificación y ejemplos: Desplazomiento Codificación 0lll0ll0 | desp desp 210 Ejemplos JBE ETIQUETA JNA ETIQUETA JC ETIQUETA JCXZ Instrucción: JCXZ - Bifurcar si CX es cero (Jump tf CX is Zero). Formato: JCXZ desplazamiento Descripción: Transfiere el control a la instrucción (IP + desplazamiento) si se cumple la condición CX:0. Si CF * 0, no hay transferencia de control. El desplazamiento debe estar comprendido entre -128 y +127 bytes de esta instrucción, es decir, desplazamiento es un valor con signo de 8 bits .a (1 byte). Esta instrucción es útil al comienzo de un bucle, para saltárselo si el contador (CX) tiene el valor cero, es decir, para ejecutar el bucle cero veces. Lógica: si CX:0 IP:IP+desplazamiento (el signo del desplazamiento se extiende a 16 bits) Banderas: OF, DF, IF, TF, SF, ZF, AF, PF, CF Ejemplo: DEC CX JCXZ ETIQUETA ; CX: CX-1 ; bifurcar a ETIQUETA si CX:0 Tipos de operandos, codificación y ejemplos: Desplazamiento Codificación Ejemplo desp 11100011 | desp JCXZ ETIQUETA 211 JE /JZ Instrucción: JE - Bifurcar si igual (Jump tf Equal). JZ - Bifurcar si cero (Jump rf Zero). Formato: JE desplazamiento JZ desplazamiento Descripción: Transfiere el control a la instrucción (IP + desplazamiento) si se cumple la condición ZF : l. Si ZF:0, no hay transferencia de control. El desplazamiento debe estar comprendido entre -128 y + 127 bytes de esta instrucción, es decir, desplazamiento es un valor con signo de 8 bits (l byte). Lógica: si ZF: I IP:IP+desplazamiento (el signo del desplazamiento se extiende a l6 bits) Banderas: g, T, tU, T, T, t:, T, T, g Ejemplo: CMP AX,BX ; comparar AX con BX JE ETIQUETAI ; bifurcar a ETIQUETAI si AX: BX SUB AX,BX ; AX: AX-BX JZ ETIQUETA2 ; bifurcar a ETIQUETA2 si AX es cero. Tipos de operandos, codificación y ejemplos: Desplazamiento Codificación Ejemplos desp 01110100 | desp JEETIQUETA JZ ETIQUETA 212 JG/JNLE Instrucción: JG - Bifurcar si mayor Formato: JG desplazamiento (Jump if Greater). JNLE Bifurcar si no menor ni igual (Jump if Not Less nor Equal). JNLE desplazamiento Descripción: Transfiere el control a la instrucción (IP + desplazamiento) si se cumple la condición ZF :0 y SF : OF. Si ZF: I o SF + OF, no hay transferencia de control. El desplazamiento debe estar comprendido entre -128 y + 127 bytes de esta instrucción, es decir, desplazamiento es un valor con signo de 8 bits (1 byte). Above (por encima de) y Below (por debajo de) se refieren a la relación entre dos valores sin signo. Greoter (mayor que) y Zess (menor que) se refieren a la relación entre dos valores con signo. Lógica: si ZF :0 y SF: OF IP:IP+desplazamiento (el signo del desplazamiento se extiende a l6 bits) Banderas: g'T,'U' T, T' ?,T'T, T Ejemplo: CMP AX,BX ; comparar AX con BX JG ETIQUETA ; bifurcar a ETIQUETA si AX > BX ; (considerando el signo) Tipos de operandos, codificación y ejemplos: Desplazamiento Codificación Ejemplos desp 0lllllll JG ETIQUETA I desp JNLE ETIQUETA 213 JGE/JNL Instrucción: JGE - Bifurcar si mayor o igual (Jump if Greater or Equal). JNL - Bifurcar si no menor (Jump if Not Less). Formato: JGE desplazamiento JNL desplazamiento Descripción: Transfiere el control a la instrucción (IP + desplazamiento) si se cumple la condición SF: OF. Si SF + OF, no hay transferencia de control. El desplazamiento debe estar comprendido entre -128 y + 127 bytes de esta instrucción, es decir, desplazamiento es un valor con signo de 8 bits (l byte). Above (por encima de) y Below (por debajo de) se refieren a la relación entre dos valores sin signo. Greater (mayor que) y Zess (menor que) se refieren a la relación entre dos valores con signo. Lógica: si SF: OF IP:IP+desplazamiento (el signo del desplazamiento se extiende a l6 bits) Banderas: OF, DF, IF, TF, SF, ZF, AF, PF, CF Ejemplo: CMP AX,BX JGE ETIQUETA comparar AX con BX bifurcar a ETIQUETA si AX > BX (considerando el signo) Tipos de operandos, codificación y ejemplos: DesplaTqmiento CodiJ'icación Ejemptos desp 214 0l l l l l0l I desp JGE ETIQUETA JNL ETIQUETA JL/JNGE Instrucción: JL - Bifurcar si menor (Jump if Less). JNGE Bifurcar si no mayor ni igual (Jump if Not Greater nor Equal). Formato: JL desplazamiento JNGE desplazamiento Descripción: Transfiere el control a la instrucción (IP + desplazamiento) si se cumple la condición SF + OF. Si SF: OF, no hay transferencia de control. El desplazamiento debe estar comprendido entre -128 y -f127 bytes de esta instrucción, es decir, desplazamiento es un valor con signo de 8 bits (l byte). Above (por encima de) y Below (por debajo de) se refieren a la relación entre dos valores sin signo. Greqter (mayor que) y less (menor que) se refieren a la relación entre dos valores con signo. Lógica: si SF # OF IP:IP+desplazamiento (el signo del desplazamiento se extiende a 16 bits) Banderas: OF, DF, IF, TF, SF, ZF, AF, PF, CF Ejemplo: CMP AX,BX ; comparar AX con BX ETIQUETA JL ; bifurcar a ETIQUETA si AX < BX ; (considerando el signo) Tipos de operandos, codificación y ejemplos: Desplazamiento Codificación Eiemplós desp 0lllll00 ldesP JL ETIQUETA JNGE ETIQUETA 215 JLE/JNG Instrucción: JLE - Bifurcar si menor o igual (Jump if Less or Equal). JNG - Bifurcar si no mayor (Jump tf Not Greater). Formato: JLE desplazamiento JNG desplazamiento Descripción: Transfiere el control a la instrucción (IP + desplazamiento) si se cumple la condiciónZF:loSF#OF. Si ZF : 0 y SF: OF, no hay transferencia de control. El desplazamiento debe estar comprendido entre -r28 y + r27 bytes de esta instrucción, es decir, desplazamiento es un valor con signo de 8 bits (l byte). Above (por encima de) y Below (por debajo de) se refieren a la relación entre dos valores sin signo. Greater (mayor que) y zess (menor que) se refieren a la relación entre dos valores con signo. Lógicá: siZF:loSF*OF IP:IP+desplazamiento (el signo del desplazamiento se extiende a l6 bits) Banderas: T'T, 1", T, T' T,g'T' g Ejemplo: CMP AX,BX JLE ETIQUETA comparar AX con BX bifurcar a ETIQUETA si AX < BX (considerando el signo) Tipos de operandos, codificación y ejemplos: 216 Desplazamiento Codificoción desp 01l1lll0 | desp Ejemplos JLE ETIQUETA JNG ETIQUETA JMP Instrucción: JMP - Bifurcar (JUMP). Formato: JMP dirección Descripción: Transfiere el control incondicionalmente al operando. La bifurcación puede ser: - Dentro del mismo segmento. En este caso, IP se sustituye por el valor del desplazamiento de la instrucción referenciada. El desplazamiento, a su vez, puede estar: ¡ Entre -128 y + 127 bytes de la instrucción. En este caso, se genera una instrucción de dos bytes de longitud (bifurcación corta). o Inferior a -128 o superior a +127 bytes. El desplazamiento puede ser hasta de 32 Kbytes. En este caso, se genera una instrucción de tres bytes de longitud. distinto segmento. - A En este caso, CS e IP se sustituyen por los valores correspondientes a la instrucción referenciada. La bifurcación también puede ser: o Directa, es decir, especificando una etiqueta. o Indirecta, es decir, especificando una dirección. Lógica: si bifurcación a distinto segmento CS: segmento IP : desplazamiento en caso contrario si bifurcación directa IP : desplazamiento en caso contrario IP : IP + desplazamiento (con signo) Banderas: T, T' 'U' T' T' Z:' T' T' g 217 Ejemplo 1: JMP ETIQUETA Ejemplo 2: JMP FAR PTR ETIQUETA ; bifurcación directa a ETIQUETA ; (a distinto segmento) Ejemplo 3: JMP [BX] ; bifurcación indirecta (al mismo segmento) Ejemplo 4: JMP FAR PTR [BX] ; bifurcación indirecta (a distinto segmento) Ejemplo 5: SALTO DW PROCI ; desplazamiento de PROCI JMP SALTO Ejemplo 6: SALTO DD PROCI JMP SALTO ; bifurcación directa a ETIQUETA ; bifurcación indirecta PROCI (al mismo ; segmento) ; dirección completa de PROCI ; (desplazamiento y segmento) ; bifurcación indirecta a PROCI (a distinto ; segmento) Tipos de operandos, codificación y ejemplos: Segmento Llamada Codificación Ejemplos mismo directa lll0l001 | desp JMP ETIQUETA mismo directa corta I I l0l0l I I desp JMP SHORT ETIQUETA mismo indirecta llllllll I modl00r/m JMPETIQUETAIDII distinto directa I I l0l0l0 | desp I seg JMP FAR PTR ETIQUETA distinto indirecta IIIIlllI I modl0lr/m JMPETIQUETATDII 218 JNC lnstrucción: JNC - Bifurcar si no acarreo (Jump if No Carry). Formato: JNC desplazamiento Descripción: Transfiere el control a la instrucción (IP + desplazamiento) si se cumple Ia condición CF:0. Si CF: l, no hay transferencia de control. El desplazamiento debe estar comprendido entre -128 y + 127 bytes de esta instrucción, es decir, desplazamiento es un valor con signo de 8 bits (1 byte). Lógica: si CF:0 IP:IP+desplazamiento (el signo del desplazamiento se extiende a l6 bits) Banderas: T, o_-t, tu, T, T, ,:, T, T, T Ejemplo: ADD AL,BL ; AL : AL + BL JNC ETIQUETA ; bifurcar a ETIQUETA si no acarreo Tipos de operandos, codificación y ejemplos: Desplazamiento Codificación Eiemplo 0l 110011 | desp JNC ETIQUETA desp 219 JNE/JNZ Instrucción: JNE - Bifurcar si no igual (Jump if Not Equal). JNZ - Bifurcar si no cero (Jump tf Not Zero). Formafo: JNE desplazamiento JNZ desplazamiento Descripción: Transfiere el control a la instrucción (IP + desplazamiento) si se cumple la - condición ZF:0. Si ZF: l, no hay transferencia de control. El desplazamiento debe estar comprendido entre -128 y +127 bytes de esta instrucción, es decir, desplazamiento es un valor con signo de 8 bits (l byte). . Lógica: Above (por encima de) y Below (por debajo de) se refieren a la relación entre dos valores sin signo. Greater (mayor que) y Zess (menor que) se refieren a la relación entre dos valores con signo. si ZF:0 IP:IP+desplazamiento (el signo del desplazamiento se extiende a l6 bits) Banderas: g, T, tU, T, T, ZF, AF, PF, CF Ejemplo: CMP AX,BX JNE ETIQUETAI SUB AX,BX JNZ ETIQUETA2 comparar AX con BX bifurcar a ETIQUETAI si distintos AX: AX-BX bifurcar si AX es distinto de cero Tipos de operandos, codificación y ejemplos: Desplazamiento Codificoción Ejemplos desp 01ll0l0l I desp JNE ETIQUETA JNZ ETIQUETA zn JNO Instrucción: JNO - Bifurcar si no desbordamiento (Jump if No Overflow). Formato: JNO desplazamiento Descripción: , Transfiere el control a la instrucción (IP + desplazamiento) si se cumple la ( condición OF:0. Si OF: l. no hav transferencia de control. El desplazamiento debe estar comprendido entre -128 y + 127 bytes de esta instrucción, es decir, desplazamiento es un valor con signo de 8 bits (l byte). Lógica: si CF: 0 . IP : IP + desplazamiento (el signo del desplazamiento se extiende a l6 bits) Banderas: T, O_-t, tt, T, T, t:, T, "_', g Ejemplo: ADD AL,BL ; AL: AL + BL JNO ETIQUETA ; bifurcar si no desbordamiento (overflow) Tipos de operandos, codificación y ejemplos: Desplozamiento Codificación Eiemplo 0l 110001 | desp JNO ETIQUETA desp 221 JNP /JPO Instrucción: JNP - Bifurcar si no paridad (Jump if No Parity). JPO - Bifurcar si paridad impar (Jump i"f Parity Odd). Formato: JNP desplazamiento JPO desplazamiento Descripción: Transfiere el control a la instrucción (IP + desplazamiento) si se cumple la condición PF:0. Si PF: l, no hay transferencia de control. El desplazamiento debe estar comprendido entre -128 y + 127 bytes de esta instrucción, es decir, desplazamiento es un valor con signo de 8 bits (l byte). Lógica: si PF:0 IP:IP+desplazamiento (el signo del desplazamiento se extiende a l6 bits) Banderas: OF, DF, IF, TF, SF, ZF, AF, PF, CF Ejemplo: JNP ETIQUETA ; bifurcar si paridad impar Tipos de operandos, codificación y ejemplos: z¿¿ Desplazomiento Codi"ficación Ejemplos desp 0ll010ll I desp JNP ETIQUETA JPO ETIQUETA JNS Instrucción: JNS - Bifurcar si no signo/si positivo (Jump if No SiSn/tf positive). Formato: JNS desplazamiento Descripción: Transfiere el control a la instrucción (IP + desplazamiento) si se cumple la condición SF:0. Si SF: 1, no hay transferencia de control. El desplazamiento debe estar comprendido entre - 128 y + 127 bytes de esta instrucción, es decir, desplazamiento es un valor con signo de 8 bits (1 byte). Lógica: si SF:0 IP:IP+desplazamiento (el signo del desplazamiento se extiende a l6 bits) Banderas: OF, DF, IF, TF, SF, ZF, AF, PF, CF Ejemplo: SUB AX,BX JNS ETIQUETA AX = AX-BX bifurcar a ETIQUETA si no signo, es decir, siAX>BX Tipos de operandos, codificación y ejemplos: Desplozamiento Codificación Eiemplo 0llll00l I desP JNS ETIQUETA desp z3 JO Instrucción: JO - Bifurcar si desbordamiento (Jump if Overflow). Formato: JO desplazamiento Descripción: Transfiere el control a la instrucción (IP + desplazamiento) si se cumple la condición OF = l. Si CF :0, no hay transferencia de control. El desplazamiento debe estar comprendido entre -128 y + 127 bytes de esta instrucción, es decir, desplazamiento es un valor con signo de 8 bits (l byte). Lógica: si OF = I IP:IP+desplazamiento (el signo del desplazamiento se extiende a 16 bits) Banderas: OF, DF, IF, TF, SF, ZF, AF, PF, CF Ejemplo: ADD AX,BX JO ETIQUETA AX: AX + BX bifurcar a ETIQUETA si desbordamiento (overflow) Tipos de operandos, codificación y ejemplos: Desplazamiento Codificoción Ejemplo desp 01110000 | desp JO ETIeUETA 24 J PIJ PH [n.";tr¿lccid*¡r r F *rrn=f t¡: !)*r*ripci*rl:: F, i¡*i,:r.: '¡i{:: l.,t: ;:r;i¡::i:i1e :l 16 hitsi fisnei*rar¡: .i. r!: ,1": j.- t i*mp!r,r: ':-"i *:,,1,' ri,¿ : lir rrs cii: +p*r*nrli:,0 f}¡t,9,:: .i,f :1: at-r¡¡g¡a3'litrr .'¡' :,'.i' r¡::r!rn ;' :;::ift?:í:i!.,:, :..1,'' :i::': : a;l fi:li1i *l¡t'::,0:l¡'il;; ij,:::r .iP E'fTQUETA ilEr F:'ltQ{-rETA 2á JS {nsfrucción: JS " Bilurc;rr si sieno (Jurtp on fiiin). F'crmato: JS desplazunlcrrt.o l)*:seripción: l'ransliere el control a ia instruccron (lP ']- desplazarnienl.t>) ;i se r.¡;lltple la condición SF .-' l. Si SF ,. 0. no h;ry Lr¡llrslclencj;r de conttol. El desplazarniertir; clebe estar cumprcnrJiclo elttre 126 ¡" I l-li b_vtes de esta insl.rueción, cs decir, desplazanuenl.o es ull v;tlol. cr-lr :,jgl;r-r rje 8 bits (l byre). l,ogica: si SF ,' I IP ... Its I dc:'Lrla¿;utticnltt (.r,i ;;igrxr del del;plaz¿l¡rjr:nto sc exriende a ló bit:i) ffa¡rderas: CIF, tojcrn¡rl*: 1-]1. lF I F. t"t SLIB AX.tsX iS É,TIQtrF,I A LF " ¡\F. PI,, CF ; AX ,. AX BX : lrifurc¿u ;r b ttQtJE lA sr signo. ct¡ ri*.ir. lsi AX':'0 Ti¡ros de operandos, codificacirin y rjemplos: Dcs¡tluíumrt:nto L'ttltf'icucuin desp 7fj6* 0l i 11000 j rlesp E¡em¡tla JS ET'IQLJE-IA LAHF Instr¡rcción: LAftF t'argar regi:;tro AF{ colr la-. hrndem:; (I ond regi.stt'r .'1Il fi"om I;lnys) Formato: LAIIF Deseripeión: (.'r:pia las trr.nderas SF, ZF, AF, P[: y (]F en los bit.s ''!, ti,'7, ? y 0., respei:ti vamente. del registro AII El contcnido dc los bits 5. .] v I qr"redan indr finidr:s. SF -'" bit 7 ZF -' bit 6 AF ' hir,X ('F ,- bit 0 PF -bit? Lógica: AFI, SF :ZF :x: AF:r:PF:r :('F (r quiere decir r,afor inrlefiniclol { : r¿uiere cleeir concltenrrlc¡ Band¡:rns: r]:" Fljemplo: ?F', LA[{F (rF ll, ]i sF 7F. AF, PF, ; er:pia benderr:. sohrr Af f 'Iipos de oper:rnrlos, cr¡dificaeión .y ejcrnplos: {)perando.r {-'o¡li!'icrciórt F;iunpl* 100il lil f ArIF -ffi LDS {¡as'{rr¡ce ión; [,DS " Ca:gel' iegisiro de s;;:::i;;:,-, ri; ;''Lt;t¡d üata Seg*;enl r¿'s,s;,:,-,t " S orrnatcs: l-l)S *eslli:o, i'u;:nle Ijescripciq;sÉ: Tfi::r::irr:;'L:, i,i¿ ÉUili€f* 'lg 3l ',.r,--l j,;..1,;r;;.i:;.;.-.:,.":.;,'.i'"- -jtrtl;;.--: ,---- :,1;:,-,., ,---.,-.-,L:'-'.j . ..f r-:u. .,i.",-- . ;-:'-..::-... - -'1.:i?ltilitr. ,ir deile i-in ;tai .i..:i;i;üri¿ Op6refidii ;* ;iil;;c i-,i:,¿il;:. ique cB-, :: ¿¿ll: -.-. . ú€:r:.i;,irj,,= desi:iaZamiÉr, -'..r :.r- -,,.¡,, :.! " ; Ír: : ii$ .. .tj5tilfi-1ti Ji-:i:ii:; , jr,',i:::--i:f p:lai:l.l I r ;¡i;:irf ; i j;; iii'j* iiiiiai-'i ;. ,;;r.r.::, ,,. .:1"- fl,r i.?"inrei jf;{'¿itaii-} :üf,iirir -:;, *:J; ::*i,-i:, S*gxl::::.:li;1. Logicn; t)$ =. pal;r,il:r *pu*iaia F.a; i;,.,,,;1¡,¡ . I, d*Sir l;.,1: .= i-iiel.ii;i i!*¡denss: 'ür]lilñ;É-i: iif, T, :_o' 1:, T' T. iT I'i'"1 i,i1. ..r.,.r,-.r.r.--.: :..i. . i,". !,1. l:!,..-;1...., .::;;5,i:;:... -. 1 .: .":.. r,' n¿ XX ...,.,¡ ;-:.¡, ,, -l::jf-'i-.r:: --:':l..1-' l;: ]\\ " ::ii':;j¡j,i'r ,'-., ',i::'; :i¡,¡',:¡h, ü[* s3 ifti;:;-i]a.:r;'i-ii::lc'1]51;.j.;': -i ;,: .-"iab i;:,= i¡iiú i,ie';;^a::;;;ii::f. in-, Sf!i;,;l;iiü p".!ii-iiil = 34iI i:,;g:i'::i:ui $ai:; ¡i: ; :¡ ;il:; i I i;1 :,= ; 2.i4h í;.re6;nclil,, ¡j,-;_i.:lli,r: | ::.,f ,:;,i,,: = Í {,T E n I u ¿ li:iñ;áÍ.-:.iel i,¡i.-!f .:.: . i-Da{ t:,.tr,YV' :i{ *. d.isl1.r:¿ii11ien':'¡ ,Je .l{X =. :b?¿iii i'i¡:r;s ttr* *püraffi düs,':+iil r''¡¡:ia¡;il¡¡i 3' trjir!] ri;;:j¡. .:t\j:.:;'!;P)i li llesj¡¡;u',' .':';.,,r,itr.:,l-.,,.,,;¡'¡.;,.,t,.,u,', :'i:gi'ir ::-':;:;,:,)" .;{¡¡rj,,,,:.. ;:.,.,; ::'?! r,'n l-LlS 5l,tl',{}:M--DF¡\i- ¡V¡;¡*.' iri;:íl i,ie,ie sei =f r 1 i :.-i;a',i; -. L i. ;l'i._ti i,.1);,.i;,'i;.-,ti-,i 3ffi ¡'.j, ;¿ i;tii;.r"; LFA Instrucción: LFA - Cargar Cirección efectiva iL¡scd Eifective Arirxressl" Forn¡üto: I-EA iiestino,f"uente Descrdpción: T:ansiiere ei desplazarnie*ic cel operando fuente al operando destins, ill ;peranrlr: i'uente debe ie¡ lrn operandur de memoria tl-'yte ¡ raiai:rai. lJ1 ;:peranr$o destinc es rin :egistro de 16 bits, pero no un registro ne segm*nlo" LEA ¡ermite especificar registros lndices en el operando fuente, al ,;ü'nlrario que con ei operaclor üFIr$ET. Légrca: des¡ut* = enesi:iazamientil J* Í"uente Banrieras: {jr" L_\f. IF, TF. 5íj. ZF, ,\F, PF, CF : :;i eies¡;ta;:arniento cie XX: 1234h :v SI :0006h Ejemnlo: t i23Ah Lt¿r:i .,}.X,XXlSil Fipos r{e rrperandos. codit-ücaciirn y ejernplos: Ü¡tsÍ:tt¡: ¡qi.h l;ercnte tli¡r¡íiicscian :nern i*0011ül j moci reg rlm 'v'*¡¿¡: ¡nod eiene ser Ejemplos LEA AX,MEIvI--BYTE LEA 5I.MEM_f.\:_ * ii :;l rnod: ll" err<;r l¡:Feracion nc deflnida) e29 LES Instrueción: LES - ()argar registro de segmento e.xtr¡r (Laad Extra Segmenl regi.eter). Formato: t.ES destino,fuente llescripción: 'f'ransfiere un puntero ele -1? bits (dirección completa compuesta p<lr despla zamiento v segmento,'en este orden) correspondiente al se¡¡undo operandr, (que dehe ser lln operando de memori¡r de doble palahra): destino -clesplazanrienter (¡ralabrn de orden inferior) (primera palalrra) ES segment(, (palahrr de orden superior) (segunda palahra¡ El primer operanelo (destino.¡ debe ser urr registro (pero no rrn registrr-r de sePmen f (), t.ógica: ES ., palabra apuntada por (fuerrte r 2¡ destino frrenf e Banderas: ()F, [)F, IF, 'fF, SF, 7,F, AF, PF, (]F F)jemplo: YY' t)l-) )aX clespla;uamiento y segmentc, de XX s:i segrnento rJe XX I:114h si elesJrlnzamiento cle XX , 56'781¡ YY , l:JlA 56781t, que se almacena e:orno 7856.14111 prirnera palabra .- 7856 (desplnzamienfo¡ segunclr palahra 1.11? (segmento) I,ES SI,YY palatrra superior I i13.Xfi (segrnento) palabra inferior , 5678h (desplazarnientol SI ries¡rhzamienf o de XX , 5tr78h FS sesrnento de XX l').i{ti fipos ele operanelos, cotlificaeiírn y eiemplos: [)t:,sÍittt¡ Fuenlc {.1rli.licaciótt Eiern¡úo': regl6 rnenr.32 ll00(tll)rl I nrorl reg r 'rrr t,FS S{,F,/tF},4 DF'AÍ Nota: rnorl dehe ser / | I si rnocl '- ll, error (operaciírn nc rlef irririn) an LOCK lusLrueción; f,.()('K Blo¡-tuc;:r el Bus f'ormato: J,OUK Descripcirin; J.()i.iI( es un ¡trclilr: de un b.tl.c que a.eclr¡llJati;i ¿i r.¡Jla tJt3tfucciÓn y que activa Ja. seilal I..()(lK nu€Ill.¡iJS rjtcha insl.ruceiÓrl lc c¡ecul.;r; es clecir, impide la ullfl¿;rcir:¡l rlel ltus pot olros procesadr:res, ltlt¡lidienelo ele esta forma el accgs(J a los lccursos ct-ttttparl-ielos pr,lt i,;s jlr,1,:ts¡1elt¡l'cs- (L()(:K the bus) En si:,l.elnas de rnull.iples prllecsa.dores eon rcrr;rs{ls ct;lrt¡rarltdcls es necesaltr: un ntecallislllo de csle li¡to para cl eorl¡'r:l Llel ¡¡ccsso a estos recursos. Banderas; ()F" I)F. Il-. llcrn¡rlo: Sr r¡ucrcnrus irrr¡-lcdi; cJ acseso;r ulta. sel'rg dc rJ¡rlris cn rne'rnoria" es necesario ui.ilizar ilna tecurca. de senráfrtro" Si eJ valor rieJ selllili.¡ro es 0 (ver<le), quie- lg decll'que ¡rtrcde accsdelse" Si cl valr;r ijel sel¡lálil'g cs 1 (rr>jo). no se pueric ur:cerjcr. !,n isl.(l co¡tl.cxl(), la ir¡sl.luccir-¡n rnás ul-lj 'Js )l.(llj(j" que sc i,¡liliza para dos :;clnal'tllr¡ '¡ para pr)llellrl etl estado: I c(JSiJr,. pal¡¡ r'lblcller gl esl;¡dr; ''Jel {lrllr:). ; Ai J rrldrca irloq¡ucar á¡¿s {scln¿jlutrt tt) it) I ; ('HL,{ltJEAR: l!1(-)v AI "i I (J( K X(,'lJ(r Sl.l\,l.AFI )R.( ),AI . CMP AI.,,I JE ('l-lb,(ll-JlAlt ; Al-, ', I ; Sh,NIAI.()R(-) ., i (ro,¡o) : Al-, r:slado SEMAFORO ; l,SEtulAFORO .. I (rojo)? .:ii ...l:;iJurci¡r . it() ...;galiz;¡t' i)rr)ceso ; iJe¡;¡;uús de l'eali¿ar el ptuccso, i)OlJer serlt¡til't¡¡.) verrJe (v¡rlot"0). Cs dectr" " lrlrcr;l cl ttus NIOV 5L.MA1'ORL).{) ; liberar el btts l-.;ri; lllsll i.¡ccirtles l;igr:iellcs ¡r¡¡ lulcionarJall Jlt)r{lue cl estadrl tlel sernálclrei ¡.rr;rfira r:anlttiar cltre las ljii\lllJcci{)¡lss (-ifuIts y M()V. xt1 CF{EQUEAR: LOCK CMP SEh{AFORO,fi : ¿semafcro verde? JNE CF{EQI-IEAR ; nü .." iif¡;rcnr LCCK ItO\i SghtAFORO.t ; SEhl¡ri:CRii: i (rojo) Tipos de operamdos, codificación y ejernplas; perandos Codifícadcr: Eje*cpit; i Í^tá 111000{i LocH LffiDSlLODSB/tGDSW {nstrueción; r.,ÚDS - (largar cadena l-3t¡D \tn"gt. LüDSB - í-.argar caciena le i:vi:s tLOzD Byte *rre.g.t. i..üD,q\V -;:.)3vgvv cadena ;e pl:;lhm-s ,:'t- aü í{ord, !;:ilts ¡ " FoEr&afo: l,.iDS :¿üera--:uen¡e a, ;-JD:B -' t"Ü5\\ ilescrtsc:,0¡r: ir¡.ni,¡ieie u:r i,r'!,'t€ c, i:nr ::ai¡hra : ;-,i i-;dei'{e f'¡-:e¡'ie iiirer:ci:na¡,i:i : .!i ]S:Sil * r,lgi¡l:¿--., álu;nuia;¡r (i, r:¡ ,:,i. i\ctua-liza et:.::!i;iir:.'lii ::rll. ,. -,: .atin:e l. :,1.:.:ttnte .1.(.nier.:o r,l I r; ,._ r:r-iÍ: ,t ci-l ¡-ga.¡: -,:, o i.i,'. :l:j:af,Xlr ei i-.r:-:r:r i-,'.- r:¿i ,ili,tfc ,j.l l.:.f ..\ ., .;..:.:'/,'.. ,';,, ,:. j U:1í1 il.1t3d*;. s 5i *i rr::eranilr es rle t-1,:ti¡ nriiaitrg-. ..: ;.;.a.ri!fieie u:]a p*.iarrt ;,:i if,g!iiir., t'1 :,li:;iili¿ ii:¡ ii;ricaaes. .ri i;. ii-L:t,:ra dt .li.reccl.,¡Ir ¡rrt ,.:eiit f ülf .= r';, 5i ¡¡€ llifftii:i,i¿, :::Cif r1..3ni3 Iváese i"l.s Ii.ir.-t.i-{i;n¿¡ i-1,,,;- :, 5Tf}.) i:;: lii*' ,.' ' r-.1 t¿' ;r.:it:i,CCi;:t i,',iii:,1::,i;:"i;J,5;,::¡i'"'.-':l::':'i,:',.l!,:lt',i: l:.: t.:i"'..;;-t- ,\t -, -L- ' ":l r;: ll l.-. it ::-:- i:' ,r ,, .::l t; lf.riÍ''i-eal'-ri i-,.;I).:,\ c' ¡::.iir:iij::j;'-:- t,.t ;.:.li3fi:t i-),:,:il,ii .i; r. .i:i.li.',- ..t.,'. -i r r: .:Ci':;.ilre íii lf .,rl ¡.ir r lt.'i:'-ii. ,-- .:,¡,3¡¡¡.;l ,:':t:*Lli'.:r,:1,.1 :-r :r- '. -: li.; :,.' :'.iil¡,3 .'1 ¡"x;11¡1.3¡.¡-¡1:,.-.'¡ '::"i.ti": ':';."1: ":: , jl '. \(, ti:. -" r.1'.' '--:l .':'ll r':1. rl .i-: , ,; '.'r'i ...1r ,, r'. t'it¿i;.ri-: ,l.:ll'-':'lJ::. .:i;iif a,l-.: ,i1a;i:i.ll':.ii.i,l":-1,'l ..trl',rj-;:';li.-.::.'.-. .'.'tilll'iil .r!'.i i., ,1.y''.. .'il,.l rl .i:it - :':i,','ta:l:;.:: :..; .. '.:. lt,.::l (1.. .. .r il r.i.r:i,;'1 i-. ij:;1;r:il: si DF fr SI 'St idelte en cí1s0 conttario SI .,SI ¡lelts Banderas: OF. DF, TF, T F, :t Ejemplo 1: C-Lf) I FA Sf .Ft IFNIF I.ODS FITFNIE i Sl ; AI ,\F fF {f ; LIF -- 0 (ini'ret'ien{4.¡ S{) rirs¡iiran:icni¡r de FI IFNT'F F{-¡ENIE Si FtiFNIF er de tipc hvte. lrr irltirn¡ inrtnrc¡"iirn re prre<le sirriituir tr¡r: I ODSB i '\i I)S;[STI, SI SI : I Si FtiFNi'F es dc lipo ¡rclci..r;t. Jl ílltilll iliriri-i'i¡rri sr'¡rrrertrr'.ii\titrtii llll LODS\' Ejemplo 2: : .,\X i)S:fsll. Si Sl r .) L.OI)S FS:F{iFNIF ;\I FS:[SI] Tipos de operandos, eodificación ¡' e.iemplcr: Ca¡leno {ttdttÍt' ('tvlil'ittt'itt¡'t Ficttt!tlttr meln l0l()l IOu I ( )I)S l\fF\,f BY t'F T ( )I}SE r ()Ils ltF\{ P,'\l L( ){}S\\r H LOOP lnstrucción: Le)OP Bucle (LOOP). I'ormato: l,(iOP desplazantierrl cr Descripción: I)ecrernertta cl regrslro corrl"arJor (CX). Si (lX es distilrf.o de cer<1, cnl.onces IP.,.IP + despl;rzamiento (expandiendo cl signr: a 16 bits)" Si CX es ccro, elltollces se cjecuta la siguiertte insl.rucción. El desplazantiento debe esfar comprenclido erltrc 128 y t i27 ttytes de esta instrucciri¡1, es clecir, desplazamiento es un valor con sigtto ele 8 bits ( I byte). Me<lian1e esta instruccirin es ¡rosible implernerttar bucles. I-Jn t¡ucle es un conjunto de inslruceiones que se ejecutan una serie de veces. El csquerna es cl siguiente: MOV (.X,cont;ldor i CIX ,,- núrnero de veces que se va a ; cjecutar el bucle BI.JCt,E: I.OOP BUCLE ; CX =, CX -l y bifurca a BLICI-,E ;si CIX#0 Es posible realizar bucles aniclados, es decir, unrl dcntro de ettrcl. El esqucrna llara dos bucles es: M()V BU(.-l.El: ... C,\.conladr-rrl ; (lX,.,, contador buele I PIJSH CX ; salvar (lX I.OOP BUCILE2 ; CX -. (lX I y bifurca a tsLlCLE2 MOV CX.contador2 : CX =, cont¡¡d<lr bucle 2 BLJ(,I.82; POP C.X I-0()P BU(_][,El :si(lX*0 ; recuperar (lX : CX: C:X-"1 y bifurca a BUCLEI : si CX l'0 XF Las instrucciones para el bucie inrerno se ciespla:an iris posicione; para mayor claridad. I-r'rgicir l CX:CX-l IP : IP + desplazamientci {expandiencio e! signl a iG bits) siCX+0 Banderas: g'T'tr' T' T, y"y,T' 3 Fric*riplo: ; cálculo de la suma de io-q numeros i a j ü MOV AX.{} MOV CX,IS SUMAR: ADD AX,CX LOOP SUMAR : A,X va a conlene: e. tesi;;:ario ; coniador: iii ; AX: AX - ¡5 T rpüs de operandos, codificación y e.iemplos: DesplaZqmiento Cctdi.l¡t*t:;,tr desp il¡trO*i{i I desp ffi E,ierr;Pi'¡ LOC}F ETíQUETA LüOPE¡'LffftFZ IrTstnuccióE' .t'¡+¡:-gnaÉ*: i (]tr?l - B':clc sr ;gu';" i!..Cif i.i Eqwli. I l!0F'Z " Bucle si cero í"1,CSi'il z;:::;,: L ül}lF .,1,?:ri::azerj;e:ii i r: i i, ]+P"¿ Jesnlauam eni¡.-, i lleqr:niFr*Éé:t: i¡.rr :'r:: l';li. :l f i ieg!f llC t)t:":', rt i),1:,1. i CIX ) " S ,1,'i .,,', ." CX :'s, di-',.ii,i,-,-:' lif, cer+. eiliüifaii.:. iF -='IF -t Cespiazamielii' {i i;::.lditnJ* ei srg::c Cti j."'..':'-a;:¡r-'rto a 16 hitl). S;,r.:t' ,,.'i ,: CX: {.t" ft¡:¡t'r,ti*l se t.lecuta ln tns|t*";liÓ,:l il.¡,:,uienie" ;'', f ,-1rai¡72.:nle::tc, al::'i'rt :.':i::1'i i:,:rrripl*rdid* €l,t:.r-ai: - .1* ;; +' ii"l i::¡tel:; ;le i:::,.-r r:'.:::lr.iitc;J;:1, eil i1::,:i;:,;;3t,triezamient* es i.,-, t:i;i;,;,: F.;.rg!**: s_'.\".: f:X-, I I],:¡lrsler.?s: t -tr !' É-;1r":+r¡:lc: llg::¡ ¿i,r E iil¡ :a':i:Íi;. !. sj'iF=lyCX+ü ii'- {F} + desplaze"m;ento iexpandiendc ei srgno a 16 bits) T' l'., T' :f-" :: T'T'T ;:.ii:ilt'ir3r ei priffie: '¡a,,.:': ür..,i,:ila* de c:ero ei:. ,-iÍa lahia de birtes {TABLA} \,{OV CX.{-F,5C'í'FITABI-A MOV SI. ' j ilrTK(i: ilic Sl C}{F TAFI-.'\ iSi,.r CX: longrtud cie TAELA val*r lnieie.l indice in*ier¡e::¡ar indice {'*,t:lüai'er tün cero LOOPE *TR{r iNE Fii",. LL,-CF r.TRi.i llfi,' !'ia, I'¡ ¡ ¡ r {r, ir irí: i?i !1jdrü,S, *CldifÉ*aCióm ¡ i)e.:;i in:srcien!c, E j*':qüit:¡ *esp L OLT!'F FTIQUETA 237 LOOPNE /LOOPNZ instrueción: LOOPNH - Bucle si no igual (LAAP i.f Not Equal)" t,O0PNZ - Bucle si no cero (L,OOP af Not Zero)" I o¡:nlatsi: L()C)PNH clesplazarrrierr to l ,l)OF NZ desplazurrricrrto f itescripción: l)ecreinenta el registro contador (CX). Si ZF ,-,0 y (lX cs cJistinto de cero, entonces IP., IP t desplazarniento (expandienclo el signo dcl tlesplazamiento a l6 bits). Si ZF ." I c¡ CX -- 0, entonces se ejecuta la instrucción siguiente. El clesplaeamiento clcbe estar cornprendido entre l2B y t- 127 bytes de csta instlucción, cs decir, desplazalniento es un valor con signo de I bits (l bytc). a,,lgica: (ix,,.. cx_ I siZF,'-0yCX*0 IP .,. IP + clesplazamiento (el signo del dcsplazamiento se cxtiende a 16 bits) }i,¡¡¡deras: 'lu' :_u' l_l' :l' ::'' T, g' :u' c,¡*rnplo; ; tnconttar el primer valc¡r cero en una tabla cle bytes r.: (]X,I-ENGTH 'TABLA .t\l0V h4()v SI,.I {}TRO: IñlC 5I (;tvlp I'Atsl.AlSIJ,0 I íX]PI\¡H { }TRC) CX.= longitud de 'IABLA valor inicial indice incrementar indicc comparar cOn cero La úllirna ilrstruccirin cs cquivalcntc a JE FIN LOOP O RC) FIN: lip*rs rir opcrandos, codificación y ejcrnplos: Despluzurn'ento Codlltcacién tlesp lll0(Xi00 | desp 23E Ejemplo I,OOPNE ETIQUE]'A MOV Instrucción: MOV Mover (M0Ve). Formatr¡: N4OV destino,ftrente Descripción: 'lransfiere un byte o una ¡ralabra dcsde el npr,'rnncl,:r filente ill oprrandi destino. El operando clestino ¡ruede ser lln registr* o t¡n elemento cle memorie (byte o Palabra). Ei operincto fuente puede scr un regisfro, ttn elem¡n{r¡ cle memoria o un valor inmediatc. Amhos operandos cleben ser del mismo tipo (tr-yfe n ¡ralabr;l). Fl conteniclo especificaclo por el elemenlo fuente se c'npie sohre el elernert to de destino, quedanclo inalternder el clemcnto filerrle Lóg!*:r: destino : fuenle Banderas: OF, DF, IF, T'F, SF, 7,F, AF" PF, (lF Ejempro: :fl if,fi t M()V AX.BX ; AX l:l4h : BX 1114h Observeciones: *, No se pueclen ntÍi'er drtos entrr dcls clclr:eni¡:1, de tn¡rn'rri:l utilizar un tegistro inÍcrmedio: L!'r. r!r11 AX --PEPF MOV JIJAN,AX ; .IUAN '' AX t\,{OV AX,PEPE ; No se puede mover un valor inmediato a un registrn de segrnent.o- se puede utilizar un registro intermedio: Mov AX,l12 ; AX,. l12 MOV ES,AX : ES AX No se pttede rrtilizer cl registro ('S coma c.le':fina. ----" %g l ip*s Ct rrperaradc,l, ,r:trdiíir¡i;jü;l íjES;:r:t {!;.i:: i,;:..: , .. 3 *i:ítiiri.;" j .,:;ji :';t;¡ : :.. t:,ii j,,,:-::.1 "..,t,t i.::¡-:i¡.i. I 1i lt)tli.i, r, l;:.r i- !-"ar.::.:l: :,':üiji,ri-:uu :'r ü '1;if i' i{[iv]*_,1.l! i c,{il'.ir;1, .'.,tj:i.r!- .- 1i-, ,:¡-.r, r.,- ,..j j'i' r\l'r.,Il¡,¡,1,- ¡:, ¡q¡ l'ri-i :(:.:.it.1 ri.ri¡r,i i l.J ',t.-'., ir,:r.....;-i,, -, -^r- i'i; i'riL r-¡ i'--:, ....,t'"., i,¡:',-).o .. o-r'i. .rf ..i tr i ¡lir;i _¡_.r,11_- :') u i.,:t-1'" ,a..{. i}:q ...:\ :.1j i 1 r)', .... 1'.| ll:i-.:._',.", ¡'f- \" {) \, Íl--l.., r4 ¡jM ]::l ! 'l i: ':.'o i, *)r."-,¡i[.]+ Ir:+.. r,1 I ..; :,.' r.,r ilri. itóú ¡ r\i[]i'I '.:i. .. !:,r?: :.l i '1.,- :'_ii-,..r_: i\.(,.i :',i,:i,,'-,:.,i_ ?i*s i l,, ;-: l. :,iL.,i)'. tffi * t/,$ i fl\lE *Vffi ffi r M #V SWd' instr'¿ cclorr: I iitfi::r;j¡i.i-',1 l:l(.1;e llt; l:'lt', :l(.,'. I,i¡1I :)ti lltli!r. ,-i1 :t rl:):ll r lll rr tl¡ t' lr1.: lL:(rr:..- ,r:t "1 Ffl es,tr clri;o, hahrie unir f ransferenci¡r de lrrr elemento clel stp.nrenfo, direci:i¡lnlrcl¡r ¡rix FS, al misrno segmento. Frr.:r m,1.,'er elementils dentro del segmentrt direccionrcl(, pór l)S, h:ihtir qrrt hrret ES I-)S F.ó*ir'a: l'rilrr: de:;tinrr .,- crrlena flente dell:r .' l YPF de cadenrr firente (l ó ?) .,i I)r 0 Sl SI i delta lil III I delta fn 1':1lil t'()ntr¡ri{|l !:I SI delf r lll tr)I delt:r SÍnderas: {}r I}}- IF. IF, SF. 7F. AF. PF. { l- F,lernplc !' :y!ri]!.j-{ 1{){} hvte.: o prlrrls rlesde FIIENIF. en el stgmrnto tle d:rtos, a ' ! lFq I li"j( ) rn el :;ef,rnent() extra { I l! ; I)F -,, 0 (inc'rtmentnr SI y I)l) : SI =, elespl:¡z-runientr¡ de FIIFI.II'F ; I)I ,, despl:tzrttttientr¡ de I)FSI'INo ; ('X 10() (niitnero dr t'lementos) ]1tr"[Sll }1iS FIrF |".'!( ; mover los elenrenlos If I,F 1 SI,FI JFN I'F i FA T}T,I}FSI'IN( } :\{l}.\' ( \ l{x) iji 1"!,: -!tylrrtlt{)r sl}tr tipo hvte, le últim:l inslnrc:ción:;c pttedc sttsfituir por: PFF $fr !\i qB ; mover los elemc'nf os tipc ltylt' .-.li l¡r: rlrrvrrllt{}s :ron tiJrc palnhm, la irltinlr instn¡c'c'i(rn se puecle sustituir I{lr' RFF 1\4{ }VSW F{ernnlr: .1: : rr!(!!rr !(X) hyfes o palabrns desele FIIFNIF, en el scgtnenfn cle clatos, a : f )F,-.q I IN{ }- tarnbién en el sesnrento cit d¡tf r¡s ( Lt) FI IS!I F{ }[i I)F , 0(ini'renrr.-ntrr Sl y I)I) T }S Fq I F.'i. qI,FtIFN'IF I FA t)[,t)FS',ilN( ] fsv{(f\l ( X,100 RFF h,t( )VS IDr!,tSfl 2A- : mover los elelnentos li¡to palatrr:l FS t)S Sl rles:¡;l:tz*rrti¡1¡1¡rdrFTIEN'IF I)I ,- rlespl:tzrrnientt¡ de I)FS'I INo ('X l0f)(nirrlrero de elernentos) rnover los elenlerttos Cadenu dc.rtino Cudertu Júente CctdiJicaci(tn E¡anrpkx melll rlern MOVS I )L,S'I M()VSts MOVS I)ES'I 1010010w tsY I E.I,IJEN_ BY I'E PAI,.F'I,JEN_ PAI, M0VSW '- -i4s n?f' t¡ ü__. ':r:.:1:-.¡¡,'..,ii¡ea... jr .,,,. r', l:.¡lliCar, li.ll ::i¿]-.. t tu( ! ; í.tiltly, utrigred)" :.'¡:,.rir1,,i¡l'r, :;,:, ,. iti;.,'"¡r-!¡1:. .. '',:.,:.,r',:: ". :tt c*Ls:¡J*rlt e. li¡;rc, ei e.cumi:lad*; l.J\i- r: AXI pcr,-'i l1;":;. ,-:.r:.:.,. :,;Stit1 í;u* ei rip* Ce esie rfFefxli"{.C iur::te s.;:. ir;'.'ie + paii;l.r1::. !il. r''.-¡'.t::.: :tild.¿:¡ fuent* es de tipe: L:'.¡i*, ei :e-o-::.i!ta"dei:e alrnace*" en AX 'i.'" -,'¡.¡,', ¡-l+ fre.*tr-: '¡,t Jq; rir:': fl¿i:lbrt .:i res':!i:lC+ se ai:lacr:::; l:: '\3' : .. :.).,,-,: ,. ,:t:.i;:lr r.i\í i-f:ii:!::e Srl:Feiil¡: r l,t3. :íl -. ,¡ ,.¡,- r.,. t,,jtfrj,3.i,Je.: rÉs:,.rj::Lc1-.. ¡.\FL ¡,.i.a el c¡¡+ Ce c,perandO lin,-- L1,'l: I '\ .,, ,. - ,1¡¡ 11¡: :";r':ri:'...-:'.:-li:,:ifr:. l:jaí:í!; ir.-'f'! {eíü. Se acf":";afi !¡rs:i:,f-1e :, ... 'r .'.. ':i.:tt::::.:_ia: i.:.a: ,iql:ir ::rti:a Í:1.:f:j|irli Ci::i,:ielif digl:eS -r:ig.::.,ti:-';,,,, '. ,: ..:',. '-.. . ; , :-: {i.i,', " li , íililliipi:i::;:iir sir: ::it:t,f \ r.:- ¿ .iri,.ttf;':i: . .,:;:,..1 :' -.':.1r.¡ : :):.llti¡'iA ' tl'lj.,,t \ ,, AX i¿;¡1.;; r\:ri: : lr,':"-._,r'j,i-. : ln iign,C) ': .':.nr r .:,:,tl,ii;::.t¡ L l,t¡_rClt...: ) ¡,!rlq ,= lr:ila'bra i.ii i-ertc:j .1 ': i... .,-. --:. ,1,:-l.i-:,:l ,. "-: al,: t.i ' ¡i1r .'.:: i-': " {-r¡: ::: i' i . .:.'-. ' .!\ 't !* 1i .É,1^. lrrt :+:- .' ;,'l;' ',. : ,-',){ 5.;, : 2l,l* i'i,'¡ i.¡;r*1-i"r L, 2M aii \l\ ,' t,'j.11,". jj\ : " "lrlF ::-' . .!)r. ,.. ¡--:iri.':;.- i..:ti,!-i¡l,:iia..'i : Bi, .- iii: ; {-F- : l}F'= tl : ; : ¿":4 ;:ltiC,., -2" \,/,i r I'; t4f,. tsX I íesuiiaú¡o:0liii ):2Fa!: DX =,i)fi::h 'r._.,; ,- "l:l!ái : F.\. = ()ilF :1. - \_ ¡ - -/^ Tipos de r-rperand*¡s., cr¡dii'i¿:aciírn 3.: e.iemplos; fies: ir¡ t r',' Cotlifit*t::i-'n r{r!". j:11{:ii,¡r, ;'ri.l,: j: ¿;,¿r! l'\' I' i ,j:. '., ' i,.,: . ir;1 I, ir,¡' :i ." 2& NEG lnstrucción: NE(j - Negar,/Folntar cl completucnl.o a 2 (NE(iate). Formato: NEG destinr-r l)escripción: (.alcul;l ci valor ncgativo del operando, es decir, resta cl operanelo de cero y rlcvuclve el rcsull.ad¡¡ en el ¡nismo operando (byte o palabra). Para h¿¡ccr esto. cl o¡rerarrdo destino se resta del núnrero compuesto por todo unos y sc le ;uiade l. Esto es lo misnlo que el conrplettienlrs a2 del núIIICI'O. NL,(j de¡tino es er¡uivalcnte a l;ls tnstrucciones N0l' rlcsttnr-¡ lN(. Lr'rgica: rlcbl.ltl() si dcstino cs tlpo byte destino . FFh- destino destino -destinr¡ t I si rlestino cs tipo palabr a clcstinr¡ .' FFFFh- destino dcstino ,.. destino I I Bandcras: ()F, l)f,. lf,, 'I'F. SIr, Zb. AF, PF, CiF XXXXXX [[emplo: ; Fth=llllllllb :; : ODh ..,'0000 I lOlb ;AL"',F2h=llll0010b Ntl(i Ai. l lb ; At, ,,= OEh .,0000 I I lOb 'l"ipos dc operanclos. c¡rdil'icación y ejernplos: I)esluto (.otld'icación rüE illl0llw I nrod 0ll rÁn r¡Ier¡r ,ü Ejemplos NEG AI, NEG AX NEG MEM tsYl'E NEG MEM-PAL NOP Instrueción: NOP Ner nperaeiírn lNo OPersiion) Formato: NOP Descripción: Fl ¡rreicesador no hace nada- Pasa a ejc:cntar le inr{rrrcciiin sip,ttitnf t Lógica: Ningrrna. Banderas: OF, I)F, IF, T'F, SF, '7,F, AF, PF, ('F Ejemplo: NOP ; no olrerar'i(rn 'Tipos de operandeis, codificación v ejernplos: Operandos (''otlifieación Fjem¡"'lo l(D100(n NOP 247 r r l,¡¡ R r,¡t& l. i. r].. 1,: :' ' t \':.. r :i ;i..,:r::: r\rl}l? ," l' ' ,¡; .,. .: , "i-í' ,. .¡¡¡:-t; i,-:...]]j!:i)i.]..:..:i.|'-,.':..,:r'-3...ii::::iir-¡l¡i:].-li.'cí.t,-.i!.l¡,s¡it-:-¿:Cj;]].¡;::iiÜ!"¡:!,;3l:i' . .;:t1.i-r.. : . .- '. 1,. ,.-r: -- 'i.-:i;I¿:.i:ú,-¡ ., ¡,:-.;l-:,,:rví, r.., ..,Srr,itai-lll t.l.-1 tir iI,.lSfiiL} . .t::dl.] | a,;._"i .;*r ,' .l 1r:¡1.1¡¡i ;. ¡. Ole- .i..¡il .:t,,-: r_;-,,i; r:','i.: ,,;,:.. ,.;, . .-:l .t--;.:t,-l;.lr,l .i .:. . :_. ,,g .;¡,1,,-. t,?!;,.t:f.1" r.i,,, .. f ,'il.:h--.'.),.:i,!11.., )l . li. 'f". , ti¡ ,,',',t. 5.F l,):- " .t r.l,-'r i i, j : : , t; I l, i,' ..,1,S.,i ,t\t.) r 1';", :,,it.) 1" -.i'," 'i.. r.;: ,l _'ri.i:.! :,,i,, l- i¡'i,1,,ivf _ii ,r"fiJ 't "''. o'f lt.i{'.:r'i -i:r i, ,l ":i; *ffi fnsfrucción: ül;. F¡.-:rnle€s.¡¡ []es*ripci*n: ililr* f-"ogic:¿: tr'L Bancieras: í:.1 Hjem*l*: FUF:-'|,,..,, :, ; i ltt ii i i .lir(rir {]Fl A:".8.\ . .¡!i.4,. .= FE!:rCl: : 8.1,. .,r,, i Ji.trh Tip*s rie operandos " *c¡d ií ¡*ic'¡i ¡,¡c'i rii (: ür$i{lÉ r üesrinr¡ F-Í;€n;.,:, :-.¡..;¡.li!;¡:t;:irin f¡.¡!F ?í.1 r-*, reg ll1rll-' 0flflfi i {-}¡.1r:' I m¡r: iit: :".'-'¡.r I"RCI]1 ?a, m acu¡n v';rJ il)001l0w I val ()RQAL,,01h I e&, VA, l0lJ0000w I rnorJ Al rlnt I va.l ()R BJ_..30 oR 8X,30 iliui ¡l virJ (rR AX.l02h 0R ME,M BYT'E,OIh oR MEM_ PAt,.0l02h OUT lnstrueción: O{f I Salirl¡r rle byfeo palahrr ¡()IIlitul Ltyte: or y'otr{). Formato: ()[ f I prrert¡t,lrcumuledor [)escripción: '['ransfiere rrn b.yte o una ¡ralahr¡r del registrr¡ Af r¡ AX:r lrnír plrcrfíl cle seli d¡ del procesadeir. Fl nirrnero de la prrerta se puecle es¡rer:if icar mediente: o urr valor fijo (de (l a 255); r lrn valor varial"rle, el c'nntenido en el registro t.lX (rle (! :r 655]i¡. pr rrlián dose ar'cecler ¡t 6.4K pltrrtos de salirh t,ógica: si ac'lrmulador --, AL AI se escrihe en puerto si acrrmulirdor - AX AX se escrihe en puerf (t Banderas: oF. T)F. IF. I-F, SF. '7,F, AF, PF. ('F Ejemplos: Otf l l.2h.AX ; fransferir el velor dr A"X al prrertc l-2lr ()tfl t)X.Af ; transferir el valor de AI al puerto es¡recificnrlo 'lipos de operandos, codificaciírn y ejemplos: Atumulndot Ptterf Af, val AX val Af DX AX t)x n OotliJir:acirín F,ientf kt,t I ll00llw I val ()t r I l.lh,AI r)f t'l l.ltr.AX lll0lllw ()tl'l l-lx.Af t){r'I r)x"Ax ##p iÉ1slfuljr:li.¡tr; l¡..:il - :.!!.tiiiilr Sdl¿bI'A ;le La fri*. ;::',i -' ij ¡i tt.i ; il tr t ae * ; ri,;i € *\ t i rf ü I i i, tf J :.,; i', i.;:'¡;i;;-¡il.r" . .it*F ,:t;',,-;.i,,; .;i:i,ri,i'rtri!..r,Lri1; it'i;.i:,lsiiri;.. ¿i 3rfíneíif.ü ltip{i l¡¿iabra} quie :ic *nni,l*nlra an i.3 ait{] ce l* plla i:-i-,1.1:::-i:r:1.::-i.,r !:.11,:r'+: ;'egiti.rri lF',l:;i üpelanii{-i iesr,l;l* itipo::aiabra},:1'luegcr :r:;:ea:l:-.,.. ¡- ; JÜ) l;,-tb:Sifti -:ij :, -ei::!r.i,-, ;li itri ::e ::li;€iie *tpecificar:ümo desttirtt" :.,:.,.ir i-iii..lr-li,ir l{-r;i 1'riail:3a la -'i;,riciÓn üpiJcsl.a''ie P*}? es Ft-Sf{. i.,',:,r..i....., ..:,isi.i,: = tj.i¿.:r'í ipiri,:t{,iápr:;;"SS:SP .:;."1¡ ;iJ*i¡rr::-¡.;.r; .. '...:' , -l ..ti: j;r;" iti ^ 'i:f , 3F. zl; . AF, PFr. Cl: -..,:,,;,,.,,.,;..,: "ili' 1,.,( ::i.., i;i ti:.;-r::!] i:;l(r:::f¡j.i-i :'e ia p;;;;;.'{.:i I I il; ,,i/.li' ,,.\,.:i)¡ ..,.Ji-i ¡i-',.: r.,,,i,,,.r,..r,-,.,1: :i''llj -rL i'il \X - .:,:t-SPl ; 5;: .., ;ir' .- .l i Elflfi.Íri.,.i ijg ia.;il¡¡:; i? 'laiüÚié PElil :,j i.ri : ¡Lrt)!i r.; .¡ ít'¡tell¡ ian*c ia ;¿iodif!c¿rt;i*;i,-;e,{.}i l, '',,¡üV tr.';.lSill ,.'ií,)l r:i:f't--.,i,{ ,,',,*.1-] \i'..? ''::,.¡ ;,,, . i.i .:;É; r..:, .c.!-iii*;n : .\,\, ,'= :i,$:[SP] , r}IJFL-, - Á}i ..!P ==..!P + l ",:¡¡tlifil:*eiéf¡ y *jellipiOs, ')t3,i:!i!i, i:.,j{irf idilcttir¡ .:* :: ttrt!/}¿ü"\' I leg :.¿i:: ,,r: r;'i ;.:¡;i: i .'j{ii.ti i i I I .:i; i.,iiU reg i l1 ': .¡; J 0ii iri-]lr' i-rli. ritt-,oj q,10(J r¡':lr itr¡}}} li{iiiv1 -l3A{PÍ )F Er{j ry#pF f¡l:;ii l¿;ci¡3*¡; {jt}trF - Q:xcar 'randeras ,je la r-rita íFúf),Fiag:: :;j' ::;s,::ki f a}:]Láé¿{i I ;OPF i-}t:*;;lrpc;óm: T¡::¿nsilere r.its *:specilicr¡s ,le le :::i*rt,r':rl ,¡ ,ij"rr:; ..: ,; i:iia íapuil;adc prli ':1 regii;ri-' SP) ',: 'las :rartúu¡,' .. iúres qiie cc,nieiil¿:ii i:i'e1'r.r:liei;;*. ^,.,''. | -.' Ei registri: 3F se lncieutc,:ia l;*g; *l; ,:, ,:,;l li -*,ÜF 3it 1i-i * l)ii nii I -* íF i.";l ¡j * 'l',fl ¡ii ?*5ü 5 * Zí:: 'rit ril 4 -* All .bi¿ J * .?trF fi¿ -' C1i ,t;t i,* :¡lsir;;;iaü .:ili* ::,*a;:;:¿ liá ,'*.;'r;:;,u;, ;-lí,, j;,;li¡i.. r¿, ;¡ :-,,, ; -l;, i:,an ije;;;; = ; 5;? ...5p-.- Ld;t;.i¡rr*:;; üF - ],1. I jr', 'l f,. :it - ;_i" - ,i,I,:, n i;¡,t:;;*lu i ,l=i ,: fj* iib i'a :j ;': erJcir) c;r fl ¿¡. r'r.t ; r-ili:.iP : i'. irüi:'ir :i :'. ,rí 'i { i'F" .(r- :i i ¿¡Cii;,?-ii;:.¡; i--iir;,iie::i,., ¡r,,." t !;: .;fi{:f r¡¡i ¿i r}¡; } i *;¿üi f ie¡C iO iri,r, ii:i e ¡ i pl <,* Lr : iJ;;t:r'i;;itcs -. tt,,: : !.Í i. i: ;: :¡; ¡; liiili i irii -i'.;t:::'t;;iti ,l:;.li:rl; ?53 PUSH Instrur:eión: PI ISII Poner ¡nlrhm en la pila (P( I,\II v,onl ontt.t stack). F'r¡rrmeto: PI ISII frrenle []esc:ripción: Dec'rementr el prrntero ele la pila (SP) en L y luego tran:;fiere l:r p:tlnbn es' ¡rrcif ir:lrdlr err el oprrando firente a lo alto de la pillr lnhor:t apttntld:t por r:l resistro SP,. El repistro ('S no sc puede espeeificar c'omo filente . [,lr !rrsf nrci'irin qrre rerliz:¡ ll firnción oJruestlt de PtISH es P()P f ,ógica: sP sF '.r. ¡r:tlrhrr aJrrrntld:r por SS:SP .,, frrentr' Rnnderas: oF. I)F. IF. TF. SF'. '/F, AF, PF, (-F Eiemplo l: Pt iSFT AX : poner AX elr llr pil:r rr1rrivalenf e a: IB SF,] h,{r}v [st,l,Ax ;SP.,SP 2 P[TSFI PEPF ; poner lr palehr:r PEPF err Ia pil."r SI Ejemplo 2: : SS:[SPl AX et¡rrir,rlenlr' :r (erc'e¡ltrr:rndo Ia moelificrci(lrr de AX¡: rB sP,.¡ ; SP .,SP 2 I'I,I(-,¡V AX.PFPF : PFPE AX lVÍO\i [SPl"AX ;Ss:[SPl .. AX s{ 'fipos de op*randr¡s. codificaeií¡n .i' eiemplos: ?*r Fu(t?li' (''o¡líl'irucitín F it:t'n¡tlo,; rr:g I fi 0l(]l(! res PI-ISFI BX rner¡r lfi lf If llll Inrocl l1(lr/rrt PIISFI N,IEM PAI si:g 0{){l r*g ! l(l {rey / All PLISH FS PUSHF Instrucci¡ill; fltlSF{l' P<-¡llcl b;.r.nder¿rs cu I:r ¡rrl;r (Pr.t5a Fhgs onto stu:k). Forrnato: Dcscri¡.rcirin; trr.JSHt i-)r-:c¡r-:¡¡lclrl.;i el ¡rrrrrlclo de [;l pilir tSP) at .t" y Iucgr,,r ;.;.¡;;.:iit;{ ti-iir ','¿irjj c:, {i(- i;.r:, i.xl¡lclc¡;rs ;r l-lil.r, cspecílicos dc l;r p;rl;tbr;r dr"' irt ¡;il;i iJ jl ci.r:ir:;¡.¡ri;t ¡-;rlr el ii;grr'it o SP. r.)f - t¡i¡ i1 J-rF . illl i{j ¡F 'Lu! iF, 'bit I i:(¡'i;;t ¡ 1,1' i,-r l. ¡r .\F " l;ii ¡,i. " l-lit .) 1.) ,"1 {t :l;¡r l} l-.;l iri:lr r¡r;clri¡l quc tcitllzit Ia Irrrlr;rrjrl {lJ,jiJsslíi rjr; l'l-r-rirl ,-,, .F,.:'- r L,írgica: 5P SP .}, Ba¡¡dcras; irallllr;l dir,;ccir-;¡¡;rdil ;rur S5:SP bi¡;l.Jcl;l:', {,it. I)t, fF" tF, 5F" '¿F, At-. ¡ri. {. l,jernplo; Pl-JSHL' ; l)oll{Jl b¿urrlcr¿s cn la lrriir fipos rlc opcrandos. c¡r¡lrlicaci¡i¡r y tjelnpkls: {-ip<:rwukts l-'otl4lu:aciún b'¡crtt¡tkt tr.)0t J 100 Pr"jsHF 4W sc}t iil'.¡1^ lt. i:r:zqu!=rri:: lrav*s df s¡-::l.la,:{ ;:i -;1¡;1:,, lkrr_tt,¡q!,¡ CSrf'., i ¿f'f ¡" l¡1sl¡"r¡r'r'il','; i't_r!.-,a¡r: -l i,,, ,'l;:iJ.-lr-l:' I-1,:a:.:r: ; i:'r' ; ," , -,..r!,:i'.:ii,: :r. !:ii:, d:,i r--p;r:.r*r Crslin*.i*:lXc c,on ie bgnd,:r:, *e' h:1.:, trne¡:ifil:rl¿-.:,r, fi Seli]t1.if Op*r*.ldi¡. .;:1 t".1';.:y11r.;'_i* i::: ij,rr. . ;,: rir:s.lia;¿al er-t j. rt ixf;d* e-qnfa.ifii:ar cir*;t¿r¡::l'i. 5., ' ,'; r.'::.,:-,: Cei-.;" *arg¿lrs? :l {,.L.'.'espsi.ific:?r CL, s*:rl: $igr.i1¡;1- '', ;¡i..r1.i.' L13?ii:: ii:i,:. i!;:¡:,: L l' '\ 'i,i_ ., . =::,* *- ¡- - . :.:,a.rr t. rlr',Jr,. ..'.'1. = .if ti;itc ,r,/ +. i,:Í1C,_ r.li j"'ii '?\:' it' ll ¡l :Í.i:-ll: -.1 :: .: ,llir"-'' -- ; ,:r hir ¡. f n:rlti a* riettMc É {'i; {-l '' ,,' ! i:\l-r ':.: r:r r:. {r!1tr:1riL .- I t", : ,-: ( l ¡'rl ('l 'ílrr: Li¿t'tt; il i.:..r{: a i ¡.1 r: :ii n irj Y' -'r'! , , l{e,,:l ti! 1i:', Ált '1 ñ',ir:¡¡1¡¡¡.r, i iii'., 7.ii, !i[r, 7i:', .4,i' pi rot;i,i 3 lij't;i : 4!.- ,, {}1{ii 1i 1¡-:!r. íli'= {r :. , : é:. .,,. i :i i Q,0{}:b, i-F ,- {-: i...l,,, riit; Anles ¡,1 ,,. {ii,.-i¡ ¡ ll*h CF =.,i¡ i:i.," i{iii I1üüh --l',i ,,:"1.. '. i i i',f![il: .-'-: ,, . {.11 256 üesz.u¿1s {L: lüi Ai_-{1 i tl- ,= j l. i10{ib, cF : {t ¡üfiOh. {.1}r: I {'rO{}it;" CFi* {i Tipos de operandos, codificación y ejemplos: Destino Contodor Codificación I l0l00vw I mod 010 r/m reg reg Ejemplos RCL BL,CL RCL BX,CL reg val RCL BL,I RCL BX,I mem reg RCL MEM-BYTE,CL RCL MEM__PAL,CL val RCL MEM-BYTE,I RCL MEM__PAL,1 E7 RCR Instrucción: RCR - Rotar a la derecha a través de acarreo (Rotate through Carry Riqht). Formato: RCR destino.contador Descripción: Rotar a la derecha los bits del operando destino junto con la bandera de acarreo (CF) el número de bits especificado en el segundo operando. l, Si el número de bits a desplazar es se puede especificar directamente. Si es mayor que 1, su valor debe cargarse en CL y especificar CL como segundo operando. Lógica: temP : contador hacer mientras temp # 0 temp-cf : CF CF: bit inferior de destino destino : destino/2 bit superior de destino : temp-cf temP: temP - I si contador: I si bit superior de destino * bit anterior de destino OF: I en caso contrario OF:0 en caso contrario OF queda indefinida Banderas: OF, DF, IF, TF, SF, ZF, AF, PF, CF X-X Ejemplo: MOV CL,3 ; rotar 3 bits ; AL.:0101 I I lOb, CF :0 RCR AL,CL ; AL: 1000 l0llb, CF: I Cuento I 2 J 28 Antes Después AL:0101 lllOb, CF:0 AL:0010 ll1lb, CF: O AL:0010 llllb. CF:0 AL:0001 0lllb. CF:l AL : 0001 0l I lb, CF: I AL : 1000 l0l lb. CF : I Tipos de operandos, codificación y ejemplos: Destino Contodor Codificación Ejemplos reg reg I l0l00vw I mod 0l l r/m RCR BL,CL RCR BX,CL reg val RCR BL,I RCR BX,I mem reg RCR MEM_-BYTE,CL RCR MEM PAL,CL mem val RCR MEM__BYTE,I RCR MEM__PAL,I 259 R EPl R E PE / REPZ / RE PN E / RE PNZ Instrucción: REP REPE REPZ REPNE REPNZ Repetir operación de cadena (REPeat string operation). Repetir operación de cadena, si igual (REPeat string operotion, if Equal). Repetir operación de cadena, si cero (REPeat string operation, if Zero). Repetir operación de cadena, si no igual (REPeat string operation, if Not Equal). Repetir operación de cadena, si no cero (REPeat string operotion, if Not Zero). Formato: REP REPE REPZ REPZ REPNE REPNZ Descr:pción: Hace que la siguiente instrucción de cadena se repita un determinado número de veces, el especificado en el registro contador (CX). REP se usa en conjunción con las instrucciones MOVS (mover cadena) y STOS (almacenar cadena). REPE y REPZ son idénticas y generan el mismo código (un byte) que REP, pero se utilizan en las instrucciones CMPS (comparar cadena) y SCAS (explorar cadena), pero necesitan que ZF : | (es decir, que el resultado de la comparación o exploración haya dado igual o cero). REPNE y REPNZ son idénticas y generan el mismo código (un byte). Se utilizan (como REPE y REPZ) en las instrucciones CMPS y SCAS, pero necesitan que ZF: 0 (es decir, que el resultado de la comparación o exploración haya dado diferente o distinto de cero). En resumen: Instrucción REP REPE :REPZ REPNE: REPNZ 2ñ Función Instrucciones Repetir CX veces Repetir CX veces mientras ZF: I Repetir CX veces mientras ZF :0 MOVS, STOS CMPS, SCAS CMPS. SCAS Las operaciones repetitivas con cadenas son interrumpibles, es decir, el procesador reconocerá la interrupción antes de procesar el siguiente elemento. Esta instrucción genera un byte prefijo. Otros bytes prefijos son: o LOCK. . especificación de registro de segmento. Se pueden combinar diferentes prefijos, pero deben desactivarse las inte- rrupciones, pues la interrupción devuelve el control a la instrucción interrumpida o al prefijo anterior a esa instrucción. Lógica: hacer mientras CX * 0 ejecutar interrupción pendiente, si la hay ejecutar instrucción de cadena en el b¡e siguiente CX:CX-l si instrucción siguiente es CMPS o SCAS si ZF * bit z del códieo terminar Banderas: OF, DF, IF, TF, SF, ZF, AF, PF, CF Ejemplo 1: ; copiar TABLAI sobre TABLA2 (100 palabras) MOV CX,l00 ; CX : longitud de las tablas LEA SI,TABLAI ; SI : desplazamiento de TABLAI LEA DT,TABLA z i ot: f.:tJil:?Htti.t"n%" BLA2 REP MOVS [DI],[SI] Ejemplo 2: (segmento extra) ; copiar elementos ; localizar el primer valor diferente de dos tablas de 100 bytes (TABLAI y TABLA2) MOV CX,IOO LEA SI,TABLAI LEA DI,TABLA2 REPE CMPS lDrl,Isr] CX: longitud de las tablas SI : desplazamiento de TABLA I (segmento de datos) DI : desplazamiento de TABLA2 (segmento extra) comparar elementos mientras sean iguales CMP CX,O JE NINGUNO ¿cX:0? ; los elementos diferentes se encuentran en DS:[SI-l] y ES:[DI-l] 261 ; ; todos son iguales NINGUNO: Ejemplo 3: ; localizar el primer valor igual de dos tablas de bytes (TABLAI y TABLA2) MOV CX,l00 ; CX: longitud de las tablas LEA SI,TABLAI ; SI : desplazamiento de TABLAI LEA DT,TABLA , i or: !'.XtJi:.;Hff,tT'f" BLA| REPNE CMPS [DI],[SIl CMP CX,O JE NINGUNO ; (segmento extra) comparar elementos mientras sean ; : distintos ; ¿CX:0? ; los elementos iguales se encuentran en DS:[SI-l] y ES:[DI-l] ñrNcuNo' : todos son diferentes Tipos de operandos, codificación y ejemplos: Operandos Codificación Ejempto 1l I 262 l00lz REPE RET Instrucción: RET - Retornar de un procedimiento (RETurn). Formato: RET [valor] Descripción: Retorna de un procedimiento, previamente invocado mediante CALL, utilizando como dirección de retorno la dirección salvada en la pila por CALL, que corresponde a la instrucción siguiente a dicha sentencia CALL. El ensamblador genera un retorno distinto, según se haya definido el procedimiento: definido como NEAR: - Procedimiento En este caso, se quita de la pila una palabra, que corresponde al desplazamiento de la dirección de retorno. Se genera un retorno dentro del mismo segmento. definido como FAR: - Procedimiento En este caso, se quitan de la pila dos palabras, que corresponden al desplazamiento (primera palabra) y al segmento (segunda palabra) de la dirección de retorno. Se genera un retorno a un segmento dis- tinto. El valor opcional que se especifica en RET es el valor que hay que sumar al registro SP, con objeto de descartar parámetros. Si los parámetros son direcciones de memoria, cada parámetro ocupa: (desplazamiento), si procedimiento NEAR. - 2I palabra palabras (desplazamiento y segmento), si procedimiento FAR. - Lógica: 1P - pila SP:SP+2 si distinto segmento 69 - pila SP:SP+2 si existe valor opcional SP:SP+valor Banderas: g' T' tt' T' T' ?, T' T' g Ejemplos: RET ; retorno de procedimiento ; (no hay parámetros) 26Íl RET 4 retorno de un procedimiento NEAR con 2 parámetros de direcciones (4 = 2 parámetros x 2 bytes/parámetro) RET 8 retorno de un procedimiento FAR con 2 parámetros de direcciones (8 parámetros x 4 bytes/parámetro) :2 Tipos de operandos, codificación y ejemplos: zil Procedimiento Valor Codificación Ejemplos NEAR no I 100001 I RET NEAR si I 1000010 | valor RET 4 FAR no I l00l0l I RET FAR si 11001010 | valor RET 8 ROL Instrucción: ROL - Rotar a la izquierda (ROtote Left). Formato: ROL destino.contador Descripción: Rotar a la izquierda los bits del operando destino el número de bits especificado en el segundo operando. Si el número de bits a desplazar es l, se puede especificar directamente. Si es mayor que l, su valor debe cargarse en CL y especificar CL como segundo operando. Lógica: temP : contador hacer mientras temp ¡ 0 CF: bit superior de destino destino : destino x2 + CF temP : temP- I si contador: I si bit superior de destino * CF OF: I en caso contrario OF:0 en caso contrario OF queda indefinida Banderas: OF, DF, IF, TF, SF, ZF, AF, PF, CF X-X Ejemplo: MOV CL,z ; rotar 2 bits ; AL : 1100 l l00b, CF : 0 ROL AL,CL ; AL : 001I 001lb, CF : I Cuentu Antes Después I AL: 1100 I100b, cF : 0 AL: l00l 1001b, cF: I AL : l00l l00lb, CF: AL : 001I 001lb, CF : 2 Tipos de operandos, codificación y ejemplos: Destino Contador Codificación Ejemplos reg reg I l0l00vw I mod 010 r/m ROL BL,CL ROL BX,CL 265 val ROL BL, I ROL BX,I ROL MEM BYTE,CL ROL MEM-PAL,CL ROL MEM BYTE,I ROL MEM PAL,I 266 ROR Instrucción: ROR - Rotar a la derecha (ROtote Right). Formato: ROR destino.contador Descripción: Rotar a la derecha los bits del operando destino el número de bits especificado en el segundo operando. Si el número de bits a desplazar es 1, se puede especificar directamente. Si es mayor que I, su valor debe cargarse en CL y especificar CL como segundo operando. Lógica: temP : contador hacer mientras temp f 0 CF: bit inferior de destino destino : destino/2 + temp_cf bit superior de destino : CF temP : temP- I si contador: 1 si bit superior de destino É bit anterior de destino I oF: en caso contrario OF:0 en caso contrario OF queda indefinida Banderas: OF, DF, IF, TF, SF, ZF, AF, PF, CF X-X Ejemplo: MOV CL,z ; rotar 2 bits 1100 I100b, CF ; AL : :0 ROR AL,CL ; AL:0011 001lb, CF:0 Cuenta Antes Después I AL : 1100 l l00b, CF : 0 AL : 0110 0l lob, cF : 0 AL:0ll00ll0b,cF:0 AL : 0011 00l lb. CF : 0 2 Tipos de operandos, codificación y e¡emptos: Destino Contudor Codificación reg reg Ejemplos 110100vw I mod 0l I r/m ROR BL,CI ROR BX.CI 267 ROR BL.I ROR BX.I mem 268 reg ROR MEM-BYTE,CL ROR MEM-PAL.CL val ROR MEM-BYTE,I ROR MEM-PAL.I SAHF Instrucción: SAHF - Almacenar AH en banderas (Store AH in Flags). Formato: SAHF Descripción: Transfiere bits específicos del registro AH a los registros de banderas SF, ZF, AF, PF y CF. SF:bit7 ZF --bit 6 AF: bit 4 PF:bit2 CF:bit0 Lógica: Banderas: SF : ZF : x : AF : x : PF : x : CF : AH (x quiere decir valor indefinido) (: quiere decir concatenado) OF, DF, IF, TF, SF, ZF, AF, PF, CF XXXXX Ejemplo: SAHF : almacena banderas sobre AH Tipos de operandos, codificación y ejemplos: Operandos Codificación Ejemplo l00llil0 SAHF SAL/SHL Instrucción: SAL - Desplazamiento aritmético a la izquierda (Shtft Arithmetic Left). SHL - Desplazamiento lógico a la izquierda (SHtft logical Left). Formato: SAL destino,contador SHL destino.contador Descripción: SHL y SAL realizan la misma operación y son físicamente la misma instrucción. Desplaza a la izquierda los bits del operando destino el número de bits especificado en el segundo operando. Los bits de la derecha se rellenan con cero. Si el número de bits a desplazar es l, se puede especificar directamente. Si es mayor que l, su valor debe cargarse en CL y especificar CL como segun- do operando. Lógica: temP : contador hacer mientras temp ¡ 0 CF: bit superior de destino destino:destinox2 temP : tem'- I si contador: I si bit superior de destino É CF oF: I oF:0 en caso contrario en caso contrario OF queda indefinida Banderas: Ejemplo: OF, DF, IF, TF, SF, ZF, AF, PF, CF x-xx?xx MOV CL,z SAL AL,CL ; desplazar 2 bits 1100 l l00b, CF ; AL : :0 ; AL : 001I 0000b, CF : I Cuenta Antes Después I AL: ll00 ll00b, CF: O AL: l00t 1000b, CF: I AL: l00l 1000b. CF: I AL : 0011 0000b, CF: I 2 Tipos de operandos, codificación y ejemplos: Destino Contador Codificación ll0l00vw I mod l00r/m reg reg Ejemplos SAL BL,CL SAL BX,CL val SAL BL,l SAL BX,I mem reg SAL MEM-BYTE,CL SAL MEM-WORD,CL mem val SAL MEM-BYTE,I SAL MEM-WORD,I 271 SAR Instrucción: SAR - Desplazamiento aritmético a la derecha (Shtft Arithmetic Right). Formato: SAR destino,contador Descripción: Desplaza a la derecha los bits del operando destino el número de bits especificado en el segundo operando. Los bits de la izquierda se rellenan con el bit de signo del primer operando. Si el número de bits a desplazar es l, se puede especificar directamente. Si es mayor que l, su valor debe cargarse en CL y especificar CL como segun- do operando. Lógica: temp - contador hacer mientras temp ¡ 0 CF: bit inferior de destino destino : destino/2 temP : temP- I si contador: I si bit superior de destino f bit anterior de destino OF: I en caso contrario oF:0 en caso contrario OF:0 Banderas: Ejemplo: OF, DF, IF, TF, SF, ZF, AF, PF, CF x--xx?xx MOV CL,2 ; desplazar 2 bits ; AL : I100 1100b, CF : 0 SAR AL,CL ;AL:llll 00llb,CF:0 Cuenta Anles Después I AL : 1100 l l00b, CF : 0 AL: lll00ll0b,cF:0 AL: llll00llb,cF:0 2 AL:lll00llob.cF:0 Tipos de operandos, codificación y ejemplos: Destino reg Contador Codificación Ejemplos reg ll0l00vw I mod lll r/m SAR BL,CL SAR BX,CL 272 val SAR BL,I sAR BX,l ! SAR MEM-BYTE,CL SAR MEM-PAL,CL mem VAI SAR MEM BYTE,I SAR MEM-PAL,I SBB Instrucción: SBB - Restar con acarreo (SuBtract with Borrow). Formato: SBB destino.fuente Descripción: Resta el operando fuente del operando destino. Resta uno si está activada la bandera de acarreo (CF). El resultado se almacena en el operando destino. Los operandos deben ser del mismo tipo (byte o palabra). Lógica: destino : destino-fuente si CF: I destino : destino- I Banderas: OF, DF, IF, TF, SF, ZF, AF, PF, CF X-XXXXX Ejemplo l: ; AL : FEh : 1l I I 1l lOb : BL : l2h:0001 0010b : ------------- ECh: lll0 ll00b : lb ICF:Olh: ; ------------EBh:1110 l0llb : SBB AL.BL : AL: EBh ;BL:l2h Ejemplo 2: ; resta de dos números de 32 bits ; fuente en DX,CX (palabras superior e inferior) ; destino en BX,AX (palabras superior e inferior) SUB AX,CX ; restar palabras inferiores SBB BX,DX ; restar palabras superiores con acarreo Tipos de operandos, codificación y ejemplos: Destino Fuente Codificación reg reg 000ll0dw I mod reg r/m 274 Ejemplos SBB BL,CL SBB BX,CX SBB BL,MEM-BYTE SBB BX,MEM-PAL SBB MEM-BYTE.BL SBB MEM-PAL,BX mem acum val 100000sw I mod 0ll r/m reg mem 000lll0w I val val SBB AL,I2h SBB AX.I234h I val SBB BL,I2h SBB BX,I234h SBB MEM-BYTE,I2h SBB MEM-PAL.I234h SCAS/SCASB/SCASW Instrucción: SCAS - Explorar cadena (SCAn String). SCASB - Explorar cadena de bytes (SCAn Byte String). SCASW - Explorar cadena de palabras (SCAn Word String). Formato: SCAS cadena-destino o SCASB o SCASW Descripción: Sirve para explorar una cadena de bytes o palabras. Para ello realiza la operación: acumulador (AL o AX)-cadena-destino afectando a las banderas, pero sin almacenar el resultado. La cadena destino está direccionada por DI en el segmento extra, o sea, ES:[DI]. Es decir, que se realiza la operación: acumulador (AL o AX)-ES:[DI] Actualiza el registro DI para que apunte al siguiente elemento de la cadena: o Si los operandos son de tipo byte, la resta es a nivel byte (con AL) y el registro DI cambia una unidad. o Si los operandos son de tipo palabra, la resta es a nivel palabra (con AX) y el registro DI cambia dos unidades. Si la bandera de dirección es cero (DF:0), ambos SI y DI se incrementan. Si DF: l, ambos se decrementan (véanse las instrucciones CLD y STD). En la instrucción SCASB se realiza la resta entre bytes AL-ES:[DI]. En la instrucción SCASW se realiza la resta entre palabras AX-ES:[DI]. El operando especificado en SCAS lo utiliza el ensamblador únicamente para verificar el tipo (byte o palabra) y para ver si se ha especificado un re- gistro de segmento. SCAS realiza la operación sin usar realmente el operando de la instrucción. 276 Se pueden utilizar los prefijos REPE (REPZ) o REPNE (REPNZ). Se apli- can para realizar una búsqueda de un elemento de la cadena que cumpla alguna condición determinada. El número de elementos a explorar se especifica en el registro CX. Lógica: si cadena-destino es tipo byte AL-ES:[DI] delta : I si cadena-destino es tipo palabra AX-ES:[DI] delta:2 si DF:0 DI: DI + delta en caso contrario Banderas: DI: Dl-delta OF, DF, IF, TF, SF, ZF, AF, PF, CF X-XXXXX Ejemplo: ; buscar en la cadena de 100 bytes llamada DESTINO (del segmento extra) ; un elemento de valor igual a 50. CLD LEA DI,DESTINO MOV CX,IOO MOV AL,50 REPE SCAS DESTINO DF :0 (incrementar DI) DI : desplazamiento de DESTINO CX: 100 (número de elementos) AL : 50 (valor a buscar) explorar cadena ; si se encontró el elemento, DI contiene el desplazamiento del elemento ; siguiente y ZF :0. La última instrucción se puede sustituir por: REPE SCASB ; explorar cadena de bytes Tipos de operandos, codificación y ejemplos: Cadens-destino Codificoción Ejemplos mem8 l0l0l l lw SCAS MEM-BYTE SCASB meml6 SCAS MEM-PAL SCASW 277 SHR Instrucción: SHR - Desplazamiento lógico a la derecha (SHtft logical Right). Formato: SHR destino,contador Desplazar a la derecha los bits del operando destino el número de bits especificado en el segundo operando. Los bits de la izquierda se rellenan con cero. Si el número de bits a desplazar es l, se puede especificar directamente. Si es mayor que I, su valor debe cargarse en CL y especificar CL como segundo operando. temP : contador hacer mientras temp ¡ 0 CF: bit inferior de destino destino : destino/2 temP : temP- I si contador: I si bit superior de destino I bit anterior de destino OF: I en caso contrario OF:0 en caso contrario OF queda indefinida OF, DF, IF, TF, SF, ZF, AF, PF, CF XXX?xX MOV CL,2 ; desplazar 2 bits ;AL:00ll00llb,CF:0 SHR AL,CL ; AL : 0000 I100b, CF : 1 Cuenta Antes Después I AL : 0011 001lb. CF : 0 AL:0001 l00lb. cF: I AL:0001 1001b, CF: AL:0000 1100b, CF: 2 Tipos de operandos, codificación y ejemplos: Destino Contqdor Codificación reg reg ll0l00vw I mod l0l r/m Ejemplos SHR BL,CL SHR BX,CL reg val SHR BL,I SHR BX,I mem reg SHR MEM-BYTE,CL SHR MEM-PAL,CL mem val SHR MEM-BYTE,1 SHR MEM-PAL.I 279 STC Instrucción: STC - Poner bandera de acarreo (SeT Carry flaÜ. Formato: STC Descripción: Pone a I la bandera de acarreo (CF) sin afectar a ninguna otra bandera. Lógica: CF: I Banderas: T' T' 'U, T' T, ':,T, T' i' Ejemplo: STC ; CF: I Tipos de operandos, codificación y ejemplos: Operandos Codificación Ejemplo lllll00l 2ñ sTC STD Instrucción: STD - Poner bandera de dirección (SeT Direction flag). Formato: STD Descripción: Pone a I la bandera de acarreo (DF), por lo que en la ejecución de las instrucciones de manejo de cadenas los registros indices SI y/o DI se autodecrementan de modo automático: o en I si el(los) operando(s) son de tipo byte. . en2 si el(los) operando(s) son de tipo palabra. Lógica: DF:l Banderas: T' T' tr' T, T' t:,T, "_'' ft Ejemplo: STD ; decrementar índices en instrucciones de manejo de cadenas Tipos de operandos, codificación y ejemplos: Operandos Codificoción Ejemplo lil[Oll sTD STI Instrucción: STI - Poner bandera de interrupciones (SeT Interrupt flag). Formato: STI Descripción: Pone a I la bandera de activación de interrupciones (IF) y activa las interrupciones enmascarables (las que aparecen sobre la linea INTR del procesador). Una interrupción pendiente no será reconocida hasta que no se haya ejecutado la instrucción que sigue a STI. Lógica: IF: I Banderas: T' T' lt' T' T' t:' T' T' g Ejemplo: STI ; activar interrupciones enmascarables Tipos de operandos, codificación y ejemplos: Operandos Codificación EiemPlo 1l1l l0l1 w. sTI STOS/STOSB/STOSW Instrucción: STOS - Almacenar cadena (STOre String). STOSB - Almacenar cadena de bytes (STOre Byte String). STOSW - Almacenar cadena de palabras (STOre Word String). Formato: STOS cadena-destino o STOSB o STOSW Descripción: Transfiere un byte o una palabra desde el registro acumulador AL o AX al operando destino (direccionado por ES:DI). Actualiza el registro DI para que apunte al siguiente elemento de la cadena a almacenar: ¡ Si el operando es de tipo byte, se transfiere un byte y el registro DI cambia una unidad. ¡ Si el operando es de tipo palabra, se transfiere una palabra y el registro DI cambia dos unidades. Si la bandera de dirección es cero (DF:0), DI se incrementa. Si DF: l, se decrementa (véanse las instrucciones CLD y STD). En la instrucción STOSB se transfiere el registro AL al byte ES:[DI]. DI se actualiza en una unidad. En Ia instrucción STOSW se transfiere el registro AX a la palabra ES:[DIl. DI se actualiza en una unidad. El operando especificado en STOS lo utiliza el ensamblador únicamente para verificar el tipo (byte o palabra) y para ver si se ha especificado un registro de segmento. STOS mueve realmente el registro AL o AX a ES:[DI], sin usar realmente el operando de la instrucción. Cuando se usa con REP, se puede"rellenar una cadena con un valor determinado, especificándose el número de elementos de la cadena en el registro CX. Lógica: si cadena-destino es tipo byte cadena-destino : AL delta: I N si cadena destino es tipo palabra cadena_destino : AX delta:2 si DF :0 DI: DI + delta en caso contrario DI: Dl-delta Banderas: T, T, tu, T, T, t:, T, T, T Ejemplo l: CLD ; DF :0 (incrementar DI) LEA DI,DESTINO ; DI : desplazamiento de DESTINO STOS DESTINO ; DESTINO : AL O AX Si DESTINO es de tipo byte, la última instrucción se puede sustituir por: STOSB ; AL : ES:[DII, DI : DI + I Si DESTINO es de tipo palabra, la última instrucción se puede sustituir por: STOSW Ejemplo 2: ; AX : ES:[DI], D[ : DI + 2 ; rellenar los 100 bytes de la cadena DESTINO con blancos CLD ; DF :0 (incrementar DI) LEA DI,DESTINO ; DI : desplazamiento de DESTINO MOV CX,l00 ;CX : 100 (número de elementos) MOV AL,' ' ;AL : carácter blanco REP STOSB : rellenar la cadena Tipos de operandos, codificación y ejemplos: Cadena-destino Codificación Ejemplos mem l0l0l0lw STOS MEM-BYTE STOSB STOS MEM-PAL STOSW M SUB Instrucción: SUB - Restar (SUBtrqct). Formato: SUB destino,fuente Descripción: Resta el operando fuente del operando destino. El resultado se almacena en el operando destino. Los operandos deben ser del mismo tipo (byte o palabra). Lógica: Banderas: destino : destino- fuente. OF, DF, IF, TF, SF, ZF, AF, PF, CF X-XXXXX Ejemplo: ; AL: FEh: llll lllOb ; BL : l2h:0001 0010b : ------------- : ECh:1110 ll00b SUB AL,BL ; AL: ECh ;BL:l2h Tipos de operandos, codificación y ejemplos: Destino Fuente Codificación reg reg 00l0l0dw I mod regr/m Ejemplos reg SUB BL,MEM-BYTE SUB BX,MEM-PAL mem SUB BL,CL SUB BX,CX SUB MEM-BYTE,BL SUB MEM-PAL,BX acum val val 00l0ll0w I val SUB AL,I2h SUB AX,I234h 100000sw I mod 101 r,/m I val SUB BL,l2h SUB BX,1234h mem val SUB MEM-BYTE,12h SUB MEM -PAL,I234í TEST Instrucción: TEST - Test/Comparación lógica gESr). Formato: TEST destino,fuente Descripción: Operación "y lógica" a nivel de bit entre los dos operandos. El resultado no se almacena en destino. Esta instrucción es equivalente a AND, pero sin guardar el resultado en destino. Tras esta instrucción se pueden consultar las banderas mediante una instrucción de bifurcación condicional. La tabla de la operación AND (para las cuatro combinaciones posibles de bits es): 0 0-0 0l-0 I 0-0 I l-l Lógica: destino "y lógico" fuente Se actualizan las banderas. CF :0 OF:0 Banderas: OF, DF, IF, TF, SF, ZF, AF, PF, CF 0-xx?x0 Ejemplo: ; AX: FEDCh: llll lll0 1101 1100b ; BX : 1234h:0001 0010 0011 0100b : -----------I 234h:0001 0010 0001 0100b ; TEXT AX,BX ; AX: FEDCh 1234h ; JNZ NOCERO ; bifurca si existe algún bit en el mismo lugar de AX ; y BX que sean ambos I BX: Tipos de operandos, codificación y ejemplos: Destino Fuente Codificoción reg reg 1000010w I mod regr/m ffi Ejemptos TEST BL,CL TEST BX.BX TEST BL,MEM-BYTE TEST BX,MEM-PAL TEST MEM-BYTE,BL TEST MEM-PAL,BX mem acum val 1010100w I val TEST AL,O1h TEST AX,OIO2h reg val 111101lw I mod 000 r/m I val TEST BL.3O TEST BX,30 mem val TEST MEM-BYTE,OIh TEST MEM-PAL,O1O2h n7 WAIT Instrucción: WAIT - Esperar Formato: WAIT Descripción: Esta instrucción, junto con ESC, permiten la comunicación con otros coprocesadores. WAIT sirve para poner al procesador en estado de espera, estado que aban- dona cuando se activa la línea TEST. La línea TEST la activa el coprocesador cuando está libre o preparado para ejecución. WAIT chequea la lÍnea TFST a intervalos fijos (cinco intervalos de reloj). Banderas: OF, DF, IF, TF, SF, ZF, AF, PF, CF Ejemplo: WAIT ; esperar a que el coprocesador esté disponible. ESC 2Ih,TABLA ; pasar información al coprocesador Tipos de operandos, codificación y ejemplos: Operandos Codificación Ejemplo l00l l0l I wArr N XCHG Instrucción: XCHG - Intercambiar (eXCHonGe). Formato: XCHG destino.fuente Descripción: Intercambia el contenido entre los dos operandos (tipo byte o palabra). No puede utilizarse registros de segmento como operandos. Lógica: temp : destino : fuente fuente : temp destino Banderas: T'T'tr' T, T' t:,T' T' 3 AX: 1234h Ejemplo: BX :5678h XCHG AX,BX AX:5678h BX : 1234h Tipos de operandos, codificación y ejemplos: Destino Fuente Codificación Ejemplos reg reg 100001lw I mod regr/m XCHG BL,CL XCHG BX,CX reg mem XCHG BL,MEM-BYTE XCHG BX,MEM-PAL mem reg XCHG MEM-BYTE,BL XCHG MEM-PAL,BX reg acum acum reg 10010 reg XCHG AL,I2b XCHG AX,I234í XCHG AL,BL XCHG AX.BX 28ff l XLAT Instrucción: XLAT - Traducir (Translote). Formato: XLAT tabla fuente Descripción: XLAT realiza un posicionamiento sobre una tabla de bytes para obtener el valor correspondiente a un índice. El valor de AL se usa como índice (desplazamiento) sobre la tabla. El valor correspondiente se carga sobre el propio AL. Se supone que el registro BX apunta al comienzo de la tabla. La longitud máxima de la tabla es de 256 bytes. El primer byte de la tabla tiene desplazamiento cero. La tabla debe ser tipo by.te. Lógica: AL : byte direccionado por (BX + AL). Banderas: T, T, tt, T, T, ,:, T, T, g Ejemplo: TABLA DB 1,56,12,43,76,84 MOV BX,OFFSET TABLA MOV AL.4 XLAT TABLA definición TABLA BX : desplazamiento de TABLA recuperar el byte 5 de TABLA AL:76 Esto es equivalente a: MOV AL,TABLA[41 Tipos de operandos, codificación y ejemplos: Fuente Codfficación Ejemplo I IOIOI I I XLAT MEM-BYTE 290 XOR Instrucción: XOR-O lógico exclusivo (logicol eXclusive OR). Formato: XOR destino,fuente Descripción: Operación "o lógico exclusivo" a nivel de bit entre los dos operandos. El resultado no almacena en destino. La tabla de la operación XOR (para las cuatro combinaciones posibles de bits) es: Lógica: 0 0-0 0l-l 10-1 I l-0 destino : destino "o lósico exclusivo" fuente CF :0 OF:0 Ejemplo: OF, DF, IF, TF, SF, ZF, AF, PF, CF 0xx?xO AX: FEDCh: 11ll lll0 ll0l ll00b BX : I 3 4h:0001 0010 00ll 0100b ECD8h: lll0 ll00 l1l0 1000b XOR AX,BX ; AX: ECD8h : BX : 1234h Tipos de operandos, codificación y ejemplos: Destino Fuente Codificación Ejemplos reg reg XOR BL,CL XOR BX,CX reg mem mem reg 001100dw I mod regr/m XOR BL,MEM-BYTE XOR BX,MEM-PAL XOR MEM-BYTE,BL XOR MEM-PAL,BX N1 acum val 00ll0l0w I val reg val 1000000w I mod ll0rlm I val XOR BL,3O XOR BX,3O mem val XOR AL,OIh xoR AX.OI02h XOR MEM-BYTE.OIh XOR MEM-PAL.OIO2h Parte fl Aplicaciones en el entorno MS DOS 12 Arqu¡tectura del IBM PC El IBM PC se compone básicamente de: ¡ La CPU (Unidad Central de Proceso). o La memoria. o Los controladores auxiliares. Los componentes más importantes se encuentran en la placa base (System Board). Otros se encuentran en las placas de expansión, que se conectan ala placa base. En la placa base se encuentra el microprocesador principal (8088/8086), con al menos 64 Kb, los programas en ROM (BASIC, BIOS) y otros elementos. La CPU Es el microprocesador principal del ordenador (8088/8086). Controla la operación básica del IBM PC enviando y recibiendo señales de control, direcciones de memoria y datos de una parte a otra del ordenador a través de un canal de comunicación llamado bus. A lo largo del bus se encuentran los puertos (ports) de entrada/salida que conectan la memoria y los controladores auxiliares con el bus. Los datos pasan por estos puertos de ffi entrada/salida mientras viajan a,/desde la CPU a otras partes del ordenador. Dentro de la CPU existen, como hemos visto, una serie de registros internos que forman un área de trabajo para almacenamiento temporal de datos, direcciones de memoria y banderas (fla*| de estado y de control del procesador. La memoria La constituyen una serie de chips individuales que sirven para almacenar la información. El IBM PC viene con dos tipos: memoria ROM (de sólo lectura) y RAM (de lectura/escritura). En la placa base hay capacidad para 256 Kb y las expansiones se hacen a través de las ranuras (slots) de expansión. El 8088/8086 puede direccionar hasta I Mb. Cada byte tiene una dirección de 20 bits. Este espacio se divide en 16 bloques de 64 Kb cada uno (16x64 Kb: Mb). Cada bloque de 64 Kb se identifica por el primer I dígito hexadecimal. Cada bloque tiene asignado un uso diferente: Bloque Direcciones (hex.) Memoriq Uso 0a9 AvB CaF 00000 a 9FFFF 40000 a BFFFF C0000 a FFFFF Total 640 Kb 128 Kb 256 Kb memoria RAM memoria de pantalla memoria ROM 1024 Kb:1Mb Los controladores aux¡liares El microprocesador principal no puede realizar todo el trabajo del ordenador. Se vale de otros procesadores para realizar ciertas funciones de control, como, por ejemplo: el control del flujo de la información entre el procesador principal y los dispositivos externos conectados, entre los propios controladores, etc. Muchos de estos chips son programables. En el Manual de Referencia Técnica se dan detalles sobre cómo programar estos controladores. Esta programación directa se realiza mediante las instrucciones IN y OUT. o El controlador de interrupciones (8259). Supervisa las interrupciones, es decir, las señales que se envían a la CPU por el hardware. Intercepta estas señales, determina su importancia en relación con otras señales que recibe y emite finalmente una interrupción a la CPU. Cuando la CPU recibe la señal de interrupción, ejecuta un programa específico asociado con el dispositivo. 296 Este controlador puede manejar hasta ocho peticiones de interrupción al mismo tiempo. El controlador DMA (8237A). La operación DMA (Direct Memory Access) consiste en leerlescribir de/en un dispositivo y la memoria sin la intervención de la CPU. Este controlador está principalmente orientado a la unidad de disco. El oscilador (8284A). Suministra la señal de reloj que se necesita para dirigir a la CPU y a los periféricos. Su frecuencia base es de 14,31818 MHz. El bus interno y el temporizador (8253) utilizan una frecuencia de 1,193 MHz, una duodécima parte de la frecuencia base. El PPI (8255 Programmable Peripherical Interface). Se usa para conectar alguno de los periféricos al bus. La información que se envía a/desde estos dispositivos (como el altavoz) viaja a través de puertos de entrada/salida via este chip. El temporizador (8253). Es un controlador que obtiene la señal del oscilador y que se usa prin- cipalmente para llevar un contador de tiempos y para general sonido por el altavoz. El controlador de pantalla (6845). Está situado en la placa de expansión conocida como adaptador de pantalla. El controlador de diskette (FD765). Supervisa y controla la operación de la unidad de diskette. 2St7 13 Uso de los recursos del sistema Los recursos del sistema se utilizan a través de un conjunto de rutinas que realizan una serie de funciones. :1T:, " ::: ;:;:::;'*, y,,, * I s Son rutinas basicas de entrada/salida, como: leer una tecla, escribir un carácter por pantalla, acceder a un sector del disco, etc. , DOS (Disk Operating SYstem). Son las rutinás del sistema operativo que facilitan el desarrollo de aplicaciones. En último término invocan a las rutinas elementales BIOS. La memor¡a del sistema (espacio direcc¡onable) El espacio direccionable por el 8088/8086 es de I Mb (que corresponde a 5 caracteres hexadecimales o 20 bits): I Mb : 1024 Kb: 165 = 2'z0 (00000h a FFFFFh). El mapa del espacio direccionable es el siguiente: 2% Dirección (Kb) Longitud (Kb) 0 0.12s 0.r25 0.125 0.25 0.5 0.25 0.5 I 0.25 0.25 62.5 |.25 1.5 64 t92 256 384 640 704 768 960 976 64 64 192 984 32 t0l6 8 l6 8 Direcciones (hex.) 7F 080- FF 100 IFF 200 3FF 400 4FF 5FF 500 600 - FFFF 10000 - 2FFFF 30000 - 9FFFF AOOOO BOOOO COOOO - AFFFF - BFFFF - EFFFF FOOOO. F3FFF F4OOO - F5FFF F6OOO - FDFFF FEOOO - FFFFF Contenido Vectores interrupción BIOS Vectores interrupción DOS Vectores interrupción usuario Vectores interrupción BASIC Area de datos del BIOS Area de datos del BASIC y DOS Memoria del usuario Area de expansión de la memoria Area de expansión de la memoria Memoria de expansión pantalla Area de memoria de pantalla Area de ROM: expansión Area de ROM reservada Area de ROM del usuario Area de ROM: BASIC Area de ROM: BIOS Observaciones: o Las posiciones más bajas (1 Kb - 000h a 3FFh) contienen los vectores de interrupción. r Las 640 Kb primeras corresponden a la máxima memoria RAM soportada. o El área de memoria ROM está situada en las posiciones superiores del espacio direccionable. ¡ El área de datos del BIOS es una zona reservadapara uso del BIOS, pero un programa de usuario podría inspeccionarlo y cambiarlo. Esta área se. inicializa en el arranque del sistema. ¡ Dentro del área de datos del BIOS (400h a 4FFh) existe lo que se llama el área de comunicaciones entre aplicaciones. Son l6 bytes (direcciones 4F0h a 4FFh) que se usan para almacenar información que comparten varios programas. Es conveniente incluir algún tipo de identificación para verificar que esta área no ha sido destruida por ningún otro programa. o El área de memoria de pantalla se divide en dos mitades: la que comienza en B0000h (32 Kb) y la que comienza en B8000h (32 Kb). El adaptador monocromo sólo usa 4 Kb comenzando en B0000h (no usa los 24 Kb restantes). El adaptador de color /gráficos usa 16 Kb comenzando en B8000h (no usa los 16 Kb restantes). o La memoria de expansión de la pantalla la usa el EGA (Enhanced Grophics Adopter) y el Adaptador Profesional de Gráficos. 299 Las interrupciones Existen 256 interrupciones posibles (0 a 255: FFh). Cada vector de interrupción ocupa una doble palabra y contiene la dirección de la rutina de servicio asociada a esa interrupción en la forma: desplazamiento I segmento Por ejemplo, si un vector de interrupción tiene segmento = 1234h y : 5678h, el vector de interrupción contendría el valor correspondiente a la definición: desplazamiento DD 12345678h ;doble palabra Y, como sabemos, este valor se almacenará como 7856 34I2h, es decir, la primera palabra corresponde al desplazamiento y la segunda al segmento. Los tipos de interrupciones son los siguientes: Nro. (decimal) 0 3l 32 64 128 63 127 255 Nro. (hex.) Tipo 0- lF BIOS 0h - 7Fh DOS 80h usuario 100h - lFFh BASIC 200h - 3FFh 20-3F 40-7F 80-FF Dirección vectores - FFh La dirección del vector de interrupción correspondiente a la interrupción n es 4(n-l), puesto que cada vector de interrupción ocupa 4 bytes. Gambio de un vector de interrupción Un vector de interrupción (al residir en RAM) puede modificarse para que apunte a una rutina de usuario. Existen tres métodos: l. Método de los dos MOV. En este método se utilizan dos instrucciones MOV para insertar la dirección de la nueva rutina de servicio en el vector de interrupción. Previamente hay que inhibir las interrupciones (excepto la ño enmascarable, que actúa en situaciones graves y urgentes). Después de las instrucciones de mover hay que volver a activar las interrupciones. DESPLA EQU 4x(NINT-l) XOR AX,AX 3m desplazamiento correspondiente a la interrupción NINT AX__O MOV ES,AX CLI ; ES : O ; inhibir las interru pciones MOV ES:DESPLA,OFFSET RUTINA mover desplazamiento MOV ES:DESPLA + 2.SEG RUTINA mover seg- STI mento las interrupciones activar ; 2. Método del MOV encadenodo. Este método se utiliza para eliminar el pequeño riesgo de que actúe entre los dos MOV la interrupción no enmascarable. Esto se logra sustituyendo las dos instrucciones por una sola, que es un MOVS (MOV encadenado) con repetición. DESPLA MOC 4*(NINT-1) ; desplazamiento correspondiente ; a la interrupción NINT ; DI : O MOV ES,DI ; ES : O MOC DI,DESPLA ; DI: desplazamiento en XOR DI,DI LEA sI,DIREC ; ¡"-f;:$llzamiento de DIREC ; CX:2 palabras CLD ; dirección hacia adelante CLI ; inhibir las interrupciones REP MOVSW ; mover las dos palabras STI ; activar las interrupciones MOV CX,2 Suponiendo que, en el segmento de datos, esté definido: DIREC DD RUTINA ; dirección completa de RUTINA 3. Otro método es mediante la interrupción DOS 21h (función 25h). Hace que la aplicación sea independiente de la versión del sistema operativo. PUSH DS MOV DS,SEG RUTINA MOV DX,OFFSET RUTINA MOV AL,NINT MOV AH,25h INT zlh POP DS salvar DS mover segmento mover desplazamiento AL: número de la interrupción función: poner vector de interrupción llamar al DOS restaurar DS Las funciones DOS de poner y obtener vector de interrupción son: 301 T2 AH Función 25h Poner vector de interrupción Entrada: AL: número de la interrupción DS:DX = dirección rutina de servicio 35h Obtener vector de interrupción Entrada: AL: número de la interrupción Salida: ES:BX: dirección rutina de servicio 14 lnterrupciones BIOS Corresponden a las interrupciones 00h a lFh. Se dividen en cinco grupos: Grupo Números Tipo I 00h - 07h 08h - OFh lOh - lAh Interrupciones internas del microprocesador 8088/8086 Interrupciones del controlador de interrupciones 8259 Puntos de entrada del BIOS Rutinas del usuario Parámetros del BIOS 2 5 4 5 lBh - lch lDh - lFh Las interrupciones internas del microprocesador 8088/8086 se activan cuando ocurre una condición excepcional (por ejemplo, una división por cero) durante el proceso de las instrucciones. El 8259 es el controlador de interrupciones. Acepta como entrada las señales de petición de interrupciones de diferentes dispositivos del sistema. Tras recibir la petición, este controlador pasa la señal junto con un código identificador al procesador principal (8088/8086). Actualmente los dispositivos conectados al controlador de interrupciones son: el temporizador (8253 timer), el teclado y las unidades de diskettes. Las rutinas del usuario son llamadas por otras rutinas de interrupción. Los parámetros del BIOS no corresponden realmente con rutinas de ser303 vicio, sino que son direcciones que apuntan a tablas de datos para las interrupciones 10h y 13h. Interrupción 00h: División por cero Es una interrupción interna que se activa automáticamente cada vez que el cociente, en una instrucción de dividir (DIV o IDIV), es demasiado grande para poder ser almacenado en un registro (AL o AX). Esta interrupción hace que se emita el mensaje "Divide Overflow" y se devuelva el control al DOS. Interrupción 01h: Ejecución paso a poso Esta interrupción permite ejecutar un programa instrucción por instrucción. Se utiliza para depurar programas con el programa DEBUG del DOS (comando Trace). El DOS inicializa el vector de interrupción con una dirección que contiene una instrucción IRET, es decir, que no hace nada. Interrupción 02h: No enmascarable Las interrupciones pueden ser activadas (permitidas) o desactivadas (inhibidas): o Para activarlas (bandera IF: l): intrucción STI. o Para desactivarlas (bandera IF : 0): instrucción CLI. Todas las interrupciones, excepto ésta, pueden ser inhibidas. Genera el mensaje "Parity Check 1" o "Parity Check 2", inhibe las interrupciones (con CLI) y para el microprocesador (con HLT). Interrupción 03h: Breakpoint Esta interrupción permite que se ejecute un programa hasta que se encuentre un indicador de parar la ejecución. Se utiliza en el programa DEBUG (comando G). Igual que en la interrupción 1, el DOS inicializa el vector correspondiente con una dirección que contiene la instrucción IRET. Interrupción 04h: Overflow (desbordamiento) Esta interrupción se activa mediante la instrucción INTO (interrupción si overflow). 304 Igual que en las interrupciones I y 3, el DOS inicializa el vector correspondiente con una direccién que contiene la instrucción IRET. Interrupción 05 h : Imprimir pont alla (hardcopy) Esta interrupción salva la posición actual del cursor, imprime la información alfanumérica de la pantalla (ala vez que va desplazando el cursor) y restaura el cursor. Esta rutina se ejecuta con las interrupciones permitidas. Esta interrupción hace lo mismo que la tecla PrtSc. Si se pulsa la tecla PrtSc mientras se está imprimiendo, se ignora. La dirección 50h:0 contiene el estado: Valor Significado 0 No se ha invocado la función de imprimir pantalla u operación sin error. 1 FFh Impresión de la pantalla en curso. Error al imprimir. Interrupción 06h: No se uso Interrupción 07h: No se usa Interrupción 08h: Temporizador (8353 timer) El temporizador del sistema emite una interrupción cada 1.193.182/65536 nanosegs., es decir, 18,2 veces por segundo aproximadamente. Cada interrupción se llama "tic", que produce una actualización del contador de tiempos. Este contador se encuentra en una doble palabra en el área de datos del BIOS: . 40h:6Ch :46Ch: palabra inferior. o 40h:6Eh :46Eh : palabra superior. La interrupción 08h (es decir, cada tic) invoca una interrupción lCh. La interrupción lCh apunta a una instrucción IRET. Cambiando el vector de interrupción, se puede apuntar a una rutina del usuario. Interrupción 09h: Teclodo El BIOS activa esta interrupción cada vez que se pulsa -una tecla. Debe considerarse a todos los efectos como una interrupción del sistema. flF Interrupción 0Ah: No se usa Interrupción 0Bh: No se usa Interrupción 0Ch: No se usa (reservado) Interrupción 0Dh: No se usa Interrupción OEh: Diskette Como la número 09h, es una interrupción del sistema que se utiliza para las comunicaciones con las unidades de diskettes. Interrupción 0Fh: No se usa (reservado) Interrupción I0h: Entrqdo/salids de pantalla Según el valor de AH, existen 16 diferentes funciones. Estas funciones son: de establecimiento/interrogación del modo de funcionamiento de la pantalla, de transferencia de caracteres y gráficas. Véanse capítulos "La pantalla y sus modos de funcionamiento", "La pantalla en modo alfanumérico" y "La pantalla en modo gráfico". Interrupción llh: Chequeo del equipo físico Se utiliza para obtener las opciones disponibles en el sistema. Esta información se devuelve en AX (en 16 bits) y es la misma que la que se encuentra en la palabra 41h:0:410h. Bits t5-14 t2 ll- 9 7-6 5-4 Contenido Número de impresoras. Existencia adaptador de juegos (0: no, I : sí) Número de placas RS-232. Número de unidades de disco (si bit 0: l). 00 = 1, 0l:2, l0:3, ll:4. Modo inicial de la pantalla. 00 : no se usa. 01 :40 x 25 Blanco y Negro, Adaptador Color/Gráficos. l0:80 x 25 Blanco y Negro, Adaptador Color/Gráficos. 3-2 0 306 l1 : 80 x 25 Blanco y Negro, Adaptador Monocromo. Memoria RAM en la placa base del sistema. 00 = 16 Kb, 0l = 32Kb, 10 : 48 Kb, 1l :64Kb. | : diskettes,0 : no diskettes. Interrupción I2h: Tamaño de la memorio Determina el número de bloques de 1 Kb de memoria RAM instalados en la placa base. Lo devuelve en AX. No se incluye la memoria de las placas de expansión. Interrupción I 3 h : Diskette Sirven básicamente para acceder a un diskette a nivel de sector o pista. Existen seis funciones diferentes según el valor de AH. Véase capítulo "Acceso a disco". Interrupción l4h: Entrada/solida del puerto serie de comunicaciones Permite transferir y recibir información a través del puerto serie de cornunicaciones asíncronas RS-232. Existen cuatro funciones asociadas a los valores 0 a 3 de AH. Véase capítulo "Comunicaciones serie". Interrupción l5h: Entroda/salida de cassette Interrupción l6h: Entrada/solida de teclado Existen tres funciones distintas asociadas a los valores 0 a 2 de AH. Véase capítulo "El teclado". Interrupción l7h: Entrada/sslida de impresora Permite la comunicación con una de las tres posibles impresoras del sistema. Hay tres funciones, según el valor de AH (0 a 2). Véase capítulo "La impresora en modo alfanumérico". \ Interrupción I8h: Llamqdq al BASIC de cassette Interrupción I9h: Restourar el sistema Si está disponible un disco en el sistema, se lee el sector I de la pista 0 sobre el árbol boot (0:7C00h7 y se transfiere el control a esta dirección. Si no está disponible el disco, el control se transfiere al BASIC. WT Interrupción lAh: Contador del temporizador (timer) Sirve para poner/leer el contador del temporizador, según el valor de AH. La interrupción interna 08h es la que mantiene actualizado el contador. AH Función 0 Leer el contador. Salida: CX : Palabra inferior del contador. DX: Palabra superior del contador. AL = Indica si han transcurrido o no 24 horas desde la últimavez que se leyó el contador. 0:no, l:sí Poner el contador con un valor. Entrada: CX : Palabra inferior del contador. DX = Palabra superior del contador. Interrupción IBh:: Break de teclodo Se invoca cuando se pulsa Ctrl-Break. Inicialmente apunta a IRET, pero el DOS actualiza el vector para que apunte a la misma rutina que la interrupción 23h del DOS. Interrupción ICh: "Tic" del temporizador Es invocada por la interrupción 08h. Inicialmente apunta a IRET. Hay que cambiar el vector para que apunte a una rutina de usuario, que ejecuta- rá cada tic del temporizador. Hay muchas aplicaciones posibles que podrían hacer uso de esta interrupción. Por ejemplo, se podría escribir en pantalla la hora, chequear periódicamente algún dispositivo, mantener un contador interno para realizar algo cuando alcance cierto valor, etc. Interrupción lDh: Iniciación video. Tabla de datos para la interrupción l0h. Interrupción lEh: Parómetros diskette. Tabla de datos para la interrupción l3h. Interrupción lFh: No se usa (reservado) 308 15 iones DOS Corresponden a las interrupciones 20h a 3Fh. Son las siguientes: Nro. Descripción 20h Terminar programa. 2th Petición de función. 22h Dirección de terminación. Especifica la dirección a donde se bifurcará cuando se termine el programa. Esta dirección se copia sobre el PSP. 23h Dirección de salida por Ctrl-Break. Véase capítulo "El teclado". 24h Manejador de error crítico. 25h Lectura de disco absoluta. Véase capítulo "Acceso a disco". 26h Grabación en disco absoluta. Véase capítulo "Acceso a disco". 27h Terminar, pero quedar residente. Véase capítulo "Programas residentes". i:' No se usa (reservada). 3Fh No se usa (reservada). Las funciones DOS Corresponden a la interrupción 2lh. Cada función se distingue por un valor de AH. Las rutinas que se ejecutan sirven para lectura de teclado, salida por pantalla e impresora, gestión de ficheros, gestión de la memoria, etcétera. Estas funciones se agrupan en: Volores de AH (hex.) Tipo de función 0 al2 Entrada/salida de carácter 2Aa2E Gestión de ficheros Funciones no asociadas a dispositivos Gestión de ficheros Funciones no asociadas a dispositivos 13 a24 25 a26 27 a29 2F a38 39 a3B 3C a46 Otras funciones Gestión de directorios Gestión de ficheros Las funciones de la 2Fh en adelante corresponden a las nuevas funciones añadidas a partir del DOS 2.0. Las interrupciones y funciones DOS se describen en los capítulos siguientes. 310 16 El PSP, Gomienzo y terminación de un programa Antes de que el procesador de comandos (COMMAND.COM) del DOS pase el control al programa, construye un bloque de 256: l00h bytes a par- tir de la primera posición de memoria disponible. Esta área se llama el Prefijo de Segmento de Programa (Program Segment Prefix, PSP) y contiene campos como la dirección de retorno al DOS cuando acabe de ejecutarse el programa, la dirección del código si se pulsa Ctrl-Break, la dirección de la rutina del tratamiento de errores críticos, la cantidad de memoria dispo- nible para el programa y los parámetros del programa. También crea dos FCB sin abrir correspondientes a los dos nombres de ficheros que se entraron como parámetros. El FCB (Bloque de Control de Fichero) se explica en el capítulo "Acceso a ficheros". La estructura del PSP es: Campo 0h 2h 2h 2h Instrucción INT 20h. Tamaño de la memoria disponible para el programa (en párrafos). 4h 5h lh )n Reservado. Llamada al despachador (dispotcherl de trabajos. Ah 4h Eh 4h 4h Dirección de terminación (normalmente apunta al COMMAND.COM). Dirección si Ctrl-Break. Dirección si error crítico. t2h 31f Desp. Longitud l6h l6h zch Campo Usado por el DOS. Segmento del entorno (environment). Area de trabajo del DOS. 2h zEh zBh 5Ch 6Ch l0h l4h 80h I 8lh 7Fh FCB sin abrir el parámetro l. FCB sin abrir el parámetro 2. Longitud de los parámetros. Inicialmente es la DTA (Disk Transfer Area). Parámetros. l00h Cuando el programa toma el control: o DS y ES apuntan al PSP. ¡ El registro AL contiene un código que indica si es correcta o no la unidad correspondiente al primer nombre de fichero. Un valor cero indica que es correcto. ¡ El registro AH, lo mismo para el segundo nombre de fichero. . El DTA (Disk Tronsfer Area) apunta al desplazamiento 80h del PSP. Este es el DTA por defecto. El DTA (Area de Transferencia de Disco) se explica en el capítulo "Acceso a ficheros". En los programas tipo COM: : ¡ CS y SS apuntan al PSP. . IP : l00h (el byte siguiente al PSP), es decir, que la p¡imera instrucción del programa sigue al PSP. o SP se inicializa con la dirección más alta dentro del segmento del PSP. En los programas tipo EXE: ¡ CS e IP se inicializan con los valores especificados por el montador (LINK), es decir, los valores especificados en la sentencia END o el valor cero si no se especificó ningún valor. ¡ El registro SS apunta al segmento de pila (stack). ¡ SP se inicializa con la dirección más alta dentro del segmento de pila más 100h, es decir, se reserva una pila de 100h bytes. Los dos primeros bytes del PSP contienen el código correspondiente al código de la instrucción INT 20h. Es por ello que los programas empiezan siempre con: PUSH DS ; poner DS en la pila SUB AX,AX ; AX : PUSH AX ; poner AX en la pila O 312 Es decir, sobre la pila se sitúa la dirección DS:O, o sea, el comienzo del PSP. Al acabar el programa, con RET ; volver al DOS se recupera la dirección y se bifurca a ella, es decir, al comienzo del PSP. Entonces se ejecuta la instrucción INT 20h, que devuelve el control al DOS. La única manera de acabar un programa EXE es ejecutar la instrucción INT 20h con CS apuntando al PSP. En los programas COM, como CS apunta al PSP, es posible acabar directamente mediante INT 20h. Otras maneras de acabar un programa son: o Mediante la función DOS 00h (interrupción 2lh), que es idéntica a INT 2Oh. o Mediante la función DOS 4Ch (interrupción 2lh). Esta función (terminar proceso) permite devolver un código de retorno en AL. Además es independiente del valor de CS. Desde el punto de vista del programador, los campos más importantes' son los asociados a los parámetros: o Desplazamiento 80h: contiene el número de caracteres de los parámetros. Por ejemplo, el comando EJEMPLO XXX pondría el valor 4 (el blanco y las tres equis) en este campo. o Desplazamiento 8lh: contiene los caracteres de los parámetros. En el ejemplo, el blanco y las tres equis. . Despiazamiento 5Ch y 6Ch: contienen las FCB, sin abrir, de los nombres de ficheros especificados como parámetros. Es muy corriente el que uno o dos parámetros sean nombres de ficheros. Esto sucede en muchos comandos DOS, como TYPE, COPY, etcétera. Es por ello que el DOS intenta siempre construir estas FCB a partir de los dos primeros parámetros, ahorrando de esta forma al programador un trabajo considerable. Por ejemplo, el compndo EJEMPLO FICHI.DAT B:FICH2.DAT XXX produciría: . En 80h, 26 (número de caracteres). . A partir de 8lh, el carácter blanco y FICHI.DAT B:FICH2.DAT XXX. . A partir de 5Ch, el FCB sin abrir de FICH1.DAT con la unidad por defecto. . A partir de 6Ch, el FCB sin abrir de FICH2.DAT con la unidad B. 313 17 Herramientas de programación Los programas que se necesitan en el desarrollo de aplicaciones son: El editor Es el programa con el que construimos los módulos fuentes. Es preferi- ble utilizar un editor de pantalla completa (personal editor, profesional, editor, etc.). Los ficheros ensamblador deben ser tipo ASM. El programa ensamblador (MASMI Es el programa que convierte el código fuente en el código objeto, es decir, en las instrucciones de lenguaje máquina. Con ello se evita la utilización de códigos y direcciones absolutas. Entrada: módulo.ASM : módulo fuente. Salida: módulo.OBJ : módulo objeto. módulo.LST : listado del módulo ensamblador. módulo.CRF: listado de las referencias cruzadas. Comando : MASM fuente, obj eto,listado,referencias-cruzadas. 314 El listado contiene el código de máquina asociado a cada instrucción, posición en que se encuentra y una tabla en la que se indica la dirección que corresponde a cada nombre simbólico. Este listado sirve para facilitar el seguimiento del programa durante la fase de prueba. El listado de referencias cruzadas contiene información referente a cada símbolo y las sentencias donde se hace referencia al mismo. El programa ensamblador tiene dos pasos: Paso 1. Se recorre el programa fuente. Por cada instrucción, incre' rhenta el contador, la instrucción. A continuación, según el código de comprueba si tiene o no etiqueta. Si la tiene, coloca el símbolo de la etiqueta y su dirección en la tabla de símbolos. Después compara el símbolo del código de operación con una tabla de símbolos posibles. Si es válido, lo sustituye por el código real. Si no es válido, emite un mensaje de error. A continuación comprueba la sintaxis. I Paso 2. Se recorre otra vez las instrucciones del módulo fuente, reemplazando los símbolos por sus direcciones reales, tomadas de la tabla. Ef montador (LINK) Es el programa que básicamente realiza dos tareas: o Combina varios módulos objetos, realizando las conexiones necesarias entre ellos. o Convierte los módulos objetos en un módulo ejecutable. Entrada: módulo.OBJ[,módulo2.OBJ,...] : módulos objetos. librería.LlB[,librería.LIB,...] = librerías de módulos objetos. Salida: módulo.EXE : módulo ejecutable. módulo.MAP : listado del mapa del módulo ejecutable ge- nerado. Comando: LINK objeto(s),ejecutable,mapa,librería(s). Los objetos y las librerías se especifican separadas mediante el signo tt+tt. El programa EXE2BIN Un fichero tipo EXE (programa ejecutable) no es la imagen exacta del programa tal y como se ejecutará en memoria. Cuando se carga en memoria desde disco, el DOS realiza una serie de operaciones previas: o Crear el PSP (Prefijo de Segmento de Programa). o Inicializar los registros. o Indicarle al programa dónde ha sido cargado. 315 o Calcular el tamaño del módulo ejecutable. ¡ Crear una pila para uso del programa. o Pasar el control. Un fichero COM es una imagen exacta del programa tal y como aparecerá en la memoria del ordenador. Es más compacto que el formato EXE y se carga más rápidamente. Con este fichero el DOS sólo tiene que hacer tres cosas: r Crear el PSP (Prefijo de Segmento de Programa). ¡ Inicializar los registros. ¡ Pasar el control. Para que pueda crearse un fichero COM a partir de un módulo fuente, es necesario: o Que el programa conste de un solo segmento físico, es decir, su longitud debe ser menor que 64 Kb. o Que la primera instrucción ejecutable del programa se encuentre en el desplazamiento 100h :256 respecto al origen del segmento. Esto se logra mediante la directiva ORG l00h tras la sentencia SEGMENT. Entrada: módulo.EXE : módulo ejecutable. Salida: módulo.COM: módulo imagen de memoria. Comando: EXE2BIN módulo.EXE módulo.COM. El gestor de librerías de objetos Una librería de módulos objetos es una colección de objetos reunidos en un solo fichero. Si se indica al montador el nombre de una (o varias) librerías, automáticamente inserta en el módulo ejecutable los módulos objeto que necesita. Con ello se evita tener que especificar todos los módulos objetos necesarios en el comando LINK para poder generar el módulo ejecutable. El programa LIB no es parte integrante del DOS, aunque debería serlo, dada su utilidad. Acompaña a algunos ensambladores y compiladores y forma parte de algunas versiones del DOS no IBM. Por convenio, el nombre de las librerías tienen extensión LIB. Con el programa LIB se pueden realizar las operaciones siguientes: Crear una librería de objetos Añadir un módulo objeto Eliminar un módulo obieto 316 LIB librería + módulo: LIB librería-módulo: Operación Comando Sustituir un módulo obieto LIB librería -módulo + módulo: o LIB librería- + módulo; Extraer un módulo Eliminar un módulo y extraerlo Listar el directorio (en pantalla) Listar el directorio (en fichero) Listar el directorio (en impresora) LIB librería*módulo: LIB librería-xmódulo: LIB librería; LIB librería,fichero; LIB librería.LPTl: Para usar un procedimiento perteneciente a un módulo objeto, es necesario en el módulo llamador: ¡ Invocar al procedimiento con la instrucción CALL. Declarar el procedimiento como externo (con una sentencia EXTRN). Y en el módulo llamado: o Declarar el procedimiento como público (con la sentencia PUBLIC). El programa DEBUG Con las herramientas anteriores se puede crear el módulo ejecutable de un programa, que es el objetivo final: un programa que funciona. Pero es raro que un programa funcione "a la primera". Lo normal es que el programa se meta en un bucle, se quede "colgado" (por bifurcar a una dirección errónea), etc. DEBUG es un programa de utilidad para la depuración de programas, que nos permite realizar una amplia gama de operaciones como: o Examinar la memoria, es decir, el código y los datos, en ASCII y hexadecimal. Examinar los registros y las banderas. Ejecutar el programa paso a paso, es decir, una instrucción cada vez. a Parar la ejecución de un punto determinado del programa. a Desensamblar, es decir, obtener los códigos simbólicos (si existen) correspondientes a una serie de posiciones de memoria. Acceder a disco. a a Ficheros BAT Los siguientes ficheros BAT se aplican a un entorno de desarrollo en el que se utilizan un conjunto de subrutinas, cuyos objetos se incorporan a una librería. Esta librería se utiliza en el montaie de los módulos eiecutables. 317 S.BAT - Ensamblar subrutina e incluir objeto en librería ASM.LIB. P.BAT - Ensamblar módulo fuente principal de un programa y crear módulo objeto. L.BAT - Linkeditar programa (crear módulo ejecutable). Accede a la librería de objetos ASM.LIB. 318 S. BAT : fichero: S.BAT : : Descripción: : Ensamblar subrutina e incluir : obieto en libreria ASM.LIB. ---------echo off if z?1 =: z goto error : goto check error echo *** error: falta no¡nbre de La 5u!¡u!i¡¿ *'r* goto fin : check if exist 81.asm goto ensam goto fin echo *** error: fichero *1.asrn ¡6 syjsls *rr* : ensam nasn &li if not exist *1.obj goto err lib asrn. lib-tL+81 t erase 81.obi echo ... objeto 81 añadido/sustituido en Librería asn.lib goto fin : err echo *** errores en subrutina fuente *** : fin 319 P. BAT : : Fichero: P.BAT : Descripción: : Ensa¡nblar módulo fuente principal de un prograna y crear nódu,lo : objeto. : echo off íf zZI =: z goto error goto check : error echo *** error: falta no¡nbre de1 nódulo fuente **tr goto fin : check if exist *1.asrn goto ensarn echo **'l error: fichero t1.asm no existe *** goto fin : ensam nasm ?1; if exist 8L.obj goto mensa goto fin echo **tt error en programa fuente *** : mensa : 320 echo ... creado fichero *l-.ob"i fin L. BAT i richero: L.aar : Descripción: : Linkeditar prograna (crear nóduLo ejecutable). : Accede a librería de objetos ASM.LIB. : ---------echo off if z*I.-= z qoto error goto check : error echo *** effor: falta nombre del prograna **tt goto fin : check if exist 81,,obj goto link echo *'l* error: no existe fichero *l.obj 't** goto fln :1ink l-ink *l-, 8l-,nul, asm. 1lb if exist *1.exe goto bien echo *'t* error en eI montaje del prograna *1 *** goto fin :bien echo ... creado fichero *1.exe : fin g¿1 18 lnterf az con subruti nas Una subrutina es un módulo que se ensambla por separado y que puede ser invocado desde otro módulo. El objeto generado por la subrutina hay que incluirlo en el proceso de montaje (LINK) de dos maneras posibles: o Directamente. o Automáticamente, si el objeto de la subrutina se ha incluido dentro de una librería de objetos y se especifica el nombre de esta librería en el montaje. La comunicación entre el módulo llamador y el módulo llamado se realiza normalmente mediante parámetros. La llamada a una subrutina con parámetros puede ser de dos tipos: o Llamada tipo FAR (a otro segmento). En este caso la dirección de retorno se compone de CS e IP. ¡ Llamada tipo NEAR (dentro del mismo segmento). En este caso, la dirección de retorno se compone sólo de IP. A su vez, los pará,rnetros pueden ser direcciones o valores. Vamos a estudiar el caso de direcciones, por ser el de más interés. En todos los ejemplos de subrutinas incluidos en este libro: o Los procedimientos son de tipo FAR. o Los parámetros son direcciones completas, es decir, se pasa el segmento y el desplazamiento sobre la pila. 92. Esto permite la posibilidad (con pocos cambios o ninguno) de poder utilizar las subrutinas desde los lenguajes de alto nivel. Pase de parámetros Módulo llamador. Pase de parámetros FAR PUSH DS ; salvar segmento de la variable VARI PUSH AX ; salvar desplazamiento de la variable VARI PUSH DS ; salvar segmento de la variable VAR2 PUSH AX ; salvar desplazamiento de la variable VAR2 LEA AX,VARI ; AX: desplazamiento de la variable VARI LEA AX,VAR2 ; AX: desplazamiento de la variable VAR2 ::: CALL MODULO ; llamada a la subrutina MODULO Módulo llamador. Pase de parámetros NEAR LEA AX,VARI i AX: desplazamiento de la variable VARI PUSH AX ; salvar desplazamiento de la variable VARI LEA AX,VAR2 ; AX: desplazamiento de la variable VAR2 PUSH AX ; salvar desplazamiento de la variable VAR2 ónll MODULO : llamada a la subrutina MODULO Recogida de parámetros Módulo llamado tipo FAR A) Estructuro de la pila En general , para n parámetros: SS:SP* IP (CS:IP es la dirección de retorno) CS Desp. Par. n (desplazamiento parámetro n) w parámetro n) Segm. Par. n (segmento Desp. Par. I (desplazamiento parámetro l) Segm. Par. 1 (segmento parámetro l) Los parámetros se disponen sobre la pila de tal manera que el primer parámetr-o siempre se encuentra en la parte más baja y el último se encuentra junto a la dirección de retorno. B) Recogida de parómetros l. La subrutina lo que hace primero es salvar el registro BP: PUSH BP El registro SP apunta, como siempre, al último elemento. SS:SP * BP IP (CS:IP es la dirección de retorno) CS Desp. Par. n (desplazamiento parámetro n) Segm. Par. n (segmento Desp. Par. 1 (desplazamiento parámetro l) Segm. Par. I (segmento parámetro n) parámetro 1) 2. A continuación, y con el objeto de poder referenciar los parámetros, hace BP = SP: MOV BP,SP El registro BP apunta ahora al último elemento de la pila. n4 SS:BP* BP IP (CS:IP es la dirección de retorno) CS Desp. Par. n (desplazamiento parámetro n) Segm. Par. n (segmento parámetro n) Desp. Par. I (desplazamiento parámetro l) Segm. Par. I (segmento parámetro l) 3. Se accede a los parámetros a través de BP: BP BP BP+2 IP BP +4 CS BP+6 Desp. Par. n (desplazamiento parámetro n) BP+8 Segm. Par. n (segmento parámetro n) Desp. Par. I (desplazamiento parámetro 1) Segm. Par. I (segmento parámetro l) (CS:IP es la dirección de retorno) El desplazamiento del parámetro n se encuentra en SS:IBP + 6] y el segmento en SS:[BP + 8]. Desplazamientoparámetro n : [BP] +6 Segmento parámetron :[BP] +8 Segmento parámetro n-l : [BP] -t 12: [BP] + 8 + 4* I Desplazamiento parámetro n -2 :[BP]*14:[BP]+6+4*2 :[BP]f16:[BP]+8+4*2 S.egmento parámetro n--2 Desplazamiento parámetro n- I :[BP] *10:[BP] +6+4*l Desplazamiento parámetro I Segmento parámetro I :[BP] +6+4*(n-l) :[BPl+8+4x(n-l) En general, para el parámetro i: : [BPl + 6 + 4*(n-i) parárnetro ¡: [BP] -e 3a{x-(n-i) Desplazamiento parámetro i Segmento C) Argumento de RET Es siempre cuatro veces el número de parámetros. Cuatro es la lon- gitud de un parámetro sobre la pila. Módulo llamado tipo NEAR A) Estructura de Ia pila En general, para n parámetros: SS:SP * IP (IP es la dirección de retorno) Desp. Par. n (desplazamiento parámetro n) Desp. Par. I (desplazamiento parámetro l) B) Recogida de porámetros I. PUSH BP SS:SP * BP IP (IP es la dirección de retorno) Desp. Par. n (desplazamiento parámetro n) Desp. Par. I (desplazamiento parámetro l) 2. MOV BP,SP 326 SS:BP (IP ds la dirección de retorno) (desplazamiento parámetro n) (desplazamiento parámetro 1) 3. Se accede a los parámetros a través de BP: BP BP +2 (IP es la dirección de retorno) BP+4 (desplazamiento parámetro n) (desplazamiento parámetro l) n Desplazamiento parámetro = [BP] + 4 Desplazamiento parámetro n-1 [BP] Desplazamiento parámetro n-2 [BPl 1 3 Desplazamientoparámetro : : 16: [BPl +4+2xl : [BPl + 4 + 2*2 : [BP] +4+2*(n-l) I En general, para el parámetro i: Desplazamiento parámetro i : [BP] + 4 + 2*(n-i) C) Argumento de RET Es siempre el doble del número de parámetros. En este caso, la lon- gitud de un parámetro sobre la pila es de 2 b¡es. La direct¡va STRUC y el manejo de parámetros La directiva STRUC es muy útil para el manejo de parámetros. Se utiliza parai n7 . Especificar la estructura de la pila. o Simplificar el acceso a los parámetros. o Simplificar el cálculo del argumento de RET. Módulo llamado FAR A) Estructuro de la pilo PARAMS STRUC DW ? ? DD ? DD ? DD ? DD ? RETORNO DD PN ii ;; Pl PARAMS ENDS ; BP salvado por la subrutina : dirección de retorno ; dirección parámetro N ;dirección parámetro i ; dirección parám etro 2 ;dirección parámetro I B) Recogido de parómetros Puede hacerse con las instrucciones LES o LDS para recuperar la dirección de cada parámetro. Por ejemplo, si el parámetro i es un valor de longitud una palabra: LES SI,[BP].PI ; ES : segmento, SI : desplazamiento ; parámetro i MOV AX,ES:[SI] ; AX: valor del parámetro i Si se quisiera modificar: MOV ES:[SI],AX ; parámetro i: AX C) Argumento de RET Se define el símbolo, que es siempre el mismo, independientemente del número de parámetros: NRET EQU OFFSET Pl - OFFSET RETORNO ; argumento ; de RET Y en la sentencia RET se esPecifica: RET NRET 328 Módulo llamado NEAR A) Estructura de la pila PARAMS STRUC DW? bp salvado por la subrutina RETORNO DW ? PN DW? PI ;; PI dirección de retorno dirección parámetro n DW? DW? DW? dirección parámetro i dirección parámetro 2 dirección parámetro 1 PARAMS ENDS B) Recogida de parámetros Por ejemplo, si el parámetro i es un valor en una palabra: MOV SI,[BP].PI ; SI = desplazamiento parámetro i MOV AX,[SI] ; AX: valor del parámetro i Si se quisiera modificar: MOV [SI],AX ;parámetro i:AX c) Argumento de RET Es igual que para el caso de módulo tipo FAR: NRET EQU OFFSET Pl -OFFSET RETORNO ; argumento : de RET Y en la sentencia RET se especifica: RET NRET w 19 La pantalla y sus modos de funcionamiento La pantalla del IBM PC es un tubo de rayos catódicos (CRT, Cathodic Roy Tube) que es controlada por un chip llanado controlador CRT, que es un procesador Motorola 6845. En la pantalla se representa la información mediante puntos luminosos llamados pixels (picture cells) o pels (picture elements), que se activan o no durante el barrido del haz de electrones (rayos catódicos) por toda la pantalla. Este barrido es horizontal (entre dos líneas sucesivas) y vertical (retroceso desde el final de la última línea al comienzo de la primera). La pantalla puede funcionar en dos modos diferentes: o Modo texto (representa sólo caracteres). o Modo gráfico (dibujos en general). Este modo de funcionamiento depende del adaptador (controlador) de pantalla. El adaptador de pantalla El adaptador de pantalla del IBM PC es una placa que se inserta en una de las ranuras (slots) internas. Conecta el ordenador con el controlador CRT. Este adaptador tiene a su vez: 330 o Memoria RAM para representar la información en pantalla. o Puertos programables. o Un generador de caracteres en ROM. Los dos adaptadores originales de IBM son: o El adaptador monocromo (Monocrome Dkplay and Printer Adapter). r El adaptador de color/gráficos (CGA, Color/Grophics Adapter). Con el adaptador monocromo la pantalla sólo funciona en modo texto. Con el adaptador de color/gráficos la pantalla puede funcionar en ambos modos. El adaptador monocromo suministra además el interfaz paralelo para la impresora. LA MEMORIA RAM DEL ADAPTADOR DE PANTALLA Ambos tipos de adaptadores representan la información en pantalla mediante memoria mapeada (memory mapped), llamada así porque cada dirección de la memoria corresponde a una determinada posición de la pantalla. La memoria (buffer) de la pantalla está situada dentro de la placa, pero forma parte del espacio de direcciones del ordenador. La dirección inicial depende del tipo de adaptador: Adaptador Dirección Longitud Monocromo CGA B000h:0: 80000h B800h:0 = B8000h 16 Kb = 4000h 4 Kb = 1000h Para el CGA esta memoria es la misma, tanto si se trabaja en modo tex- to como si se trabaja en modo gráfico. PUERTOS PROGRAMABLES Un sistema de doble puerto en el adaptador permite el acceso simultáneo a la memoria de pantalla por parte del microprocesador (CPU) y del controlador CRT. Si la CPU modifica un b¡e de la memoria de pantalla mientras el CRT está barriendo la pantalla, puede aparecer un breve efecto de "nieve". Pero si el controlador CRT está en la fase de retorno vertical, entonces este efecto no se produce. Es posible conocer el estado del haz en un momento dado, leyendo de uno de los puertos del adaptador (véase manual de referencia técnica del IBM PC). Í¡:f1 EL FORMATO DE LOS CARACTERES Todos los caracteres que aparecen en pantalla están definidos sobre una matriz de puntos (pixels). Un carácter es una serie de pixels encendidos sobre esta matriz bidimensional. Adaptador Mstriz del cardcter (columnas x filas) Definición del carócter Monocromo CGA 9x14 8x8 7 x9 tx I En el adaptador monocromo hay 8 Kb en ROM para la generación de los 256 caracteres posibles. En el CGA la generación de caracteres en modo texto se realiza también mediante memoria ROM. Pero en modo gráfico: . Los códigos 0 a 127 están en la memoria ROM del BIOS. o Los códieos 128 a 255 están en una tabla RAM. Esta tabla se carsa con el colmando GRAFTABL del DOS. Los caracteres generados mediante estas tablas se llaman raster (barrido). Resolución de la pantalla La resolución es el número de columnas por el número de filas. Cada posición de la pantalla (X,Y) se corresponde con un carácter (modo texto) o un pixel(modo gráfico), siendo X la columna e Y la fila. Las posibles resoluciones son: Modo texto gráfico Tipo de resolución Resolución x 25 llneas x 25 líneas baja alta 40 caracteres 80 caracteres baja 160 columnas x 100 filas 320 columnas x 200 filas 640 columnas x 200 filas media alta En algunos compatibles IBM PC existe la superalta resolución (640 x 400). En este caso, la memoria de pantalla es el doble (32Kb). Las resoluciones soportadas por cada tipo de adaptador son: 3:|2 Adaptador Monocromo CGA Resolución Resolución modo texto modo grdfico alta baja, alta baja, media, alta La resolución 160 x 100 no está soportada por el BIOS, siendo necesario en este caso el uso de la programación directa del procesador de la pantalla. El origen de coordenadas (tanto en modo alfanumérico como en modo gráfico) es la esquina superior izquierda de la pantalla. La primera fila o línea es la cero. La primera columna es la cero también. El sentido positivo para X es de izquierda a derecha. El sentido positivo para Y es de arriba abajo. (0,0) x (rx- 1,0) rx : resolución x ry = resolución y (rx-l,ry-l) (0,ry- 1) El cu rsor El cursor indica la posición activa de la pantalla. En modo texto se puede conocer su posición y modificarse vía BIOS. En modo gráfico no existe un cursor físico sobre la pantalla, pero existe un cursor lógico que puede manipularse también a través del BIOS, siendo normalmente los propios programas los que se crean su propio cursor "visible". Modo de func¡onamiento de la pantalla Se selecciona mediante la función 0 de la interrupción BIOS lOh: Número Modo 0 texto texto texto texto gráfico gráfico gráfico I 2 a J 4 ) 6 Resolución 40 caracteres 40 caracteres 80 caracteres 80 caracteres x 25 líneas x 25 líneas x 25 líneas x 25 líneas 320 columnas x 200 filas 320 columnas x 200 filas 640 columnas x 200 filas Colores Adaptador B/N CGA CGA Monocromo CGA CGA CGA CGA Color B/N Color Color B/N B/N 3trf Como se ve, el adaptador monocromo tiene sólo un modo de funcionamiento (80 x 25 blanco y negro), mientras que el CGA tiene seis posibles (tres alfanuméricos y tres gráficos). Las interrupc¡ones asociadas a la pantalla Número Tipo Desuipción l0h BIOS Funciones varias, según el valor de AH. Funciones varias, según el valor de AH. 2th DOS A continuación se describen todas las funciones BIOS y DOS asociadas a la pantalla. Conceptos tales como página, paleta y atributo se describen en los dos capítulos siguientes. FUNCIONES BIOS CORRESPONDIENTES A LA INTERRUPCION IOh AH Función 00h Establecer modo de la pantalla. Entrada: AL : 0 40x25, blanco y negro, alfanumérica. AL : | 40x25, color, alfanumérica. AL : 2 80 x 25, blanco y negro, alfanumérica. AL : 3 80 x 25, color, alfanumérica. AL : 4 320 x 200, color, gráfica. AL : 5 320x200, blanco y negro, gráfica. AL : 6 640 x 200, blanco y negro, gráfica. Olh Establecer líneas del cursor. Entrada: CH (bits 0-4) : Línea inicial. CH (bits 5-7¡:6' CL (bits 0-4) : Línea final. cL (bits 5-7) :0. 02h Posicionar cursor. Entrada: DH: Fila (0-24). DL : Columna (0-79). BH : Número de la página (0 si modo gráfico). 03h Leer posición del cursor. Entrada: BH : Número de la página (0 si modo gráfico). Salida: DH: Fila (0-24). 334 DL : Columna (0-79). CH (bits 0-4) : Línea inicial. CH (bits 5-7) :6. CL (bits 0-4) : Línea final. CL (bits 5-7) :9. 05h Seleccionar página activa (modo alfanumérico). Entrada: AL : Nueva página. (0-7 para los modos 0 y l). (0-3 para los modos 2y 3). 06h Desplazamiento (scroll) hacia arriba de la página activa. Entrada: AL : Número de líneas. Las líneas de la parte inferior de la ventana se borran. Si AL :0, se borra toda la ventana. CH : Fila esquina superior izquierda. CL : Columna esquina superior izquierda. DH : Fila esquina inferior derecha. DL : Columna esquina inferior derecha. BH : Atributo a usar en la línea en blanco. 07h Desplazamiento (scroll) hacia abajo de la página activa. Entrada: AL : Número de líneas. Las líneas de la parte superior de la ventana se borran. Si AL:0. se borra toda la ventana. CH : Fila esquina superior izquierda. CL : Columna esquina superior izquierda. DH : Fila esquina inferior derecha. DL : Columna esquina inferior derecha' BH : Atributo a usar en la línea en blanco. 08h Leer carácter y atributo de la posición actual del cursor (modo alfanumérico). Entrada: BH : Número de la página. Salida: AL : Carácter leído. AH: Atributo del carácter leido. 09h Escribir carácter y atributo en la posición actual del cursor. Entrada: BH : Número de la página. BL : Atributo del carácter (modo alfanumérico). Color del carácter (modo gráfico). frts CX = Número de caracteres a escribir. AL : Carácter a escribir. 10h Escribir carácter sólo en la posición actual del cursor. Entrada: BH : Número de la página. AL : Carácter a escribir. l lh Establecer paleta de colores (modo gráfico 320 x 200). Entrada: BH : Número del color (0-127). BL = Valor del color. l2h Escribir punto (modo gráfico). Entrada: DX = Número de la fila. CX : Número de la columna. AL : Valor del color. Si el bit 7 de AL es 1, se hace una operación XOR entre el valor del color y el contenido del punto. !3h Leer punto (modo gráfico). Entrada: DX = Número de la fila. CX = Número de la columna. Salida: AL : Punto leído. l4h Escribir carácter en la pantalla (donde esté el cursor) y avanzar el cursor. Entrada: AL : Carácter a escribir. BL : Color del carácter (modo gráfico). BH : Número de la página activa (modo alfanumérico). l5h Leer estado actual de la pantalla. Salida: AL : Modo (ver AH:0). AH: Número de columnas en la pantalla. BH : Número de la página activa. 336 FUNCIONES DOS CORRESPONDIENTES A LA INTERRUPCION 2Ih AH 02h Función Escribir un carácter por pantalla. Entrada: DL : Carácter a escribir. 09h Escribir en pantalla una cadena de caracteres de memoria. La cadena debe terminar con el carácter '$'. Entrada: DS:DX : Dirección cadena de caracteres a escribir. Dibujo de líneas rectas Tanto en modo alfanumérico como en modo gráfico se plantea el problema de trazar una línea recta entre dos puntos dados: o En modo alfanumérico cada punto es un carácter (con su atributo). o En modo gráfico cada punto es un pixel (de un color determinado). La selección de los puntos más adecuados que más se aproximan a la recta teórica se hace mediante un algoritmo. En el apéndice F se describe el fundamento matemático del alsoritmo de Bresenham. Aplicaciones Mocros: VIMDEF - Definir modo de funcionamiento de la pantalla. VIMEST - Obtener el modo de funcionamiento de la pantalla. :xf7 VIMDEF.ASM Macro: VIMDEF. Descripción: Definir modo de funcionamiento de la pantal-l-a. Parámetros: modo = modo pantal-Ia (ent) (1" byte) (núnero, registro, 0 - 40 x 25 al-fanunérica, b]anco y negro l- - 40 x 25 alfanurnérica, color 2 - Ao x 25 alfanumérj-ca, bLanco y negro 3 - 80 x 25 alfanurnérica, color 4 - 32o x 200 gráfica, color 5 - 32O x 200 gráfica, blanco y negro 6 - 640 x 200 gráfica, blanco y negro t ---------vindef macro modo ; saLvar registro afectado push ax recoger parámetro de entrada mov a1 , modo definir ¡nodo de pantalla ,. rnodo mov ah,0 int 10h ; ; restaurar registro afectado pop ax endm st8 funcj.ón: poner modo pantalla Ilamar aL BIos variable) VIMEST.ASM , t.".o, . ; VIMEST. noc¡rin¡iÁn. Obtener e1 modo de funcionamiento de Ia pantalla. i Parámetros: ; modo = modo pantal-l-a (saf) (1 byte) (variabl-e, registro distinto ax o bx). ; 0 - 40 x 25 alfanunérica, blanco y negro ; )- - 40 x 25 alfanunérica, color i 2 - 80 x 25 alfanunérica, blanco y negro ; 3 , - 80 x 25 al-fanunérica, color 4 - 32Q x 200 gráfica, col,or i 5 - 320 x 2O0 gráfica, blanco y negro , 6 - 640 x 200 gráfica, bl-anco y negro ; ; paq = número de ]a página (sa1) (1 byte) (variable, registro distinto de ax o bx). t de ;---------vimest macro modo,pag i salvar registros afectados push ax push bx ; obtener estado pantal-l-a mov ah,15 int 10h ; función: obtener estado pantalla i llamar aI BIos i aI : modo, bh : página activa ; poner parámetros de sal-ida mov modoral ; nodo mov pag,bh ; página activa i restaurar registros afectados pop bx pop ax endm *|9 20 ta pantalla en modo alfanumérico En modo alfanumérico, la unidad de información representable es el carácter. Cada carácter representado en la pantalla corresponde a dos b¡es contiguos de la memoria de pantalla: l. Byte de carácter. 2. Byte de atributo. 76543210 76543210 código carácter I código atributo Dirección par Dirección impar El byte de carácter contiene el código ASCII de dicho carácf"er. El b¡e de atributo define la forma de presentación del carácter. Su configuración general es la siguiente: 7 654 3210 PIRVAIIRVA Fondo Carácter 34{t Descripción Bits Parpadeo (P) del carácter Intensidad (D del carácfer Componente rojo (R) del fondo Componente verde (V) del fondo Componente azul (A) del fondo Componente rojo (R) del carácter Componente verde (V) del carácter Componente azul (A) del carácter En el adaptador monocromo y en el CGA (en modo blanco y negro) sólo tienen sentido (aparte de los bits de intensidad y parpadeo) los atributos sieuientes: Atributo Código Normal (blanco sobre negro) Video inverso Subrayado Invisible (negro) Invisible (blanco) 0000 0lllb:07h 0l1l 0000b:70h 0000 0001b :Olh 0000 0000b :00h 0lll 0lllb=7'7h En el adaptador CGA el número máximo de colores posibles es de 16 (4 bits) para el carácter y de 8 (3 bits) para el fondo. La tabla de posibles colores para un carácter corresponde al esquema llamado IRGB (Intensity, Red, Green, BIue): Número I I R V A 0 0 0 0 Negro 0 0 0 I Azul 0 Verde 0 I I I Azul-Verde (cYan) 4 0 0 0 0 0 I 0 0 Rojo 5 0 0 I Magenta 6 1 0 0 I I I 0 Marrón I I I Blanco 8 I I I I I I I 0 0 0 0 Gris I Azul claro 0 Verde claro 0 I I I 0 I 0 I I I I I Blanco intenso I 2 3 9 l0 ll t2 l3 t4 l5 I 0 0 Color I Azul-Verde (cyan) claro 0 Rojo claro I Magenta claro 0 Amarillo Páginas y bancos de memoria Estos conceptos se aplican sólo al adaptador de color/gráficos (CGA). La memoria (buffer) de pantalla está dividida en "bancos". Cada banco corresponde a una página, que es la información que aparece en la pantalla. Es decir, en un momento dado, aparece sólo la información de un banco, el asociado a la página activa. A continuación se indica, para las dos resoluciones posibles, el tamaño de una página.y el número de páginas. El factor 2 corresponde a los bytes necesarios para representar un carácter. Hay que recordar también que el tamaño de la memoria de pantalla es de 16 Kbytes. Resolución Tamaño de unq pdgina 80x25 40x25 80 x 25 x 2:4000 bytes 40x25 x 2:2000 bytes Número de páginos 4 8 Las direcciones relativas (desplazamientos) respecto al comienzo de la memoria de pantalla son: Resolución Pdgina 80x25 0 0h: 0 Kb 2 1000h: 4 Kb 2000h: 8 Kb J 3000h: 12 Kb I 40x25 Desplazamiento 0 I 2 J 4 5 6 7 0h: 0 Kb 1000h : 4 Kb 1800h : 6 Kb 800h: 2 Kb 2000h: 8 Kb 2800h: l0 Kb 3000h: 12 Kb 3800h = 14 Kb Dirección absoluts (hexadecimul) 8800:0: 88000 8900:0:89000 BA00:0: B4000 BB00:0: BB000 8800:0:88000 B880:0: 88800 8900:0: 89000 8980:0: 89800 BA00:0: 84000 BA80:0: B4800 BB00:0: BB000 BB80:0: 88800 Obsérvese que cada página empieza en una dirección par de Kb, es de- cir, se desaprovechan al final de cada página: o 4 Kb-4000 Kb :4096-4000:96 bytes (resolución 80 x25). . 2Kb-2000 Kb :2048-2000 : 48 bytes (resolución 40 x 25). u1¿ til"rr.tór soxzs l I 0h 4000: FAOh bytes I FAOh 96 -- 60h bytes página 0 área no utilizada 1000h 4000: FAOh b¡es IFAOh 96: 60h bytes página 1 área no utilizada 2000h 4000: FAOh bvtes 2FAOh 96: 60h bytes página2 área no utilizada 3000h 4000: FA0h bytes 3FAOh 96: 60h bytes página 3 área no utilizada 0h 2000: 7D0h bytes 7DOh 48: 30h bytes página 0 área no utilizada 800h 2000: 7D0h bytes FDOh 48: 30h bytes página 1 área no utilizada 1000h 2000: 7D0h bttes l7DOh 48: 30h bytes página2 área no utilizada 1800h 2000: 7D0h bytes IFDOh 48: 30h bytes página 3 área no utilizada 2000h 2000: 7D0h bytes 27DOh 48: 30h bytes página 4 área no utilizada 2800h 2000: 7D0h bytes 2FDOh 48: 30h bttes página 5 área no utilizada 343 3000h 2000: 7D0h b¡es 48: 30h bytes 37DOh página 6 área no utilizada 3800h 2000: 7D0h bytes 48: 30h bvtes 3FDOh página7 área no utilizada La página activa por defecto es la cero. Se puede cambiar de página rápidamente mediante una interrupción BIOS. Este método puede usarse para producir animación. Correspondenc¡a entre la memor¡a de pantalla y las pos¡c¡ones de la pantalla El primer byte del banco correspondiente a la página activa corresponde al primer carácter de la pantalla (columna 0, fila 0); el segundo b¡e es el atributo de este carácter; el tercer byte corresponde al segundo carácter de la pantalla (columna l, fila 0); el cuarto byte es su atributo, etc. Una manera, la más rápida, de escribir por la pantalla es mover información directamente al banco de memoria asociado a la página activa. Para escribir un carácter en la posición (X, Y) de la pantalla hay que mover a la dirección (relativa al comienzo de la memoria de pantalla) siguiente: P' tamaño-banco + 2. Y. tamaño_fila + 2. X + B Siendo P el número de la página, y B :0 para el byte de carácter, y B: I para el byte de atributo. El tamaño del banco es 2 Kb o 4 Kb. El ta- maño de la fila es 40 u 80. X es la columna e Y la fila. Para las dos resoluciones posibles en modo alfanumérico del CGA: Resolución 80x25 40x25 Tamaño del banco 1000h 800h Desplazamiento correspondiente a (X,Y) :4 Kb l000h.P+160.Y+2.X+B :2 Kb 800h.P+ 80.Y+2.X+B Como en el adaptador monocromo existe un único banco de 4 Kb y no y: existen páginas, P :0 Desplazamiento carácter Desplazamiento atributo w : 160.Y + 2.X : 160.Y + 2.X + I Aplicaciones Macros: PAMCUR - Posicionar el cursor en la pantalla. PAMCURL - Obtener la posición actual del cursor de la pantalla. PAMESCC - Escribir carácter por pantalla. PAMESCN - Escribir número desempaquetado por pantalla. Delimitador fin de número: $. PAMESCT - Escribir texto por pantalla. Delimitador fin de texto : $. PAMTEXTO - Escribir texto por pantalla (un cierto número de caracteres). Programas: PAPANIM - Demostración. del uso de las páginas de pantalla para crear arumaclon. PAPASCII - Listado caracteres ASCII por pantalla en forma de tabla de 16 filas por 16 columnas. PAPATR - Cambia el atributo de los caracteres de pantalla. PAPATRS - Escribe los atributos por pantalla. Los 256 atributos posibles se representan en forma de tabla de 16 filas por 16 columnas. PAPEJEM - Escribe un triángulo de asteriscos por pantalla. PAPLINEA - Prueba líneas por pantalla en modo alfanumérico. Prueba subrutina PASLINEA. PAPOBJ - Dibuja objeto por pantalla en modo alfanumérico con animación a través de las teclas de movimiento del cursor. Prueba subrutina PASOBJ. PAPRASTE - Prueba subrutina PASRASTE. El programa representa en pantalla alfanumérica el carácter ASCII asociado a cada tecla. PAPTEXTO - Escribe texto por pantalla. Prueba subrutina PASTEXTO y macro PAMTEXTO. PAPTXT - Escribe texto directamente en la mernoria de pantalla. Prueba subrutina PASTXT. PAPTXTRA - Prueba subrutina PASTXTRA. Escribe un texto mediarrte caracteres roster. PAPVECTO - Prueba rutina PASVECTO. u5 Subrutinos: PASBLOC - Escribir rectángulo de caracteres con un carácter de relleno. PASBOR - Borrar pantalla mediante desplazamiento (scroll)hacia arriba de la página activa. PASBORRA - Borrar la memoria de pantalla (16 Kb) con caracteres blancos y atributo normal (07h). PASLINEA - Escribir una línea en pantalla (modo alfanumérico). Se utiliza el algoritmo de Bresenham. PASOBJ - Representar o borrar objeto por pantalla alfanumérica. PASPUNTO - Escribir carácter y atributo en una posición determina- 3l *:1.'xll*iffi:f¿"f iiiff.- o., u de pantara. PASRASTE - Dibujo de un carácter roster por la pantalla alfanumenca. PASTEXTO - Escribir un texto por pantalla. El delimitador de fin de texto es el carácter $. PASTXT - Escribir texto directamente en la memoria de pantalla. El delimitador de fin de texto es el carácter $. PASTXTRA - Escribir texto en pantalla alfanumérica mediante la definición de los caracteres rqster. El delimitador de fin de texto es el carácter $. PASVECTO - Dibujo por pantalla alfanumérica de un objeto definido mediante una lista de vectores. 346 PAMCUR.ASM i MacTo: PAMCUR. . ; ; ; noc¡rinaiÁn. Posicionar e1 cursor en la panta11a. Supone página 0. Si fila o columna están fuera de los límites, se ignora. ; Parámetros3 ; y : fila r- - 79) (ent) (1 byte) (variable, registro o número). (o a 24) (ent) (1 byte) (variable, registro o número). pamcur macro x,y 1ocal fin ; salvar registros afectados push ax push bx push dx ; recoqter parámetros mov dI,x cmp dl,0 jI fin cmp dI,79 jS fin ; dl = columna mov dhry cmp dh,o jI fin cnp d}),24 )S fin mov bhro ; Página 0 mov a}]rz ; función: posicionar cursor int 10h ; I-Lamar a-L lJ-LU:i restaurar registros afectados ; fin: pop dx pop bx pop ax endm u7 PAMCURL.ASM i i MacTo: PAMCURL. . ;' ; h^^^*¡ *^i vs-etrPefe¡¡. Á-. obtener Ia posición actual de1 cursor de la pantalla. supone páqina 0. ; Parámetros: i x : columna (0 a 79) (sa]) (L byte) (variable o registro). (0 a 24) (sa1) (l- byte) (variable o registro). ; y = fil-a ; ---------- parncurl macro x,y i salvar registros afectados push ax push bx push dx mov bh,o mov ah,03h int 10h ; nunero págj-na = 0 ; función: leer posición del cursor ; ffamar al- BIOS t dL = cofumna, dh : fila ; poner parárnetros de sal-ida mov x,d] tx(colunna) mov y,dh ,y(fila) i restaurar registros afectados pop dx pop bx pop ax endm 348 PAMESCC.ASM Macro: PAI{ESCC. Descripción; Escribir carácter rlor Dantalla. Parámetros: car = carácter a escribir inmediato) . (ent) (variable, régistro o valor pamescc macro car push ax push bx ; salvar registros mov alrcar mov bx,O mov ahroeh int Loh pop bx pop ax t página 0 ; función: escribir carácter ; llamar al BIOS i recuperar registros endm 349 PAMESCN.ASM ; Macro: PAMESCN. ; Descripción: ; Escribir número desernpaquetado por pantal-Ia. ; Delimitador fin de núnero = $. ; No se escriben los ceros a Ia izquierda. ; Parámetros: ; numero = número desempaquetado a escribir ; (ent) (variabl-e). ---------- pamescn macro numero focal bucle, escrib, conti, fin push ax push bx push di bucfe: escri-b: conti 3 lea bx,numero mov di,O ; di = 0 indj.ca que no se ha escrito ningún ; dígito mov aL, [bx] ; obtener digito desernpaquetado cmp dl,,9, t ¿fin de número? je fin t si .., bifurcar cmp al-,O ; ¿eI dígito es O? jne escrib ; no ... bifurcar crnp di,o t ¿se ha escrito algún carácter? je conti i no ... bifurcar add al, r0r ; convertirl-o en carácter pamescc aI ; escribir carácter mov di,lt di = 1 indica que ya se ha escrito algún ; dÍgito inc bx jnp bucle cmp di,o jne fin pamescc r0r ; apuntar a siguiente carácter ; ¿se ha escrito algún carácter? r si ... bifurcar ; escribir cero pop di pop bx pop ax ; restaurar registros i fin: enom 35() ; sal-var registros PAMESCT.ASM t ; Macro: PAIUESCT. ; oescrj-pción: ; Escribir texto por pantalla. ; Deli¡nitador fin de texto = $. ; Parámetros: i texto = texto a escribir (ent) (variable). ; ---------- parnesct macro texto Iocal bucfe, fin push ax ; salvar registros push bx t lea bx,texto mov a1, [bx] r(r át q¡, e¡trP ? je fin pamescc al inc bx jmp bucle fin: pop bx pop ax i bx = desplazarniento de texto ; obtener siguiente carácter . | .fiñ ¿LLtl Aa *¡v*n? ; si ... bifurcar ; escribir carácter i apuntar a siguiente carácter ; restaurar registros endm 351 PAMTEXTO.ASM Macro: PAMTEXTO. noe¡ri n¡i Án. Escribir texto por pantalla. Parámetros: texto = Texto a escribir (ent) (variable). n = Número de caracteres a escribir (ent) (1 palabra) (variable, registro cx o vafor inrnediato). ; ---------- parntexto macro texto,n l-ocal bucle i safvar registros afectados push ax push si mov si,o ; desplazamiento inicial- sobre texto mov cx,n i cx = nro. de caracteres a escribir bucfe: mov al,byte ptr textotsil pamescc al ; escribir carácter en alinc si t apuntar a siguiente carácter l-oop bucle ; restaurar registros afectados pop si pop ax endm s2 PAPANIM.ASM Programa: PAPANIM. Descripción: Demostración de1 uso de las páginas de pantalla para crear an imación. Se utiliza un recuadro por página de tarnaño creciente. Las páginas se representan en rápida sucesión, dando La sensación de un récuadro que crece. Ef prograna acaba al pulsar cualquier tec1a, Simbolos: pantall-a equ 0b800h i segmento de mernoria de pantaffa atr equ 07h i atributo caracteres blaequt';blanco | Car equ *' ; CafáCter recuadro xinc equ 6 ; ancrenento en x entre los recuadros yinc equ 3 ; incrernento en y entre l-os recuadros ; Procedimiéntos externos: extrn pasborra: far : ---------- piJ.a pila datos segment stack db ends segment npag oD! xini yini xfin db? db? datos ends x v 128 dup ( rpila' ) db? número de 1a página x (columna) y (fila) x inicial recuadro y inj-cial recuadro x finaL recuadro y final- recuadro i codigo segrnent papanirn proc far assume cs : codigo , ds : datos , ss : pi1a i poner en la pila l-a dirección de retorno a1 DOS push ds sub axrax push ax ; direccionar segnento de datos con ds mov axrdatos mov ds,ax direccionar ¡nemoria de pantalla con es tnov ax , pantal la 353 mov esrax ; crear recuadros en cada página de Ia rnenoria de pantal-l-a t --------; bucle páginas mov npag,O ; página inicial, bucl-e_p: i cal-cuLar xini. : xj-nc*npag mov alrxinc mu1 npag mov xini,al ; calcular yini = yinc*npag mov al,yinc mul- npag mov yini,al i calcul-ar xfin = 80 - xini mov bl-,80 sub bl,xini s.j - LI i ; calcular yfin : 25 - yini mov bI ,25 sub bl,yini mov yfin,bl i bucle 1íneas mov cxr25 bucl-e_y: mov y,25 sub y,cf ; bucle col-umnas push cx bucle x: mov cxr80 nov xrSO sub xrcl i cáIculo de1 desplazaniento en la ¡nemoria de pantalla ; correspondiente a 1a posición (x,y): t di = npag:t4096 + Y'r160 + x*2 mov ax,4096 nov bl,nPag mov bh,0 mu1 bx mov dirax mov al, l-60 mul y add di,ax 3At nov al-,2 mul x add di,ax ; inserción carácter: blanco o * blanco: seguir: mov blrx mov bh,y crnp bh, yinÍ jb blanco cmp bh,yfin ja blanco cmp bI, xini jb bLanco cmp bl,xfin j a bl-anco ¡nov byte ptr es: [di],car jmp seguir mov byte ptr es: [di],bla mov byte ptr es: [di+l],atr l-oop bucl-e x pop cx loop bucle_y J.nc npag cmp npag,4 jae inicial jnp bucle_p ; bucle de páginas t --------inicial: mov npag,O t npag = página inicial bucle: mov al,npag i a1 = nro. de J.a página mov ah,05h ; función: seleccionar 1a página activa int 10h r llanar aI Bfos pulsa si se una tecla, volver al DoS i mov ahrL ; función: ver si se pulsó una tecla int l6h ; lfamar al- BIos ; si se pulsó una tec1a, zf = O i si no se pulsó una tecla, zf : I ; bifurcar a fin si se pulsó una tecla )nz fin t páqina siguiente inc npag cmp npag,4 jb bucle jnp inicial ; incrernentar página ; si inferior al número de páginas ; bifurcar a sel-eccionar página i i retorno aI DOS fin: call pasborra rai ; borrar pantalla 355 papanin endp codigo ends end 356 papanim PAPASCII.ASM ; PrograÍra3 PAPASCII. ; Descripción: t Listado caracteres ASCII por pantalla en forrna de tabla de 16 filas por 16 columnas. ; t SÍmbolos: pantalla équ 0b800h ; segmento rnemorj.a de pantaLla x0 equ 5 ; columna correspondiente al carácter 00h y0 equ 6 correspondiente al carácter ooh ; fila xinc equ 3 ; separación entre columnas ; Procedimientos externos: extrn pasborra: far : i ---------- pila segment stack db pila ; ends L28 dup ( 'pila' ) ---------- codigo segnent papascii proc far assume cs:codigo, ds: codigo, ss:pi1a i poner dirección de retorno al DOS en la pila push ds sub axrax push ax hacer ds = cs push cs pop ds direccionar 1a ¡nemoria de pantalla con és mov axrpanta]1a mov ésrax ; borrar Ia mernoria de pantall,a call pasborra i escribir título 1 mov di, (Y0-5) *160 + 2*x0 + 20 i posición en memoria pantalla mov si,0 ; desplazamiento sobre títul-o rir1: mov a1,titulo1[si] cnp df, '9 t l^ Je ^-^+l+. mov es: [di],alinc si add di,2 jnp titl extraer carácter :ril+iñ^ ¡arÁ¡tar) si .,. bifurcar nover a rnemoria de pantafla apuntar a carácter s19ufEr¡LE siguiente posición en memoria pantalla 357 ; escribir títufo 2 esctit2: mov di, (y0-4)*160 + 2*x0 + 20 ; posición en memoria pantalla mov si,0 ,' desp]azamiento sobre título tit2: mov al,titulo2 [si] extraer carácter cnp af, t$, ¿úLtj,rno carácter? je bucles si ... bifurcar rr¡ r ^^. Lurl,ar ^1 s-r nover a memoria de pantalla rnc st apuntar a carácter siguiente add di,2 siguiente posición en memoria pantalla jmp tit2 ; bucl-e columnas bucles: mov cx,l-6 col-s: i 16 co]umnas mov bl,L6 sub blrcl t b1 = columna escribir nro. de colurnna en hexadecimal ; ; di = (yO-Z¡*169 + 2*xO + col-umna*xinc*2 mov alrbl i al = columna nov dl,xinc*2 ; d1 = xinc*2 mul dl; ax = cofumna*xinc*2 rnov di, ax ; di = colunna*xinc*2 add di, (y0-2)*l-60 + 2*x0 nov ah,o nov alrbl mov sirax t ah = 0 i ax = columna ; si = columna mov al,lista[si] ; aI = nro. de la columna nov es:[di],al i moverl"a a mernoria de pantalla i bucle filas push cx fiLs: mov cx,l-6 mov bh,1,6 bh, clb1, o sub jne posic ; salvar cx ; 16 fil-as ; bh = fila ; ¿cofumna 0? i no ... bifurcar escribir nro. de fila en hexadeci¡nal (sólo cuando columna = 0) cal"cul-ar ¿i = yO*160 a 2*(x0-4) + fila*160 mov ah,o ; ah = o nov al,bh ; aI = fila mov si,J-60 ; si = 160 muL si ; ax = fila*160 mov di,ax ; di = fila*16o add di,y0*l-60 '¡ 2* (x0-4) mov ahro mov al,bh mov si,ax 358 i ah = 0 ; ax = fila ; si = fila i r a} = nro. de la fila i moverl-a a rne¡noria de pantalla ; di = bl*xinc*2 + bh*l_60 + y0*t-60 + 2*x0 pos ic: mov al,listalsil mov es: [di],aI mov ahro mov al,bh mov si,160 mu1 si mov di,ax ; ah = 0 ; ax = fila ; si = J-60 ; ax = fila*160 ; di = fiLa*160 mov al-rblt al = columna nov dl,xinc*2 t dl = xinc*2 mul dI ; ax = col-unna*xinc*2 add di,ax t di = fila*l-60 + columna*6 add di,y0*l-60 + 2*x0 ; mover carácter a escribir a mernoria de pantalla inc n mov al,n mov es: ldi],al loop fils pop cx i recuperar cx loop cols fin: i pausa, leer cualquier tecla mov ah,O int l-6h i borrar 1a pantalla i función: Leer tecla i llanar aI BIOS call pasborra ret i volver al DoS db -1 i carácter inicial db tOL234567ggABCDEFt ; caracteres hexadecimales tTabl-a db de caracteres ASCII$t db'XY, X = col-umna, Y = fila$' n lista titulol titulo2 papascii endp codigo ends end papascii 359 PAPATR.ASM ; Prograna: PAPATR. ; Descripción: ; Cambia eL atributo de l-os caracteres de panta1la. ; Parámetros: ; 8 diqitos binarios con e1 atributo de1 carácter. ; Sí¡nbol-os: pantalla equ 0b800h ; segmento de ¡nemoria de pantalla ; ---------- pila pila t ; ends ---------- datos atr datos ; segnent stack db 128 dup (tpila') segment para db ends ? ; atributo ---------- codigo i, papatr segnent para proc far assume cs : codigo, ds : datos , ss : pila ; potr"t en 1a pila la dirección d.e retorno aI DOS push ds sub ax,ax push ax i direccíonar segmento de datos con ds mov axrdatos ! mov ds,ax i --i convertir parámetro a entero binario (l- byte) call conver i poner carácter de atributo en toda ]a pantal-l-a mov cx,2000 i 25 x 80 caracteres mov ax,pantalla i ax = segnento de memoria de pantal-la mov es,ax ; es = segnento de ¡nernoria de pantalla mov al,atr t al : byte de atributo mov sir lbucle: nov es:[si],aI i nover atributo add sí,2 tsi=si+2 loop bucle 360 i ; retorno a1 DOS fét papatr ; endp ---------- conver proc i convierte una cadena AscII de dÍgitos binarios en un número ¡ binario sin signo i entrada: ; 8 dígitos binarios en área de parámetros del PSP t salida¡ ; atr = byte de atributo i salvar registros afectados push es push ax push bx push cx push dx push si push di mov cx,8 mov sir 82h i ; cx = J.ongi.tud de Ia cadena AscII t si = despfazaniento área de i Paránetros ; bucle caracteres de l-a cadena mov axro i ax=0 (resuLtado) (constante) mov di,2 ;di=2 mov bh,o ; bh = 0 bucle car: mov dx,O ; dx = O nul di ; rnultiplicar resultado por la constante r ax = nuevo resultado mov b1,e6: [si] ; bI = carácter de 1a cadena sub b1,30h t bl = dígito de entrada add ax,bx ; su¡nar a resultado inc si i apuntar a carácter siguiente de La cadena loop bucle_car i siguiente carácter t poner salida i mov atr,aI r mover resultado i restaurar registros afectados pop di pop sL pop dx pop cx pop bx pop ax pop es ret 361 a6n\tér éñdh ; uvq ^^Á i ¡y ^^ v ^hJ^ end papatr w2 PAPATRS.ASM Prograna: PAPATRS. Descripción: Escribe l-os atributos por pantalla. Los 256 atributos posibles se representan en forma de tabla de l-6 fil-as por 1,6 co]unnas. S írnbolos : pantal-l-a equ 0b800h i segrnento mernoria de pantalla adrr x0 y0 i carácter a escribir ; col-umna correspondiente a1 atributo correspondiente a1 atributo ; fifa ; separación entre columnas lVl equ 5 equ 5 equ 3 xtnc ooh ooh ; Procedimientos externos: extrn pasborra: far segment stack db pifa ; ends ]-28 dup ('piLa') ---------- codigo segnent papatrs proc far assume cs:codigo,ds:codigo,ss:piIa ; poner dirección de retorno al DoS en Ia pj.la push ds sub axrax push ax hacer ds = cs [/u-¡¡ i ,' direccionar v.lc 1a memoria de pantalla con es mov axrpantalla mov es,ax ; borrar Ia mernoria de pantalla cal-l- 'pasborra i escribir título lnov di, (y0-5)*l-60 + 2*x0 + 20 ; posición en memoria Pantalfa mov sir 0 ; desplazamiento sobre titulo ti-tr-: mov al,titutol-[si] ; extraer carácter cnp dl, t $t i ¿úl-tino carácter? ia ae¡fit? si ... bifurcar Je mov es: [di],a1 i mover a memoria de pantalla 5 r9 ufer ue inc si i apuntar a carácter ^¡-.,¡^-+^ add di,2 i siguiente posición en memoria pantalla r 3dt jnp titi. ; escribir títuIo 2 esctit2: mov di,(yo-4)*1,60 + 2*xo + 20 ; posición en ¡nemoria pantalla mov si,o ; desplazarniento sobre titulo . tir2: nov al,titulo2tsil ; extraer carácter cmP df,t$t ; ¿úttirno carácter? je bucles t si ... bifurcar mov es:[di],al i mover a rnemoria de pantall-a inc si i apuntar a carácter liguiente add di,2 ; siguiente posición en-¡nernoria pantal,l-a jmp tit2 ; bucle columnas bucles: mov cx, l-6 ; 16 columnas cols: mov bl,L6 sub bL,cl t bL = colunna ; escribir nro. de columna en hexadecimal , di = (y0-2)*160 + 2*xO + col-unna*xinc*2 mov aI,b1 i al = columna mov dl,xinc*2 i dl : xinc*2 nul dI i ax : colunna*xinc*2 nov di,ax t di : colunna*xinc*2 add di, (y0-2)*160 + 2*xO nov ah,o mov aI,bI mov sj.rax i ah = 0 i ax : colurnna t si = colu¡nna mov al,listalsil ; al = nro. de 1a col-umna mov es:[di],al i moverla a memoria de pantaLla t buc]e filas push cx mov c.x,L6 fils: mov bh,16 sub bh,c1 cnp b1,,0 jne posic i salvar cx t 16 fiLas ; bh = fila i ¿cofumna 0? ; no ... bifurcar escribi.r nro. de fiLa en hexadecimal- (sóIo cuando columna = 0) i caLcular di = y0*L60 a 2*(x0-4) + fil-a*L60 (posición en memoria de pant ; lnov ah,o t ah = 0 mov al,bh ; a1 = fila t¡ov si,l-60 ; si = 160 mu1 si ; ax : fila*l-60 mov di,ax ; di = fila*160 add di,y0'r160 a 2*(xO-4) nov ah,o 364 ; ah = o ; ax = fila t si = fil-a mov al,Iista[si] ; al- = nro. de la fil'a mov es: ¡di¡,á1, i ¡noverla a mernoria de pantalla nov aL,bh mov si,ax t di = bI*xinc*2 + bh*160 + y0*l-60 + z*xo pos]-c: nov ahro ¡nov aL,bh mov si,L60 muL si mov di,ax ; ah = 0 ; ax = fila i si = L60 ; ax = fila*l-60 ; di = fila*l-60 mov al-,bL ; al = col-unna mov dl,xinc*2 t dI = xinc*2 mu1 dI i ax = col-unna*xinc*2 add di,ax t di = fila*160 + col-umna*6 add di,Y0*l-60 + 2*x0 atrj,buto a escribir a ne¡noria de pantal-La i ^o.r.r ; siguiente atributo mov alrn . mov byte ptr es:[di],car ^rYÁd+ár r atributo mov es: Idi+].1,aI loop fils pop cx ; recuperar cx loop cols fin: i pausa, leer cualquier tecla mov ah,O ; función3 Leer tecla int 16h i llanar aI BIoS i borrar 1a pantalla cal"l pasborra rec ; volver al DOS ; atributo inicialdb -L db t}L234567A9ABCDEFt ; caracteres hexadecimal-es db 'Tabla de atributos$' db tXY, X = columna, Y = fil-a$ lista titulol titulo2 papatrs endp codigo ends end papatrs 365 PAPEJEM.ASM i ; Programa: PAPEJEM. ; Descripción: ; Escribe un triángu1o de asteriscos por pantal1a: ; ; ; ******* ***** *** i Sirnbolos: n equ 50 cr equ 13 Lf equ 10 ; numero de asteriscos de 1a primera linea i retorno de carro i alinentación de linea ; Procedi-mientos externos: extrn pastexto: far t ---------pila segment stack db l-29 dup ( ,piIa' ) pila ends ---------datos segment para t linea db n dup(r*') db cr db 1f db r$r datos ends i l_inea nayor a escribir ; retorno de carro ; ali-mentacion de l-inea ; delinitador fin de rnensaie codigo segrnent papejern proc far assume cs : codigo, ds : datos , ss : pila i poner en 1a pila 1a dirección de retorno al_ Dos push ds sub ax,ax push ax i direccionar segnento de datos con ds mov axrdatos mov dsrax i --mov si,0 , linealsi] nov dirn dec di ; finea[di] t escribir linea por pantalla buc]e: 366 es e1 prirner caracter es el- úLti¡no caracter push ds l-ea ax,l-i-nea push ax call pastexto mov mov inc dec cmp byté ptr [si],' byte ptr [di],' Si ' ' mueve blanco Por l-a izquierda mueve blanco Por Ia derecha si, di bucle retorno al- DoS papel em endp codigo ends end papeJ em 397 PAPLINEA.ASM Prograna: PAPLINEA. Descripción: Dibuja 1Íneas por pantalla en nodo alfanurnérico. Prueba subrutina PASLfNEA. S Ímbolos : rx 80 25 8 ; resolución x (col-umnas) ; resoluci-ón y ( f j-las) nrectas ; número de rectas a dj-bujar i ; Procedimientos externos llamados: extrn paslinea:far extrn pasbor: far extrn tesesper: far t equ equ equ ---------- ; pila i datos segment stack db ends 128 dup ('piLa') segment para x]y1 x2 y2 c a dr¡/ ? ; coordenada x punto 1 d\"/ ? ; coordenada y punto 1 dw ? i coordenada x punto 2 dw ?_ ; coordenada y punto 2 ,lt ; carácter db db 07h ,. atributo ; definición estructura de una l"Ínea Iinea Ii ne¿r struc Crn¡ ? ;xinicial dr4r ? ,y inicial dv/ ? ;xfinal d\^/ ? tyfinal tlr ; carácter db db 07h ¡ atributo ends i recl"as a dibujar recta i datos linea linea linea linea linea linea linea linea ends t ---------codigo segnent 368 <0 , <0 | <rx-l, <rx/2, 'ry/z, ry-1, ry-1, O , rx-L,ry/z rx-l-, O o .0 tx/2try-L ,,) , ,) ,,) ,,) ,,) <0 ,3*ry/4, rx-1-,ty/4 ,,) <rx/4t ry-L,3*rx/4,O ,,2 <Yx/4 | O ,3*rx/4 try-)- ¡ ,) <0 , ry/4, rx-L,3*ry/4, t> paplinea proc far assume cs:codigo, dssdatos, ss:pila ; poner en 1a pila Ia dirección de retorno a1 DOs push ds sub ax,ax push ax direccionar segmento de datos con ds mov axrdatos l^ ^.. borrar pantal-1a call pasbor dibuj ar rectas mov cx,nrectas mov si, o i nro. de rectas a dibujar push ds lea ax, recta Isi] push ax call paslinea add si,type linea loop bucle apuntar a siguiente recta type de estructura es eI nro. de bytes esperar hasta leer una tecla call tesesper borrar pantalla call pasbor retorno al DOS ret papl,inea endp ends end paplinea 369 PAPOBJ.ASM Programa: PAPOBJ. nae¡r'i n¡ i Án. Dibuja objeto por pantall,a en modo al-fanunérico con animacÍón a través de las teclas de ¡novimiento del cursor. Prueba subruti-na PASoBJ. El- programa acaba pulsando Enter. Procedimientos externos: extrn pasbor: far extrn pasobj 3 far extrn tesfle: far pila segnent stack db l-28 dup ( rpilar ) ends i datos xinc segnenr ;. increnento en x y].nc db? x v l-abe] byte dr^¡ 40 dw L2 db 07h ope iñ^réh6ñf^ óh lt ; comienzo definición objeto ; coordenada x origen de] objeto ; coordenada y origen de1 objeto ; atributo (nornal) ; operación sobre el objeto t 0 - borrarlo r l- - dibujarlo r definición del- obj eto nh-i o+n Ah 7 db db db db db lot loot lool I ooooooo datos ends codigo segnent para proc ; dimensión x (nro. de columnas) ; di¡nensión y (nro. de filas) ; trl.a 1 r fil-a2 I , fíIa 4 far assume cs : codigo, ds : datos , ss : Pil-a ; t en 1a pila la dirección de retorno a} DoS push ds sub axrax push ax direccionar segmento de datos con ds 370 mov axrdatos mov dsrax borrar pantal]a call pasbor t dibujar el objeto dibuj ar: mov ope,lpush ds 1ea ax,defobj ; dibujar objeto ; definición objeto push ax call pasobj leer tecla de rnovimiento del cursor o Enter ; push ds lea axrxinc ; incre¡nento en x push ax push ds 1ea ax,yinc ; incremento en y push ax cal,l, tesfle ; ver si se pulsó Enter cmp xinc,0 jne borrar cmp yinc,0 je fin ; borrar e1 objeto borrar: mov ope,0 push ds 1ea axfdefobj ; borrar objeto ; definicj-ón objeto cal-1 pasobj carnbiar origen def objeto mov alrxinc cbt'/ add x,ax mov al,yinc cbr,¡ add Y,ax inn Aih,ri¡r ; al = xinc ; ax=xinc +xinc ;x:x ; a1 = yinc ;ax=yinc +yinc ;y=y ; retorno a1 DOS tln: 371 call, pasbor 371¿ ñ^ñ^hi r-i óñ.ih i codigo ends end papobj i borrar pantalfa PAPRASTE.ASM Programa: PAPRASTE. Descripción: Prueba subrutina PASRASTE. EI programa representa en pantalla alfanumérica el carácter ASCII asociado a cada tecla. E1 prograna termina si se pulsa Ia tecla Esc. Procedi¡nientos externos : extrn pasraste:far extrn pasborra: far i p j-l-a segment stack db pila : dup ('pila' ) ---------- datos segment x0 y0 dw 25 dh¡ 4 dr¡ 2 d\^¡ 2 XM yrn cod t datos ; L2A ends ; x (colurnna) esquina superi.or i.zquierda carácter esquina superior izquierda carácter ; y (fila) i tanaño en x de cada punto ; tamaño en y de cada punto t código ASCII (0 a 255) ends ---------- codigo segment papraste proc far assume cs: codigo,ds 3datos, ss:pil_a ; poner dirección de retorno aI DOS en Ia pila push ds sub ax,ax push ax ; direccionar seqmento de datos con ds ññ1r á^l.Og, ^Y mov ds,ax i 1éér tecl-a leer nov axr 0 int 1-6h 3 ; función: feer una tecLa i Llamar al BIoS ; ah = código l-, a] = código 2 se pulsó Esc (ah = 01h, al- = lbh) cmp ax,0l-1bh je fin mov codral t .¿tecla Esc? ; si ... bifurcar ; código ASCII 373 ; borrar pantalla call pasborra ; representar eI carácter push ds ; xO l-ea ax, x0 push ax c^ I I ñ^<r^qte i r1n: imn IFpr ret 374 ends pnril a Ieer ; vol-ver aI DOS papraste endp codigo ? Lrifrrrc^r ñ^ñr^qte PAPTEXTO.ASM Prograna: PAPTEXTO. Descripción: Escribe texto por pantal-l-a. Prueba subrutina PASTEXTO v nacro PAMTEXTo. SÍmboLos: ^r 6drr ; retorno de carro ; alimentación de linea 1 ? l-f equ 10 Procedirnientos externos : extrn pastexto: far Macros: if1 j.nclude pantexto.asm include pamescc.asm endif i segment stack ),2a dup ( rpilar ) db ends t datos segment para texto n db ^h d\4¡ datos ends rabcdefghijk fmnopqrstuvwxyz I t<l ; delinitador fin de texto $ - texto - L ; longitud del texto a escribir codigto segrnent paptexto proc far assume cs: codigo, ds: datos, ss: p j-l-a i poner en J-a pila la dirección de retorno al Dos push ds sub ax, ax push ax i direccionar segmento de datos con ds mov ax,datos mov dsrax escribir texto rnediante Il-anada a subrutina push ds i segmento lea axrtexto push ax i desplazarn j-ento call pastexto 375 ; escribir texto mediante macro pamtexto texto,n ; ; retorno al DOS reE paptéxto endp codigo 376 ends pnri ñAnféXtO PAPTXT.ASM ; Programa: PAPTXT. i Descripción: i Escribe texto dj-rectamente en 1a memoria de panta]Ia. ; Prueba subrutina PAsTxT. ; Procedinientos externos: extrn pastxt3 far pila pila ; segrnent stack db 128 dup ( rpila' ends ) ---------- datos par segnent texto ; parámetro a pasar a la subrutina i columna t f il-a d\4t 500 ; longitud texto a escribir db L00 dup (rPepe r) datos ends xdb49 ydbs n ; labe1 byte ---------- codigo paptxt segment proc far assume cs : codigo, ds : datos , ss : pila i poner en Ia pila la dirección de retorno al DoS ñrich .lc sub ax, ax push ax i direccionar segnento de datos con ds nov axrdatos d< ^v i escribir texto h,!eh.lc 'I á^ ñrreh ; i . ^^1I rót^?ñ^ i ^l ^v ñ^<l-vf nñq r6f paptxt endp ¡aA i ¡a a¡A< an¡l h: ni vl- 377 PAPTXTRA.ASM Programa: PAPTXTRA. Descripción: Prueba subrutina PASTXTRA. Escribe un texto medi-ante caracteres raster. Procedimientos externos: extrn pastxtra: far extrn pasborra:far extrn tesesper: far i pifa pil-a i segment stack db ends L28 dup ('pila') datos segment def l- dv/ O,O,1,,L i definición textoL: x,y,xm,ym db rAaBbCcDdEe$ texto a escribir dr^¡ O,8 rL,l t" definicj.ón texto2 : x,y,xm,ym rfFgGhl{iIjJ$' db ; texto a escribir dh¡ O r).6,I,1 t definición texto3: x,y,xm,ym tKkLlMrnNnOo$ti db texto a escribir textol def2 texto2 texto3 ; x = columna esquina superior izquierda carácter esquina superior izquierda carácter ; y = fila i xm = tarnaño en x de cada punto ; ym = tamaño en y de cada punto datos ; ends ---------- codigo segment paptxtra proc far assume cs:codigords:datos,ss:pi1a ; poner dirección de retorno al Dos en Ia piLa push ds sub axrax push ax i direccionar segmento de datos con ds mov ax,datos mov ds,ax borrar pantalJ-a cal-1 pasborra representar texto]. push ds l-ea ax, def 1 !78 r defL push ax call Pastxtra ; representar texto2 push ds lea ax,def2 t def2 push ax call Pastxtra i representar texto3 Push ds 1ea ax,def3 push ax call pastxtra i esperar a que se pulse cualquier tecLa cafr Lesespef i ; borrar pantalla call pasborra ret paptxtra endp aaÁi ¡¡ anÁe end paptxtra ; volver al DOS 379 PAPVECTO.ASM i Programa: PAPVECTO. ; Descripción: Prueba subrutina PASVECTO. i Después de dibujar el objeto, e1 programa termina pulsando i i cual-quier tecla. ; Procedinientos externos: extrn pasborra: far extrn pasvecto3 far extrn tesesper: far t ---------- pila segnent stack db ends ; L28 dup (rpilar) ---------- datos seqnent dr¿/ 10 t x (col-umna) esquina superior de1 objeto dr¡ 5 ; y (fi1a) esquina superior det objeto t definición objeto ¡nediante Lista de vectores vector struc db? Ot/ | ; coordenada x d$r ? ; coordenada y vector ends lista vector (tAt r0,O)r(,Bt r2I,O>t<tBr rO,11)r(t Bt ,2L,]'L> vector (tAt rg,5),(tBr r16,5>r<rFr rO,O> datos ends x0 y0 ---------codigo segment papvecto proc far assume cs:codigo,ds:datos,ss:pi1a i poner dirección de retorno al- DOS en la pila t push ds sub ax,ax push ax ; direccionar segnento de datos con ds mov axrdatos mov ds, ax borrar pantalla call pasborra representar el objeto en la posición (x0,y0) 380 i push ds Iea axrxo push ax i x0 push ds i y0 l or .v ttñ push ax push ds lea ax,l-ísta ; lista de vectores push ax i -^l I ñ^q\ré.to ; esperar a l-eer una tecla call tesesper ret i volver a1 DOS papvecto endp codigo ends end papvecto 381 PASBLOC.ASM Subrutina: PASBLOC. Descripción: Escribir rectángulo de caracteres con un carácter de rel-l-eno. Supone página 0. Parámétros: params sfruc d$/ retorno dd. p]dd pararns ends bp salvado por la subrutina dirección de retorno dirección parárnetro 1 (ent) (9 bytes) xa,yl tx2 ,y2 , c xJ-,)¡1 = coordenadas iniciales (2 palabras) x2,!2 = coordenadas finales (2 palabras) c (1 byte) = carácter de relleno t SímboLos: nret equ offset pL - offset retorno ; argumento de ret ; ---------- datos datos codigo segment' para x y xL ? ? ? ? x2 dw ? y2 dw ? cdb ? xn d$¡ ? yn dht ? d$, dsi dw ends segmenE assu¡ne publ ic pasbl-oc i ; xgenéricabl-oque ; ygenéricabtoque ; x inicial bt oque ¡ yinicialbloque bloque ; xfinal bfoque ¡ yfinal ; carácter de relleno ; número de filas ¡ número de col-umnas para cs : codigo, ds : datos pasbloc proc far push bp mov bprsp ; sal-var bp . Lh '!y-sP - ^- i --; sa]var registros afectados push ds push es push ax push bx push cx push dx push si ; direccionar segmento de datos con ds mov axrdatos mov dsrax w. recocfer DaraneEros l-es mov mov mov mov mov mov mov mov mov mov si, Ibp].p1 axress Isi] x1, ax es : seqmento, si : desplazarniento x1 ax,es: Isi+2] ,yI ax,es: Isi+4] ix2 yl-, ax x2,ax ax,es: Isi+6] y2,ax aI,es: IsÍ+8] c, al cál-culo deL número de fil-as y de col-umnas mov ax,x2 sub ax, xl- mov mov xn, ax inc sub ax ty2 ax r yl- mov Yn, ax inc ax i nro. de cofurnnas ; nro. de filas bucle filas mov mov mov vvv: cx, yn ax, y1 Yr aX ; nro. filas ;y=yl ; bucle co]umnas push cx mov cxrxn mov ax, xlmov x,ax i nro. coLunnas ;x=x1 posicionar cursor en (x,y) cmp jae x,80 incx y,25 jae incx crnp mov mov mov mov mov mov int ax, x dl, a1 ax, Y dh, albh, o ah, o2h t-0h col-umna fila nú¡nero página : o funcion: posicionar cursor l"-Lamar ar l,rus escribi"r carácter push cx mov nov cx, 1 mov mov ah,10 pop cx int 10h 1 carácter carácter a escribir número página = o función: escribir carácter donde cursor _LIamar aI t'rus 383 l-ncx: ix=x+lloop xxx pop cx inc y ty=y+lloop yyy restaurar registros afectados pop si pop dx pop cx pop bx pop ax pop es pop ds mov sp, bp reE nreE pop pasbloc codigo endp ends end 384 sP=bp restaurar bp PASBOR.ASM i Subrutina: PASBOR. . ; t ; n^^^-i ¡Pu¿v^¡. -^i Á-. Borrar pantalla mediante desplazarniento (scro11) hacia arriba de fa página activa. ---------- codigo segment assume cs:codigo nrrhl i ¡ i pasbor neqb6¡ r*" proc far i salvar registros afectados push ax push bx push cx push dx ^v ^ r, ^h Át ?o mov mov al,0 ah,06h int i ; recuperar Loh registros pop pop pop pop i pasbor codigo t esquina superior izquierda (0,0) ; fila inferior derecha ; co1. inferior derecha r atributo normaf i aI = 0 indica ventana completa i ah = 6 indica scro11 ; llamar a1 BIos afectados dx CX bx ax ret endp ends end 385 PASBORRA.ASM Subrutina: PASBORRA. Descripción: Borrar 1a memoria de pantalla (16 Kb) con caracteres blancos y atributo normaf (07h). sÍmbo]os: pantalla equ 0B800h i codigo ; segnento lnenoria de pantalfa segment assume cs:codÍgo pubLic pasborra pasborra proc far ; saLvar registros afectados push es push ax push cx push dx push di i direccionar segrnento de pantalla con es mov ax, pantal-La mov esrax mov di,0 1a me¡noria de pantalla mov cx,200Oh cx=16Kb=10h xl-Kb= l-oh x 400h = 4000h bytes = 200Oh palabras dirección hacia adelante carácter blanco atributo normal es: [di] = ax, di :di+2 mov al , rr rl mov ahr07h rep st'osr¡ i i recuperar registros afectados pop di pop dx pop cx pop ax pop es ret pasborra endp codigo 386 ends end PASLINEA.ASM I su¡rutina: PAsLINEA. i Descripción: ; nscribir una línea en pantalla (modo alfanurnérico). t Se utiliza el algoritno de Bresenham. i Parámetros: params struc dr¡r ? ; bp salvado por Ia subrutina retorno dd ? ; dirección de retorno p1 dd ? ; dirección parámetro l- (ent) i xl ,yI ,x2,y2,c,a (1- pal-abra) ; x1 = coordenada x inicial (1- pal-abra) ; y1 = coordenada y inicial (l- palabra) i x2 = coordenada x final (L palabra) ; y2 = coordenada y final (1 byte) i c = carácter a escribir ; a = atributo del carácter (1 byte) params ends ; SÍmbolos: nret equ offset p1 - offset retorno ; argumento de ret i i Procedi¡nientos externos: extrn paspunto: far ; ---------- datos segment x Y c a x1 ylx2 y2 delp delr de]rx del-ry deldx deldy deLre delde datos dw dvr db db d\^¡ dw dw dw dv¡ dr¡/ dvJ dw dw dw dw dw ; ; coordenada x punto de 1a 1ínea ; coordenada y punto de 1a línea ;carácteraescribir ;atributoaescribir icoordenadaxinj.cial ;coordenadayinicial ;coordenadaxfinal ;coordenadayfj.nal ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ends ---------- codigo segment assume cs:codiqo,ds:datos nrrl-rl i ¡ .^.Iinea rse ; paslinea proc far push bp mov bp,sp ; safvar bp ;bP=sP i salvar reqistros afectados 87 push ds push es push ax push bx push cx push dx push si push di t direccionar segmento datos con ds mov axrdatos mov ds,ax ; recoger parámetros 1es si, [bp].p1 mov ax,es3 [si] nov x1,ax i es : segmento, si = despl,azamiento ; x1 = coordenada x inicial- mov ax,es: Isi+2] mov y1,ax t y1 = coordenada y inicial nov ax,es: Isi+4] mov x2tax i x2 = coordenada x final mov ax,es: Isi+6] mov y2rax , y2 : coordenada y finaf mov al,es: Isi+8] mov c,a1 ; carácter a escribir mov a]res: Isi+9] mov a,a1 ; atributo deI carácter i incrementos iniciales nov sirl mov di,l- ; incremento de x inicial ,' incrernento de y inicial ; cal-cul-ar /y2-yI/ mov dx,y2 sub dx,Y1 jge almay neg di neg dx alrnay: mov i dx = y2 i dx = Y2 - YI ; bifurcar si y2 - y]- es no negativo i mover en dirección -y i valor absoluto de y2 - y]deldyrdi i almacenar incremento de y para i movirnientos diagonales ; ca]cular /x2-xI/ mov cx,xz sub cx,x1 jge almax neg si neg cx almax: 388 i cx = x2 ; cx : x2 - x1 ; bifurcar si x2 - xl" es no negativo i mover en dirección -x ; valor absoluto de x2 - xlmov deldx,si ; afnacenar incremento de x para ; rnovirnientos diagonafes ; clasificar /y2-fl,/ cnp cx,dx jge mover mov sir 0 xchg cx,dx j¡np alma mover: Y /x2-xL/ ; compara delr con del-p i bifurcar si recta en dirección x ; si lÍnea vertical, incrernento de x = 0 ; e intercambiar diferencias mov di,O ; si Iínea horizontal, incremento de y = ; almacenar del-r, delp, delrx y delry alma: ¡nov delr,cx ; cambio en Ia dirección de La recta mov delp,dx t canbio en l-a perpendicular a la recta mov delrx,si ; incrernento dé x en 1a dir. de l-a recua mov delry,di i incremento de y en la dir. de la recta i obtener val-ores iniciales para x e y mov si,x1; coordenada x mov di,yr i coordenada y caIcular valor inicial e incrementos para la función de error i mov ax,delp sal axrl ; 2*de]p mov delre,ax ; cambio si rnovi¡nj-ento recto sub ax,cx ; 2*déIp - delr mov bx,ax ; valor inicial sub axrcx ; 2*déIp - 2*delr mov delde,ax ; cambio si rnovimiento diagonal i alustar contador inc cx ; estructura del buclé principaf bucLe: Inov xrsi mov yrdi ; dibujar carácter con su atributo en (x,y) push ds l-ea ax, x push ax d^l | ñ^chrlh+^ cnp bx,o -iaa Jav Áirannrl ,' ver si línea recta o diagonal IÍnea recta recca : add sj-,deLrx ^^Á .li .lalr\r add bx,delre ;. increnentar x iñ^ÉéñéñfAr \/ ; actualizar término de error 389 loop bucle jnp fin i caso linea diagonal diaqonal: add si,deldx add di,deldy add bx,delde loop bucle i punto siguiente i incrementar x i incrementar Y i actualizar término de error ; punto siguiente i restaurar registros afectados fin: pop di pop si pop dx pop cx pop bx pop ax pop es pop ds mov sp,bp pop bp ret nret paslinea endp codigo 390 ends end t sp = bp ; restaurar bp PASOBJ.ASM r Subrutina: PASOBJ. ; Descripción: ; Representar o borrar objeto por pantalla alfanurnérica. Supone página 0. i Se dibujan sólo ]os caracteres del objeto que caen dentro de fos i ; Ií¡nites de la pantal,fa. i ; t ; t ; ; t ; ; ; ; Un objeto se define rnediante una serie de caracteres dentro de un rectángulo. byte l- - di¡nensión x (colurnnas del rectángulo) . byte 2 - dinensión y (fiLas del rectángul-o). bytes siguientes (l-ongitud totaf = dinensión x * dimensión y): caracteres que forman el objeto (por fil-as). E1 origen del objeto es Ia esquina superior izquierda de1 rectángul-o que define el objeto. Las posiciones en bl-anco de1 objeto no se represencan sobre pantalla, quedando inalterados Los caracteres que ocupan esas posi.ciones. E j e¡nplo: db 7 t i dimensión x (nro. de columnas) db 4 , i dimensión y (nro. de filas) r | db o t ; fil-al;dbtoor;fil-a2 ;dbroorrfila3 db tooooooor ; fi-Ia 4 t t Parámetros: params struc dw ? ; bp salvado por la subrutina retorno dd ? ; dirección de rétorno p1 dd ? i dirección parámetro 1 (ent) i x0ry0,atrrope, objero i x = col-unna deL origen de1 objeto (L palabra) del oriqen del objeto (L palabra) ; y = fila ; atr = atributo caracteres (1- byte) i ope = operación (l- byte): objeto t 0-borrar , L- dibujarobjeto ; objeto = primer byte que define e1 objeto params ends ; sÍmbol-os: rx equ 80 t resol-ución x (nro. de columnas) ry equ 25 ; resolución y (nro. dé filas) nret equ offset pl- - offset retorno ; arguménto de ret t Procedimientos externos: extrn paspunto:far datos segment para x0 y0 x y dw ? dhr ? dw ? d\n¡ ? i ¡ xorigenobjeto t yorigenobjeto , col-unna ;fila 391 c i i xdln ydin ; carácter ; atributo ; índj-ce sobre eje x ; indice sobre eje y i dimensión x objeto ; dirnensj-ón y objeto db? d\^¡ ? dw? dw? d\^¡ ! . ope datos codigo Án ends segmenc assume cs: codigo, ds: datos htrhl pasobj nnar:¡i i ^ nr<¡h-i push bp mov bp,sp i ; sal-var bp ;bp=sP ; salvar registros afectados hr!<h nrr qh ñrrch dc ac push ^Y si ; direccj-onar segmento dé datos con ds mov axrdatos mov dsrax i recoger parámetros l-es si, [bp].p1 ¡nov axres: Isi] mov x0rax add si,2 nov ax,es: Isi] nov yorax add si,2 mov al-res: Isi] mov aral inc si mov alres: Isj-] nna r'l inc si mov at,es3 [si] cmp a1r 0 jle fin tnov ah, 0 mov xdimrax inc si nov al,es: Isi] cmp al,0 j le fin 392 ; es = segmento, si : desplazamiento ; ax = col-unna ; x0 = col-umna si=si+2 ax = fila yo : fila si=si+2 aI = atributo a = atributo si=si+1 r'l = nnara¡ian nna = nnor¡¡iÁn "r" si-=si+1 aL : dimensión x del objeto ; xdj-n = dinensión x de1 objeto tsi=sj-+l; al- : dirnensión Y del objeto nov ahf 0 nov ydim,ax t ydin = dinensión y de1 objeto es: [si+l] es eI primer byte del objeto ; dibujo caracteres del" objeto mov j,0 ; Índice sobre eje y mov axryo ;y=y0 mov Y,ax t looP filas (j = O, I, ... , Ydin-l) i bucley: mov i,0 ;indice sobre eje x mO\¡axrxoiX=X0 mov xrax t loop columnas (i = 0, 1, ... , xdj-n-l) bucl-ex: inc si ; carácter del objeto mov alres: Isi] mov cral cmp dlr t t ; si es bl-anco, ignorarlo je nuevo cmp ope,1 ; si operación = borrar, escribir blanco je dib mov c,, , i escribir carácter y atributo en posición (x,y) de l-a panta]la push ds l-ea ax, x i x,y,c,a push ax ca]l- paspunto ; chequeo fin columnas inc i inc x mov ax, i cmp axrxdim jI buclex ; chequeo fin filas inc ) inc y mov axrl cmp axrydin jI bucl-ey i restaurar reglstros afectados fin: pop si pop ax pop es PoP ds 398 pasobj codigo mov sp,bp pop bp ret nret endp ends end 394 r sp = bp ; restaurar bp PASPUNTO.ASM i ; Subrutina: PASPUNTO. t Descripción: t Escribir carácter y atributo en una posición determinada ; de 1a pantalla alfanunérica. ; se accede directarnente a 1a memoria de pantall-a. ; supone página 0. i Se ignora l-a lLamada si Las coordenadas caen fuera de l-os lÍrnites. ; Parámetros: params struc dbt ? t bp salvado por Ia subrutina retorno dd ? ; dirección de retorno pL dd ? i dirección parárnetro 1 (ent) xrYrc'a x = colu¡nna (1- paLabra) y : fila (1 palabra) (1 byte) c = carácter a escribir a = atributo del carácter (l- byte) params ends ; SÍmbolos: pantalla equ 0b800h ; dirección mernoria de pantal-l-a rx equ 80 i resolución x (nro. de colurnnas) ry equ 25 ; resolución y (nro. de fil-as) nret equ offset p1 - offset retorno ; argurnento de ret i ; ---------- codigo segment assurne cs: codigo publ-ic paspunto paspunto proc far push bp mov bp,sp ; safvar bp ; bp = sO ; --i salvar registros afectados push es push ax push dx push si push di i recoger parámetros tes si, [bp].p1" mov axres: [si] mov cs:xrax cmp ax,0 jl fin cmp ax, rx-ljS fin ¡nov axres: [si+2] nov cs:yrax cmp axr0 jI fin crnp ax , ry- l- i es = segmento, si = desplazamiento ; ax = colunna ; x : colu¡nna ; ax : fila ty=fila 395 jg fin mov aJ-res: Isi+4] mov cs:c,aI i al- = carácter a escribir ic =carácteraescribir mov alres: Isi+5] t aI = atributo mov cs:a,al t a = atributo t ; di.reccionar mernoria de pantalla con es mov ax, pantall-a mov esrax cál-culo del desplazamiento sobre l-a memoria de pantaLla: di=y*2*rx+x*2 mov dx,0 mov ax,2*rx nul- cs: y rx i ax=y*2* mov dirax ; di=y*2* rx mov dxr0 mov ax,2 mul cs:x i ax=x*2 add di,ax ; di=y*2*rx+x*2 i nover carácter y atributo a nenoria de pantalla ¡Ttov aI , cs: c mov es: [di],al mov alrcs:a ¡nov es: Idi]+l_,al i i restaurar registros afectados fin: pop di pop si pop dx pop ax pop es i --- ¡nov sp, bp pop bp rof nré+ ;sP=bP i restaurar bp paspunto endp ; ---------- ; variabLes ; --------xdhr? swt I cdr)! i codigo 396 ends end ; col-urnna r fila i carácter ; atributo PASRASTE.ASM Subrutina: PASRASTE. Descripción: Dibujo de un carácter raster por Ia pantalJ-a al-fanumérica. Los códigos AScIf posibles son de o a 255. Para tos códigos l-28 a 255 es necesario haber ejecutado previamente el comando GRAFTABL, que carga una tabla en rne¡norj-a de definición de estos caracteres. Dirección tabla ROM (caracteres O a L27) ! F00o:FA6E. Dirección tabl-a RAM (caracteres I28 a 255): La del- vector de interrupción lFh. Los caracteres se defi-nen en una rnatriz de I x 8. Co¡no ejenplo de definición, el carácter A = 4Lh = 65: db 03 0h, o78h, occh, occh, ofch, occh, occh, 00oh Bits Byte 765432LO binario hex 0 t_ 0011.0000 30h 78h 2 3 4 5 6 xx xxxx 0111 1000 1l-00 l_l-00 t-t-00 l-1-00 XX XX XX XX X XXXXX XX XX XX XX 1-111- t 100 t-l-o0 1100 l-t-00 1100 o000 0000 7 cch FCh cch cch 00h Parámetros: params struc dw retorno dd p1 dd params enos bp salvado por la subrutina dirección de retorno dirección parámetro l- (ent) (9 bytes) x,y,xm,yrnrcódigo x = columna esquina superior carácter (1 palabra) y = fila esquina superior carácter (1 palabra) xm = ta¡naño en x de cada punto (1 palabra) ym = tanaño en y de cada punto (1 palabra) código = código del carácter (0 a 255) (L byte) Símbolos: car equ |tln ; carácter a dibujar nret equ offset p1 - offset retorno ; argurnento de ret Procedimientos externos : extrn nasbloc:far datos datos segment para x0 y0 xm ym x1 ylx2 y2 c ends d$r ? dw? dv¡ ? dw? dw? dw ? dw? dw? db car x esquina superior izquierda y esquina superior izquierda tarnaño en x de cada punto del carácter tamaño en y de cada punto del- carácter x inicial bloque y inicial bloque x final- bloque y final- bloque carácter a dibujar 397 --------------codigo segrnent para assurne cs:codigo,ds:datos pubLic pasraste pasraste proc far push bp ; salvar bp nov bprsp tbp=sp t ', --- ; sal-var registros afectados push ds push es push ax push bx push cx push dx push sj- ; direccionar segmento de datos con ds mov ax,datos mov dsrax parámetros de entrada recoger i l-es si, [bp].pl; es = segmento, si = desplaza¡niento mov ax,es: [si] ; x esquina superior izq. mov x0rax mov ax,es: Isi+2] i y esquina superior izq. mov y0rax mov ax,es: [si+4] i tarnaño en x de cada punto mov xmrax mov ax,es: [si+6] i tarnaño en y de cada punto mov ymrax mov al-,es: [si+8] t a] = código de1 carácter i ver si código en la tabla ASCII ROM (O a L27) o en fa tabla ASCfI ; extendida RAM (cargada con GRAPHTABL) cnp aI,L27 ja éxten ; comparar código cor. I27 ; bifurcar si superior tabla ROM (caracteres O a L27) buscar carácter en 1a tabl-a de generación de caracteres gráficos rnov si,0fa6eh ; sí = desplazarniento comienzo tabLa direccionar segnento RoM con ds nov dxrds mov bx,0f000h mov dsrbx jmp despl-a 398 ; salvar ds i ds = seqrnento ROM t tabla RAM cargada por GRAFTABL en Ia dirección apuntada por eI vector ; de interrupción l-Fh exten: sub a1,L28 i restar l-28 i direccionar segmento RAM con ds nov dx,ds ; salvar ds nov bxr 0 nov ds,bx ;ds=0 nov si,ds: []-Fht 4I ; desplazamiento nov bx,ds: []-Fh*4+21 t segnento mov dsrbx i ds = segrnento tabla RAM despl-a: ; ax = a1 * 8 (desplazarni.ento de Ia definición en 1a tabl-a) r (8 es la longitud de cada definición en la tabla) cbr4r sa1 sal saladd add axr l ax,1 ax,lsirax sí,7 ;aX=al ; aX = aX*2 ; aX = ax*2 ; ax = ax*2 t si. = desplazamiento conienzo definición ; si = despLazaniento fin ; al¡nacenar la definición deL carácter en la pila rl" mov cxrS std 3 lodsb push ax loop rl- car. definición car. ; 8 bytes ; dirección hacia atrás i aI = ds:tsil, si = si - 1 ; ponerlo en 1a pila mov dsrdx ; restaurar ds ; obtener eI punto inicial mov axrx0 mov xlrax mov ax,y0 mov y],,ax t2i x]- = x0 y1=y0 mov cx,8 pop dx contador de I fiLas nov axrym dec ax add ax,yL ¡nov y2 , ax al=yn ¿¡¡=yrn-1ax=y1+yn-L y2=yL+yn-L push cx obtener siguiente fila salvar contador mov cxrS contador de 8 bits mov ax, x¡n dec ax add axrxl mov x2,ax al- = xrn test d1,80h )z 14 ax=xm-1 ax=xl-+xn-L x2=xL+xm-1 chequear bit bifurcar si cero 399 push ds lea axrxl ; dirección de xI,yLtx2,y2.c push ax call pasbloc escribir caracteres en eL rectángulo (x1,yl-) - (x2,y2) mov axrxz inc ax mov xlrax rol- dI, ll-oop 13 pop cx ax:x2 ax:x2+1 xl=x2+1 e1 bit izquierdo de d} es el nuevo bj-t bucle para punto siguiente restaurar contador filas mov axrxO ;ax:x0 I¡lov x1, ax ;x1:x0 nov axry2 i ax=y2 inc ax ;ax=y2+L mov yl-, ax ;yL=y2+I loop 12 t bucle para siguiente fil-a ,' restaurar registros afectados pop pop pop pop pop pop pop dx cx bx ax es ds mov sprbp pop bp ret nret pasraste endp codigo lmo ends end ;sp=bp ; restaurar bp PASTEXTO.ASM ; ; Subrutina: PASTEXTO. ; Descripción: ; Escribir un texto por pantaIla. ? ¡'l dél imifadnr .ie fin de texto es eI carácter $. i ; Parámetros: c+ rrr^ dr¡¡ ) retorno dd prdd params ends ; bp salvado por l-a subrutina t dirección de retorno t dirección parárnetro 1 (ent) ; texto a escribir. i Sínbol-os: nret equ offset pl - offset retorno ; argumento de ret ; ; ---------- codigo segment assume cs:codigo hrhl ic háetexto i pastexto proc far push bp mov bp,sp ; salvar bp ; bp : sp salvar reqistros afectados push ds push ax push dx recoger parámetro de entrada lds i ds = segnento, dx = despfazamiento escribir texto mediante interrupción DOS mov ahr9 i función: escribir texto por pantalla int 2l-h r lfariar aI DOS dx, [bp].p1 restaurar registros afectados pop dx pop ax pop ds mov sp,bp pop bp ret nret ;sp=bp ; restaurar bp pastexto endp ¡nA i an on¡ic end ¡101 PASTXT.ASM Subrutina3 PASTXT. Descripción: Escribir texto directamente en La memori.a dé pantalla. El delirnitador de fin de téxto es e1 carácter g. Respeta los atributos asociados a cada posición de la pantalla. Supone página 0. Se ignoran los caracteres de entrada que queden fuera de 1os lÍ¡nites de la rnemoria de La página. Paránetros: params sEruc dr^t ? ; bp safvado por 1a subrutina retorno dd ? t dirección de retorno pldd ? ; dirección parárnetro l- (ent) : x,y,n,texto i x = columna (0 a 79) (t byte) (1 byte) r y = fila (0 a 24) i n = nro. de caracteres a escribir (l- palabra) ; texto = texto a escribir params ends ; Símbolos: pantalla equ 0b800h ; segmento ¡nernoria de pantalla nret equ offset pl- - offset retorno ; argumento de ret t ; ---------- codigo segment para assume cs:codigo public pastxt i pastxt proc far push bp ¡nov bp, sp ; salvar bp ;bP==n i --; salvar registros afectados push ds push es push ax push bx push si nrrch Ái i i recoger parámetros de entrada lds si, [bp].p1 mov bl,ds: Isi] ds = segnento, si : desplazarniento inc si mov bh,ds: Isi] bn = y (rrra) inc si mov cxrds: Isi] add sí,2 Ll _ ., t uvr si=si+:. si=si+lcx = nro. de caracteres a escribir ; ds: [si] apunta aI primer carácter de texto ; direccionar memoria de pantalla con es ññ\r ^v h^htalIa n2 u¡"r ra ,, mov es,ax cál-culo de1 desplazarniento sobre la memoria de pantalla: di=y*160+x*2 desplazamiento máximo = 24 * L6O + 79 * 2 = 3998 = 4OQO - 2 mov a1 , l-60 mu1 bh nov di,ax mov al,2 mul bl add di,ax cmp di,4000 jae fin ;ax=y*160 ;di=y*160 ;ax:x*2 ,di:Y*160+x*2 r ¿dentro de la páqina 0? hi f,r¡¡rr i bucle caracteres deL texto de entrada bucle: mov alrds: Isi] ; carácter de entrada mov es: ldi],a1 ; carácter de salida inc si ; siguiente carácter add dí,2 ; siguiente posición en Ia rnernoria 1 rvvP ^^ñ Lrr^1 vqvrs ^ ; restaurar registros afectados rln: di bx ax es ds mov pop pastxt endp codigo ends sp, bp nrét sp=bp restaurar bp end 403 PASTXTRA.ASM Subruti-na: PASTXTRA. Descripción: Escribir texto en pantalfa alfanu¡nérica mediante la definición los caracteres raster. El delinitador de fin de texto es eL carácter S. de Paránetros: params struc dw retorno dd prdd params ends ? ; bp salvado por 1a subrutina ? ; dirección de retorno ? ; dirección parárnetro l- (ent) i xryrxmrymrtexto ; x = coJ-unna esquina superior izquierda (0 a 79) (1 paLabra) ; esquina superior izquierda (o a 24) ; y = fila (1 palabra) t ; xm = tamaño en x de cada punto (1 palabra) ; ym = tamaño en y de cada punto (1 palabra) t téxto - texto a escribir SÍmbol-os: pantalla equ 0b80oh ; dirección memori-a de pantalla nret equ offset p1 - offset retorno i argumento de ret Procedimientos externos: extrn pasraste:far Macros: if linclude pamcur.asm endif datos segment xdw?; ydü¡?¡ xndw?¡ ynd\d?¡ coddb?; del-tax dw datos x esquina superior izquierda y esquina superior izguierda tamaño en x de cada punto tamaño en y de cad.a punto carácter a representar ¡ separación entre dos caracteres sucesivos ? ends ---------codigo segment assune cs:codigords:datos t hrrhl i c n: qtXtf tssv a i pastxtra proc far push bp lan cn yy,"y'-y sal-var reqistros afectados push ds N4 ;.l-\h salvar bp = <h push es push ax push bx push cx push si push di direccionar segmento de datos con ds mov ax,datos mov ds,ax recoger parámetros de entrada l-es si, [bp].p1 mov ax,es:[si] mov x,ax ; es = segnento, si = desplaza¡niento ; ax = x (colunna) i x add si,2 mov ax,es: Isi] mov Y,ax iax=y(fila) add sj-,2 mov axres: Isi] mov xm,ax i ax = xn (tanaño en x de cada Punto) add sí,2 mov ax,es: [si] mov ymrax ; ax = yrn (tamaño en y de cada punto) ;XM add si,z t es: [si] apunta a1 primer carácter calcular deltax = separación en x entre dos caracteres = 8*xm mov ax,xm ,'aX=Xm tnov cl , 3 tcI=3bitsadesplazar sh1 ax,cl t ¡Trultiplicar por I mov deltax,ax t delta = 8*xm i posicionar cursor en (x,y) pancur bl,bh ; ; bucl-e caracteres del texto de entrada bucl-e: nov al-fes3[si] ia Je i ; representar al fin |(| carácter mov cod,al ; carácter de entrada ¿fin texto? si, bifurcar raster i cod = carácter push ds Lea ax,x push ax ea11 pasraste inc si nov ax,deftax add xrax siguiente carácter x = x + deltax (siguiente Posición) ¿t05 j¡np bucLe ; restaurar registros afectados fin: pop di pop si pop cx pop bx pop ax pop es pop ds mov sprbp pop bp ret nret pastxtra endp i cod j-gto ends end 406 sp=bp restaurar bp PASVECTO.ASM Subrutina: PASVECTO. Descripción: Dibujo por pantalla alfanumérica de un objeto definido mediante una l-ista de vectores. cada vector se define mediante tres campos: campo 1 (1 byte) = operación: A = pluna arri-ba, B = pfuma abajo campo 2 (L pal-abra) = coordenada x respecto a l"a esquina superior. campo 3 (1- palabra) : coordenada y respecto a l-a esquina superior. EI final- de Ia lista de vectores se indica mediantetrFrr. Ej enplo: (tAt r0r0)r(,Br ,2L,O>r< tBt,0,11>,<,Bt ,2).,l-1>,<rAr ,8,5) ,< tBr,l-6,5> <rFr ror0> 0l-2 00 XXXXXXXXXXXXXXXXXXXXXX 1 X ^ X J X 5 XXXXXXXXX 7 x I 9 x 10 x x XXXXXXXXXXXXXXXXXXXXXX l- Parámetros: params struc dr¡¡ retorno dd p3 dd p2 pr- dd dd params ends bp safvado por J-a subrutina dirección de retorno direccj-ón parámetro 3 (ent) lista de vectores que definen e1 objeto dirección paránetro 2 (ent) (1 pal-abra) y (fila) esquina superior de1 objeto dirección paránetro 1 (ent) (l- pafabra) x (cofunna) esquina superior del objeto i SÍmbolos: xfac equ 1 ; factor de nultiplicación en x ; factor de rnultiplicación en y ; carácter a dibujar t atributo del- carácter (normal) pL - offset retorno i argumento de ret ; Procedimientos externos: extrn pasl-inea: far r'€á^ ód,r 1 car equ ttltt atr equ 07h nret equ offset 407 datos segnent para i estructura de un vector vector struc dr¡/ ? dw? ; coordenada x i coordénada y vector ends xo dw? . y0 d!¡? xl_ dw ? y], dr¡/ ? x2 dw? y2 dw? c db car a db atr datos ends ; ; x esquina superior izquierda t y esquina superior izquierda t x iniciaf linea ; y inicial 1ínea ; x final l-inea Iínea , y final ; carácter a dibujar ; atributo del carácter ---------- codago segment para assune cs:codigords:datos publ-ic pasvecto pasvecto proc far push bp i. Lñsalvar bp nov bprsp ^* ,!}J-JP saLvar registros afectados push ds push es push ax push cx push dx push si i direccionar segmento de datos con ds mov ax,datos mov dsrax ; recoqer parámetros de entrada l-es si, Ibp].p1 es = segmento, si = desplazamiento mov axres: Isi] x esquina superior izq. mov xOrax les si, [bp].p2 es = segnento, si = desplazamiento y esquina superior izq. mov axres: Isi] mov y0,ax 1es si, Ibp].p3 es: [si] = fista de vectores i recorrer 1a lj-sta de vectores mov alres: Isi] [Ftr ^1 je fin 408 i -^ ^:r f9u uuu ; ¿fin de la lista? . ci f in ; actuafizar coordenada x posición actual. mov ax,x2 ;xI:x2 mov x1, ax mov ax,es:[si+1] i ax = x vector mov cx,xfac mul" cx ; multiplicar por ef factor de esca]a en x add ax,xO i x2 - x0 + x mov x2,ax i actuafizar coordenada y posición actual, mov ax,y2 iY).=Y2 nov yl- / ax mov ax,es: [si+3] i ax = y vector mov cx,yfac nul cx ; multiplicar por e] factor de escala en y add ax,yo , y2 = y0 + y mov y2,ax i ; ver eI tipo de operación cmp byte ptr es: [si] 'ia ¿ ; rrAn ; ¿pluna arriba? ; si ... bifurcar ; dibujar 1Ínea entre (x1,y1-) y (x2,y2) push ds Iea axrxl push ax ca1 1 na<1 ing¡ i ; dibujar l-Ínea ; siguiente vector nas: add si,si-ze vector j¡np vec ; bifurca! ; restaurar registros afectados fin: pop pop pop pop pop pop ñ^clra^+^ dx cx es mov sp,bp pop bp rét nret ; sP=bP i restaurar bp 6h.lñ i i -^v ^^r ry uvq end 409 21 La pantalla enm odo gráf¡co En modo gráfico, la unidad representable en pantalla es el pixel, que tiene un determinado color asociado. Con el adaptador de color/gráficos, el número máximo de colores posibles es de 16 (4 bits). Los colores posibles siguen el esquema IRGB (véase el capítulo anterior). No existe en modo gráfico el parpadeo (blink) de un pixel (a menos que así se programe). Bancos de me¡.noria La memoria (buffer) de pantalla está dividida en "bancos". Cada banco corresponde a una serie de líneas. El primer banco corresponde a las líneas pares, y el segundo, a las impares. El tamaño de cada banco es de 8 Kb, es decir, la mitad de las 16 Kb de la memoria de pantalla. 410 Dirección Bonco Líneas Tamoño (hexadecimal) 0 pares (0, 2, 4, ..., 198) I impares (1, 3, 5, ..., 199) 2000h: 8 Kb 2000h: 8 Kb 8800:0 :88000 BA0O:0 = BA000 Los bancos empiezan en una dirección par de Kb. El espacio ocupado realmente dentro de cada banco es de 8000 bytes; por tanto, se desaprovechan 8192-8000: 192 bvtes. área líneas pares B800h:0 B8ú0h:lF40h: B9F4h:0 ebooh:zoooh 8000: lF40h bytes (0,2, 4, ..., 198) 192: COh bytes área no utilizada : BAooh:o área líneas impares 8800h:3F40h : BBF4h:0 8000: lF40h bytes (1, 3, 5, ...,199) = COh bytes área no utilizada 192 Algunos compatibles IBM PC soportan la resolución de 640 x 400 (superalta). En este caso, la organización de los bancos de memoria es la siguiente: Banco 0 I 2 J Líness múltiplos de 4 mós 0(0,4, 8 I (1,5, 9 2 (2,6, l0 3 (3,7, ll Tamaño 196) 2000h:8 Kb r97) 2000h 198) r99) :8 Kb 2000h:8 Kb 2000h :8 Kb Dirección (hexsdecimal) 8800:0 : 88000 BA00:0: 84000 BC00:0: BC000 BE00:0 : BE000 Al final de cada banco se desaprovechan también 192 bytes. 8000: lF40h b¡es árealíneas4+0 (0, 4, 8, ..., 196) 192: COh bytes área no utilizada B800h:0 B800h:lF40h: B9F4h:0 árealíneas4+l B800h:2000h: BA00h:0 B800h:3F40h: BBF4h:0 8000: lF40h bytes (1, 5, 9, ...,197) 192: COh b¡es área no utilizada 8000: lF40h bytes árealineas 4 + 2 (2, 6, 10, ..., 198) 192: COh bytes área no utilizada 8000 = 1F40h bytes árealíneas4+3 (3,7, ll, ..., 199) 192: COh bytes área no utilizada B800h:4000h: BC00h:0 B800h:5F40h: BDF4h:0 8800h:6000h : BE00h:0 B800h:7F40h: BFF4h:O 411 Representación de los pixels en la memoria de pantalla Cada pixel ocupa uno o varios bits de la memoria de pantalla, dependiendo del tipo de resolución: Resolución Bits/Pixel Pixels/Byte Colores 160 x 100 320 x 200 640 x 200 4 2 4 16 (0 a 15) 2 I 8 Paletas I a(0a3) 2(0y1) 2 I Sólo la resolución media (320 x 200) y la alta (640 x 200) están soportadas por el BIOS y son las que vamos a considerar. En alta resolución (640 x 200) existe un bit por pixel. Los colores son: el 0 (negro o punto apagado) y el 1 (blanco o punto encendidc). Existen 8 pixels por byte: CCCCCCCC C Color 0 0 (negro) I I (blanco) En media resolución (320 x 200) y en superalta resolución (640 x 400), hay dos bits por pixel, es decir, hay 4 pixels por b¡e. Los colores posibles son cuatro: C,q Cr Ct Cr C. Cl C. Cr Ct Color 00 0l 10 11 0 (fondo) 1 de la paleta 0 ó I 2 dela paleta 0 ó I 3 de la paleta 0 ó I El color del fondo es uno de los 16 posibles. Por defecto es el cero (negro), pero puede cambiarse a cualquier otro color. Los colores de las paletas son: Color Pqleta 0 I Verde 2 Rojo Marrón J 412 Paleta l (estóndsr) Azul-Verde (cyan) Magenta Blanco El número de bytes ocupados en cada fila (par o impar) es de: . 640 x 200: 640 pixels x I bit/pixel :640 bits : 80 bytes. . 320 x 200: 320 pixels x 2 bits/pixel : 640 bits : 80 bytes. Como existen 100líneas por banco, el espacio ocupado por cada uno de ellos es de 80 x 100:80O0 bvtes. Localización y acceso en la memoria de pantalla del pixel (x,y) Una manera, la más rápida, de dibujar por la pantalla es mover información directamente a la memoria de pantalla. Caso alta resolución (640 x 200) l. Localización del byte y del bit osociado ol pixel Vamos alocalizar el b¡e dentro de la memoria de pantalla y el bit dentro del byte que corresponde al punto (x,y). Entrada: x: columna (0 a 639) Y: fila (0 a 199) c: color (0 ó l) Salida: d : desplazamiento respecto a la dirección B800h:0. b : número del bit (0 a 7) del byte. . Desplazamiento correspondiente a fila par o impar: Si fila par dl :0 En caso contrario dl : 8192:2000h r Desplazamiento correspondiente al número de fila: d2 : cociente(fila/2) * 80 : cociente(y/2) * 80 r Desplazamiento correspondiente al número de columna. d3 : cociente(columna/8) : g6.¡.tte(x/8) o Desplazamiento total d: dl + d2 + d3. o Resto r : resto de la división (x/8). 413 Este resto es el número del bit afectado (de izquierda a derecha) empezando con cero. Por tanto: ¡ Número de bit b:7-r. 2. Acceso al bit Para acceder al bit se rotan a la izquierda r bits (instrucción ROL). De este modo, el bit 7 del b¡e (primero de la izquierda) contendrá el bit correspondiente al pixel (x,y): 76543210 alb b b b b b b -bits Si el color (c) está en un b¡e, se desplazan 7 bits a la izquierda (instrucción SHL) para que el bit del color sea el primero lelaizquierda: c10000000 Se pone a cero el bit izquierdo del byte de memoria haciendo la operación AND con 7Fh: bbbbbbb tttttl 0 lllllll a AND Olb b b b b b b Se pone el color en el bit izquierdo del b¡e de memoria mediante la operación OR entre el byte de memoria y el b¡e de color: 0 btbtbrb,b,b,b 0,0,0,0,0,0,0 clb b b b b b b 414 OR o Se colocan los bits en su sitio, rotando a la derecha r bits (instrucción ROR). Caso alta resolución (320 x 200) 1. Localizoción del byte y de los 2 bits asociodos al pixel Vamos alocalizar el byte dentro de la memoria de pantalla y los dos bits dentro del byte que corresponde al pixel (x,y). Entrada: x: columna (0 a 319) y: fila (0 a 199) c: color (0 a 3) Salida: d : desplazamiento respecto a la dirección B800h:0. b: número del bit inicial (0 a 7) del byte. o Desplazamiento correspondiente a fila par o impar: Si fila par dl :0 En caso contrario dl :8192:2000h o Desplazamiento correspondiente al número de fila: d2 : cociente(flla/2)* 80 : cociente(y/2) * 80 o Desplazamiento correspondiente al número de columna. d3 : cociente(columna /4) : s6.i.tte(x/4\ o Desplazamiento total d: dl + d2 + d3. o Resto r = resto de la división (x/4). r El doble de este resto es el número del bit inicial afectado (de izquierda a derecha) empezando con cero. Por tanto: ¡ Número del bit b : i -2 x r. (Los bits del pixelson el b y el b + 1). 2. Acceso al bit o Para acceder a ambos bits se rotan a la izquierda 2 x r bits (instrucción ROL). Dp este modo, Ios bits 7 y 6 del byte (los dos primeros de la izquierda) contienen los bits correspondientes al pixel (x,y): 415 0 76 a,alb'b'b'b,b,b - bits Si el color (c) está en un byte, se desplazan 6 bits a la izquierda (instrucción SHL) para que los bits del color sean los dos primeros de la izquierda: c,c10,0,0,0,0,0 Se ponen a cero los dos bits de la izquierda del b¡e de memoria haciendo la operación AND con 3Fh: 4ta btbtbtbtbtb oic lt lt 1t1t1tl 0,0lb AND b'b' b,b Se inserta el color en los dos primeros bits de la izquierda del byte de memoria mediante la operación OR entre el byte de memoria y el byte de color: 0,0 br br btbrb rb c¡c 0f 0l0t0t0t0 OR c,clb'b'b,b,b,b Se colocan los bits en su sitio, rotando a la derecha 2 x r bits (ins- trucción ROR). La generac¡ón de caracteres en modo gráfico Son los llamados caracteres de barrido (raster). En el adaptador de color/gráficos y en modo gráfico, la generación de caracteres es la siguiente: 416 o Los códigos 0 a I27 están en la memoria ROM del BIOS. La dirección de esta tabla ROM es: F000h:FA6Eh. Cada carfucter se define mediante 8 bytes. La longitud de la tabla es de 128 x 8: I Kb. o Los códigos 128 a 255 están en una tabla RAM. Esta tabla se carga con el comando GRAFTABL del DOS. La dirección de esta tabla RAM es la del vector de interrupción lFh. Los caracteres se definen de la misma forma y su longitud también es de I Kb. La dirección de esta tabla está contenida en 0:lFh*4:0:7Ch :7Ch. En resumen: Tabla Carocteres Dirección l (RoM) 000 a 127 128 a 255 F000h:FA6Eh La del vector de interrupción lFh 2 (RAM) Sería posible, por supuesto, crear nuestra propia tabla, dejándola residente en memoria, y cargar su dirección en el vector de interrupción lFh. Sería como hacer un GRAFTABL alternativo. Un programa ejemplo es PGPTABLA.ASM. En el listado BIOS del Manual de Referencia Técnica, las definiciones correspondientes a la primera letra del alfabeto son: DB 030h,078h,0cch,0cch,0Fch,0cch,0cch,000h ; A : 4lh : 65 DB 000h,000h,07 8h,00ch,07ch,0cch,076h,000h ; a : 6lh : 97 Es decir, existen 8 bytes por cada definición de carácter, uno por linea (de arriba a abajo). Los bits de cada b¡e indican los puntos activados dentro de cada linea. Para los caracteres que estamos considerando: Byte 0 I 2 J 4 5 6 n Bits 76543210 XX XXXX XX XX XX XX XXXXXX XX XX XX XX Binqrio Hexsdecimal 001 I )000 30h 78h 0lll t000 I 100 l 100 t 100 t 100 CCh cch ll11 t 100 FCh l 100 t 100 CCh CCh I 100 I 100 0000 )000 00h Byte Bits 76543210 0 I 2 J 4 5 6 XXXX XX XXXXX XX XX XXX XX Binsrio Hexqdecimql 0000 0000 0000 0000 00h 00h 78h 0ch 01ll 1000 0000 ll00 0lll ll00 ll00 ll00 0l1l 0ll0 0000 0000 7 Ch CCh '7 76h 00h Para escribir texto en modo gráfico, hay que posicionar el cursor como si la pantalla estuviera en modo alfanumérico. A continuación se escribe el texto mediante la interrupción correspondiente. Hay que tener en cuenta: o No es posible mover los caracteres directamente a la memoria de pantalla, pues los bits serían interpretados como pixels. o No existe control del color del fondo (supone el color del fondo por defecto). Aplicaciones Programas Dibuja líneas por pantalla en modo gráfico. Prueba subrutina PGSLINEA. PGPOBJ Dibuja objeto por pantalla en modo gráfico con animación a través de las teclas de movimiento del cursor. Prueba subrutina PGSOBJ. PGPRASTE - Prueba subrutina PGSRASTE. El programa representa en pantalla gráfica el carácter ASCII asociado a cada tecla. PGPTABLA - Ejemplo de instalación de una tabla de caracteres gráfi- PGPLINEA cos extendidos. PGPTXTRA - Prueba subrutina PGSTXTRA. Escribe un texto mediante caracteres raster. PGPVECTO - Prueba subrutina PGSVECTO. Subrutinas PGSBLOC 418 Dibujar sobre pantalla gráfica un rectángulo relleno de un color determinado. PGSBORRA Borrar la memoria de pantalla (16 Kb) con ceros bi- narios. Escribir una línea en pantalla (modo gráfico). Se utiliza el algoritmo de Bresenham. Prueba subrutinas PGSPUNTO, PGSPUNX y PGSPUNXX. PGSOBJ Representar o borrar objeto por pantalla gráfica. PGSPUNTO Poner color en una posición de la pantalla gráfica. PGSPUNX Dibuja un punto sobre la pantalla gráfica en alta resolución mediante acceso directo a la memoria de pantalla. PGSPUNXX - Dibuja un punto sobre la pantalla gráfica en media resolución mediante acceso directo a la memoria de pantalla. PGSRASTE Dibujo de un carácter raster por la pantalla gráfica. PGSTXTRA Escribir texto en pantalla gráfica mediante la definición de los caracteres roster. El delimitador de fin de texto es el carácter $. PGSVECTO - Dibujo por pantalla gráfica de un objeto definido mediante una lista de vectores. PGSLINEA 419 PGPLINEA.ASM Programa: PGPLINEA. Descripción: Dibuja lineas por pantalla en modo gráficb. Prueba subrutina PGSLINEA. Símbolos: nrectas equ 8 modo 6 equ if nodo eq6 rx equ ry equ else rx egu ry equ endif número de rectas a dibujar modo pantalla gráfica: 4 - 32O x 2OO color ' 5 - 32O x 2OO b/n 6 - 640 x 2OO b/n resolución x (columnas) resolución y (fitas) resolución x (columnas) resolución y (filas) 640 200 320 200 ; Procedimientos externos: extrn pgslinea:far extrn tesesper:far ; Macros: if1 include vimdef.as¡n endif ,.. ; i ---------- pila pila segment stack db 128 dup ( I pil-ar ) ends datos segnent para xl- dw? dht dw? d\^t db rr x2 y2 color ? ? l- i coordenada x punto 1 i coordenada y punto l; coordenada x punto 2 i coordenada y punto 2 ,' color ; definición estructura de una I Ínea linea struc dhr ? x iniciaL y inicial dI^¡ ! x final dw? OI¡/ linea db1 ( col-or ends i i rectas a dj.bujar <0 , linea recta <0 , linea <rx-1' linea <rx/2' linea 420 rY/2, rY-!, rY-1, 0 , rx-L,ry/2 rx-1,0 0 ,0 rx/2,ry-L ,> ,> ,> ,> ,> linea linea Linea linea datos <0 ,3*ry/4 | rx-L,ry/4 ,> <rx/4, rY-I,3*rx/4,O t> <rx/4, O ,3*rx/4 ,tY-]- '> <o , ry/4, rx-L,3*ry/4t> ends i ---------- codigo segment pgplinea proc far assune cs:codigo,ds:datos,ss:pila ; poner en 1a pila 1a dlrección de retorno al DoS push ds sub ax, ax push ax direccionar segmento de datos con ds ¡nov ax, datos mov dsrax establecer modo de pantalla gráfica 640 x 2OO b/n vi¡ndef ¡nodo dibujar rectas mov cx,nrectas mov si,0 bucle: i nro. de rectas.¡. dibujar push ds lea ax,rectaIsi] push ax cal-1 pgsl-j-nea add si,type linea loop bucle ; apuntar a siguiente recta ; type de estructura es el nro. de bytes i esperar hasta leer una tecla cal-l tesesper i establecer modo de pantal-l-a alfanurnérica 80 x 25 b/n vi-ndef 2 i retorno a1 DOS ret pg-plinea endp ¡aA vvv i an v rY anÁe end PgPlinea 421 PGPOBJ.ASM Programa: PGPOBJ. Deseripción: Dibuja objeto por pantal-l-a en modo gráfico con ani¡nación a través de las teclas de movimiento del cursor. Prueba subrutina PGSOBJ. El- programa acaba puLsando Enter. sÍmbolos modo equ 6 3 modo 6, resolución 640 x 2OO b/n i nodo 5, resolución 32O x 2OO b/n i nodo 4, resolución 320 x 200 col-or i factor de nuLtiplicación del- incremento x , xfac equ 4 rrf¡n aarr . ? if rnodo eq 6 rx equ 640 ry equ 200 nhife a¡rr el" se rx ry hhi ¡¡vr +L- endif 1 equ 320 equ 200 factor de ¡nultipficación deI incrernento y i resolución x i resoJ-ución y . nro. de bits por punto i resolución x i resol-ución y ^-" sYu nro. de bits por punto Procedimientos externos : extrn pgsobj : far extrn tesfl-e:far Macros: if1 include vimdef.asm endif pila pila segnent stack db 128 dup ('pila') ends i datos segTment xinc yinc db db defobj x y nrobi-ts ope l-abel byte dr¡¡ rx/2 dw ry/2 db nbits db ? ? ? r definición de1 objeto if rnodo eq 6 db ).6 db8 db 001h,000h db oo2h,080h db 004h, 040h 422 lncremenEo en x Íncremento en y cornienzo definición objeto coordenada x origen del objeto coordenada y origen del objeto nro. de bits por punto operación sobre el objeto 0 - borrarlo 1 - dibujarlo i dimensión x (nro. de co1s.) (nú1tip1o de 8) ; dirnensión y (nro. dé fj.las) ¡ fiLa 2 db db db db .lh 008h,o20h t fila 01oh,010h r fila O20h,008h ; fila o40hf004h ; fila óffh nféh ? fila el-se ; dirnensión x (nro, de cols.) (múltiplo de B) ; di¡nensión y (nro. de filas) r fj.fa 1 ; fiLa 2 r fifa 3 ; fila 4 db I db 4 db 003h,000h db 007h,0c0h db 03ah,0b0h db Offh,ofch endif E'iéñnl ñ añ ál ^^c^ ^ó 4 5 6 7 8 t hif /ñ,rñt^. = 000000010000000 : 0000 0001 0000 000 0 : 01 ooh : 000000101000000 : 0000 001,0 1000 000 0 : 02 80h : 000001_000100000 : 0ooo 01-00 0l_00 000 o : 04 40h = 00001-0000010000 = 0000 1000 0010 000 0 = 08 20h = 000100000001000 = 0001 0000 0001 O00 0 = 10 10h = 001-0000000001-00 = 0010 0000 0000 100 0 = 20 08h = 01000000000001,0 = 0100 0000 0000 010 O = 40 04h xxxxxxxxxxxxxxx = 11111L1,111-11111 = 1111 l-l-11 l-11-1 11"1 0 = ff feh x x x x x x x x x x x x x Ejenplo en ef caso de 2 bits/punto: o indica color 3 = 11b x indica col,or 2 = 1-0b ó oxo oxxxo ooooooo = 00 00 00 11 00 00 00 = 0000 0011 0000 00 00 = 03h,00h = o0 00 1_1 10 11 00 00 = 0000 111-0 l-L00 00 00 = 07h coh = o0 LL L0 10 l-0 t_1" 00 = 0011 1010 l-oLl- 00 00 = 3ah boh = l-l- 11, l-1 1l- 11_ 11 11 = l-l-l_1 1l,l-1 1-111_ 11 00 = ffh fch datos ends codiqo pspobj segment para proc far assume cs : codigo , ds : datos , ss : pila ; poner en 1a pila Ia dirección de retorno aI Dos push ds sub ax, ax push ax i direccionar segmento de datos con ds mñ\r áv dAfOS mov dsrax ; --t definir modo de pantalla gráfico vimdef nodo 423 ; dj.bujar e1 objeto dibuj ar: mov ope,l push ds lea axrdefobj ; dibujar objeto ; definición objeto push ax call pgsobj leer tecla de movimiento de1 cursor o Enter i push ds lea axrxinc ; incrernento en x push ax push ds lea ax,yinc ; incremento en y push ax ,' arnplificar incrementos call tesfle mov alrxfac t xinc = xinc * xfac mul xinc mov xinc,aL mov al,yfac t yinc = yinc * yfac mu1 yinc mov yincral ; ver si se pulsó Enter emp x j-nc, 0 jne borrar cnp yinc,O je fin ; borrar e1 objeto borrar: mov ope,0 push ds 1ea ax,defobj i borrar objeto ; definición objeto push ax call pgsobj ; cambiar origen del objeto mov al,xinc cbhr;ax=xinc add xrax mov al,yinc cb$¡ add y,áX jnp dibujar ; al = xinc ix=x+xinc ; al = yinc ;ax:yinc +yinc ;y=y fin: t definj.r modo de pantalla al-fanurnérico 80 x 25 b/n vimdef 2 424 ; retorno a1 DOS pspobj i ^^v vvu ^^A ¡y endp end pgpobj 425 PGPRASTE.ASM Programa: PGPRASTE. ñ^^^-ih^iÁh. us>u! rPervr¡. Prueba subrutina PGSRASTE. Fl !¿ ñr^^F:há vYr y! q¡,¡e róñrécenta asociado a cada tecla. en pantalla gráfica ef carácter AscII El prograTna termina si se pul-sa l-a tecl-a Esc. Procedirnientos externos: extrn pgsraste: far extrn pgsborra: far Macros: ara include vimdef.asm endif segment stack pila pila ends datos segment x0 y0 xm yÍr cod dhr 160 dw 50 dw 16 dw 8 db ? datos ends ; I2A db dup ( 'Pila' ) ; x (colunna) esquj.na superior izquierda carácter esquina superior izquierda carácter ; y (fila) i tamaño en x de cada punto i tamaño en y de cada punto ; código ASCII (0 a 255) ---------- codigo segrnent pgpraste proc far assume cs:codigo,ds:datos,ss:Pila ; poner dirección de retorno aL DOS en la pila push ds sub axrax push ax i direccionar segmento de datos con ds mov ax,datos mov dsrax establecer modo de pantalla gráfica 640 x 2oo b/n vindef 6 tecla mov axr0 426 ; función: leer una tecla int l-6h i l-l-anar al- BIOS t ah = código 1, al = código 2 i ver si se pulsó Esc (ah = 01h, al- = Lbh) cnp ax,o1Lbh je fin mov cod,al t ¿tecfa Esc? t si ... bifurcar ; código ASCII i borrar pantal).a call pgsborra i representar el, carácter push ds ; x0 Lea ax,x0 push ax cal-1 pgsraste rln: j¡np leer i bifurcar a l-eer i ; establecer ¡nodo de pantalla al-fanurnérica 80 x 25 b/n vindef 2 ret i volver aI DOS pgpraste endp codigo ends end pgpraste 427 PGPTABLA.ASM Programa: PGPTABIA. Descripción: Ejemplo de instalación de una tabla de caracteres gráficos extendidos. Debe crearse un fichero tipo COM de este programa. se incluyen sóIo dos definiciones, que corresponden a los códigos ASCII t-28 y L29. Los caracteres se definen de la manera siquiente: Bits 22 31 XXXXXX XXXXXX XX XX XX XX XX XX XXXXXX XXXXXX :l !:i::: 3*:'_ O L28 1 2 3 4 5 6 7 )_29 0 XXX 2 3 4 5 6 XXX XXXXXX XXX XXX XXX r- xxx 7 9 :t:11:__ ::: 1100 111-1 FCh 1111 1l-00 FCh 1t-00 1100 cch 1100 11-00 cch 1100 1100 cch 1111 1100 FCh 1111 t-100 FCh 0000 0000 00h 1110 0000 Eoh 111-0 0000 Eoh Ll-l-0 0000 Eoh 1t-t-1, 1l-00 Fch 0001- l-100 l-ch 0001 1100 l-ch 0001 1t-00 1ch 0000 0000 00h La dirección de carga de esta tabla se alnacena en el vector de interrupción 1Fh. codigo : empezar: ; segment assume cs:codigo org 1O0h lnp instafar ; origen por ser fichero tipo coM ; bifurca a la rutina de inicialización ---------- ; tabl-a de caracteres gráficos (teóricamente de l-28 a 255) t (sólo se incluyen, a modo de ejemplo, los caracteres 128 y L29) iabla labe1 byte db oFch,oFch,occh,occh,occh,oFch,oFch,oo0h r Ascrr 128 db OEoh,0E0h,oEoh,oFCh,oLch,ol-Ch,O1Ch,000h t ASCII L29 ; instalación instalar proc i cambiar el vector de interrupción BIos mov ax,0 mov esrax 428 mov es: [1Fh*4],offset tabla mov es: [1Fh*4+2],cs ; desplazamiento i segmento ; escribir mensaje mov dx,offset nensaje mov ah,09h ; funcj.ón: escribi-r texto por pantalla int 21h r l-l-anar aI DoS dejar residente la tabla y volver a1 Dos mov dx,offset instalar i dx = ú1tina dirección + 1 int 27}) ; terminar, pero dejar residente nensaje db rlnstalada tabla de caracteres gráficos extendidosl db l-3,10, r9l 'i nc{- ¡ l Ar óñ¿lh ¡n^ian éhÁe pnd émñéze¡. 429 PGPTXTRA.ASM Programa: PGPTXTRA. Descripción: Prueba subrutina PGSTXTRA. Escri-be un texto ¡nediante caracteres raster. Procedimientos externos : extrn pgstxtra:far extrn pgsborra:far extrn tesesper:far Macros: if1 include vi.rndef . asm endif t pila p j.l-a segment stack db ends !2a dup (rpilar ) datos ; definición textol-: x,y,xn,ym ,' texto a escribir t definición texto2: x,y,xm,ym ; texto a escribir ; definición texto3: x,y,xm,ym t texto a escribir i x = colunna esquina superior izqulerda carácter esquina superi-or izquierda carácter , y : fila i xm = tanaño en x de cada punto t ym = tamaño en y de cada iunto texto3 dw O rO,8 r6 db 'AaBbCcDdEe$ ' dw O,60,8,6 db rfFgchHiIjJ$' dw O,).2O,8,6 db rKkLlMnNnOo$l datos ends textoldef2 texto2 def3 t ---------- codigo segment pgptxtra proc far assune cs:codigo, ds: datos, ss:pila ; poner dirección de retorno al- DOS en ta pila push ds sub axrax push ax direccionar segmento de datos con ds ¡nov ax, datos mov dsrax i establ-ecer modo de pantalla gráfica 640 x 2OO b/n vindef 6 ¿t30 h^FFiF h.ñ+^l -^ 1 I I ^ hdch^rrá representar textol push ds lea ax,defl ; defl push ax call- pgstxtra rÁhrócóhf^r l-évtó? push ds l-ea ax, def2 ; def2 push ax caII pgstxtra representar texto3 push ds Iea ax, def3 push ax cal-l- pgstxtra ; def3 esperar a que se pulse cualquier tecla -e l I +éca<har establecer modo de pantalla alfanurnérica 80 x 25 b/n vimdef i pgptxtra I -^u ^^r r9 uvu 2 ; volver aI Dos endp ^-J^ end pgptxtra 431 PGPVECTO.ASM Programa: PGPVECTO. Descripción: Prueba subrutina PGSVECTO. Después de dibujar el objeto, el prograrna ternina pulsando cualquier tec1a. Procedimientos externos : extrn pgsvecto:far extrn tesesper: far Macros: if1 incl-ude vi¡ndef . asm endif pila segment stack db pila ends L¿ó dup (rpiLar) ---------datos segment t dw L0 ; x (colurnna) esquina superior del objeto esquina superior de1 objeto ; y (fila) ; definición objeto mediante lista de vectores vector struc r código dvr ? i coordenada x det ? i coordenada y vector ends lista vector (tArr0rO)r(,Bt,2L,O>r<tBr,Orl-L>r<rBt r2Lr:-L> vector (tAt r8r5),(,8, r!6,5>,<rFr roro> datos ends x0 y0dw5 :-----:-,-- codigo segnent pgpvecto proc far assurne cs: codÍgo, ds: datos, ss:pila ; poner dirección de retorno al- DOS en Ia pila push ds sub axrax push ax i direccionar segmento de datos con ds mov axrdatos tnov ds, ax ;- - i poner modo de pantalla gráfica 640 x 2oo b/n 432 I vi-ndef 6 ; representar el objeto en 1a posición (x0,y0) push ds ; x0 1ea axrx0 push ax push ds lea ax,y0 push ax t y0 push ds ; fista de vectores 1ea ax, lista push ax call pgsvecto ; esperar a leer una tecla ca l I tesesner ; ; poner rnodo de pantalla alfanumérica 80 x 25 b/n vindef 2 ret ; volver al DoS pgpvecto endp codigo ends end pgpvecto 493 PGSBLOC.ASM Subruti-na: PGSBLoC. nacari ¡¡ i Dibujar ^n.sobre pantalla gráfica un rectángulo rel-Ieno de un cofor determinado. Parámetros: params sEruc dw? retorno dd prdd ? ? parans ends bp salvado por la subrutina dirección de retorno dirección parámetro 1 (ent) xL, y1, x2 ty2 , c x1,y1 = coordenadas iniciales x2,y2 : coordenadas finales c = col-or (9 bytes) (2 palabras) (2 palabras) (1 byte) t Sinbolos: nret equ offset pl - offset retorno ; argumento de ret i ; ---------- datos datos ; segmenE x dv/ ydw x1 d\^¡ yl- dw x2 dw y2 dw cdb xn dh¡ yn dr^¡ ends x genérica bloque y genérica bloque x inici.al- bloque rlini¡i^l hl^d,!ó x final b]oque color ^^,ró rr f i nr'l hl número de fil-as número de col,umnas ---------- codigo segment para assume cs:codigo,ds:datos public pgsbloc pgsbl-oc proc far push bp mov bP,sP i ; sa]var bp ; bp = sp salvar registros afectados push ds push es push ax push bx push cx push dx push si direccionar segmento de datos con rnov ax, datos mov dsrax recoger paránetros 434 Les si, [bp].plmov ax,es: Isi] mov xl-, ax mov ax,es: Isi+2] mov y1,ax mov axres: Isi+4] mov x2rax mov ax,es: Isi+6] mov y2,ax mov a1,es: Isi+8] mov c,al i es = segmenco, si = desplazamiento ix1 íx2 ,y2 cálcuLo de1 núrnero de filas y de columnas mov ax,x2 sub ax,xL inc ax mov xnrax i nro. de colunnas mov ax,y2 sub axryl inc ax mov ynrax i nro. de fil"as i bucl-e fil-as mov cxryn nov ax, yl, mov YrdX vvv: i nro. filas ;y=y1 ; bucle colu¡nnas push cx mov cxrxn mov axrxl mov x,ax xxx: i escribir punto en (x,y) push cx mov cxrx mov dxry mov al,c mov a}),L2 int 10h pop cx rncx 3 inc x loop xxx pop cx inc y loop yyy i nro. col-umnas ;x=x1 cx = x (colunna) ¿¡ = y (fila) al = color función: escribir punto Ilamar aL BTos ix=x+1 ;y=y+1 i ; restaurar registros afectados fin: pop si pop pop pop pop dx cx bx ax ¿t35 pop es pop ds mov sp,bp pop bp ret nret pgsbloc endp codigo ends end ¿136 sP:bP restaurar bp PGSBORRA.ASM Subrutina: PGSBORRA. ñ^^^-i ue-e! rPv -^ i Áh. . rv¡¡ Borrar la me¡noria de pantal-l-a (16 Kb) con ceros binarios. Simbo]os: pantal-l-a equ 08800h codÍgo ; segmento memoria de pantalJ-a (adaptador cGA) ; (oBoooh si adaPtador rnonocromo) segmenE assume cs:codigo public pgsborra pgsborra proc far i salvar registros afectados push es push ax push cx push dx push di direccionar seqmento de pantalla con es ¡nov ax, pantal-l-a ¡nov es , ax mov dir0 borrar 1a memoria de pantalla mov cxr 2000h cld ¡nov ax, o rep sEoshr cx = 16 Kb = 10h x L Kb = l-oh x 400h 4000h bytes = 2000h Palabras dirección hacia adelante ceros binarios es: [di] = ax' di = di + 2 recuperar registros aféctados pop pop pop pop pop dx cx ax ret pgsborra endp codigo ends end 437 PGSLINEA.ASM t r Subrutina: PGSLfNEA. ; Descripción: ; Escribir una línea en pantal-l-a (modo gráfico). ; Se utiliza e1 algoritrno de Bresenham. ; Prueba subrutinas PGSPUNTO,PGSPUNX y PGSPUNXX. i Parámetros: params struc dvt ? ; bp salvado por la subrutina retorno dd ? ; dirección de retorno pldd ? ; dirección parárnetro 1- (ent) i xL ryl-,x2 ,y2 , c (l- palabra) ; xL = coordenada x inicial (1 palabra) r yl, = coordenada y inicial (1 palabra) i x2 = coordenada x final (L palabra) ; y2 = coordenada y final(L byte) i c = col-or params ends ; SÍmbolos: nret equ offset p1 - offset retorno ; argumento de ret ; Procedimientos externos: extrn pgspunto:far t pgspunto = subrutina general i pgspunx = subrutina resol-ución 640 x 2oo i pqspunxx = subrutina resol-ución 32O x 2oo i datos segment para x y color xL yL x2 y2 delp def r delrx delry del-dx deldy délré delde dw drr db dt4t dw dw dt4t dw dr^/ dw dw dvr dhr dw dw datos ends ? ? ? ? ? ? ? i coordenada x punto de Ia Iínea i coordenada y punto de Ia l-ínea i color punto ;coordenadaxinicial icoordenadayinicial icoordenadaxfinal icoordenadayfinal ? ? ? ? ? ? ? ? i ---------- codigo segment para assume cs:codigords:datos public pgslinea pgslinea proc far push bp mov bp,sp ¿t38 ; salvar bP ; bp = sP i salvar registros afectados Push ds push es push ax Push bx push cx push dx push si push di ; direccionar seglnento datos con ds mov ax-datos mov ds,ax ; recoger parámetros Ies si, [bp].plmov ax,es: Isi] mov xl-, ax ; es : segmento, si = desplazaniento ; x1 = coordenada x inicial mov ax,es: Isi+2] mov y1,ax mov ax,es: Isi+4] mov x2tax mov ax,es: Isi+6] mov y2tax i hñ1r Al , yI = coordenada y iniciaf i x2 : coordenada x final , y2 = coordenada Y final é<? f <i+Rt mov coLor,af ; incrementos iniciales mov sir l mov di,1 ; color ; incremento de x inicial ; incremento de y inicial ; calcular /y2-yl/ mov dx,y2 sub dx,yL jSe almay neg di neg dx afmay: mov t dx = y2 i dx = y2 - yI ; bifurcar sí y2 - y1 es no negativo i mover en dirección -Y i valor absoluto de Y2 - Yldeldy,di i alnacenar incremento de y para ; rnovirnientos diagonales ; calcul-ar /x2-x1/ mov cx,x2 sub cxrxl jge al-max neg si neg cx almax: i cx : x2 ; cx : x2 - x'l' ; bifurcar si x2 - xL es no neqativo ; lnover en dirección -x i valor absoluto de x2 - x1 mov deldxrsi i almacenar incre¡nento de x para i movimientos diagonales ; clasificar /YZ-YL/ Y /x2-xL/ 439 cmp cxrdx jge mover mov sir0 xchg cxrdx jnp al-ma i compara delr con del-p ; bifurcar si recta en dirección x ; sj. Iínea vertical, incremento de x = 0 ; e intercanbiar diferencias ¡{i i si fínea horizontal, incremento de y = 9 ^ ; afmacenar de1r, de1p, delrx y delry alma: mov delr,cx ; cambj-o en 1a dirección de l_a recta mov delp,dx i canbio en 1a perpendicul-ar a la recta mov del-rx,si i incremento de x en l-a dir. de la recca mov delry,di ; increnento de y en La dir. de fa recta obtener val-ores iniciales para x e y ; nov si, xl" i coordenada x nov diry]. i coordenad.a y i calcular valor inicial e j-ncrementos para 1a función d.e error mov ax, del-p sa1 ax,1 2 *defp mov delre,ax cambio si ¡novimiento recto sub ax,cx 2*delp - delr mov bx,ax valor inicial sub ax,cx 2*defp - 2*delr mov delde,ax cambio si movimiento diagonal t ajustar contador inc cx ; estructura deI bucle principal bucle: mov xrsi tnov Y, di t dj.bujar punto en (x,y) push ds Lea ax,x push ax t cal-1 pgspunto cmp bx, o jSe diagonal ; caso linea recta recta: ^dd <i dc1 ¡¡¡ add bx,delre 'I nnn ¿vvF inn 40 l-rr¡ l a Pgv+e f i n i <=== subrutina a ejecutar ; ver si Linea recta o diagonal- i. increnentar x iñ^róñéñfár \t ; actual"izar término de error ; punto siguiente 1ínea diagonal "-.o diagonal: add si,deldx add di, deldy add bx,defde loop bucle í ;. lncrementar x in¡raman+:r r¡ ; actualizar térnino de error ; punto siguiente ; restaurar registros afectados fin: pop di pop srpop dx pop cx pop bx pop ax pop es pop ds mov sprbp pop bp ret nret sp=bp restaurar bp pgslinea endp i -^ evqrYv ^^^ end M1 PGSOBJ.ASM Subrutina: PGSOBJ. Descripción: Representar o borrar objeto por pantalla gráfica. Se dibujan sóIo la parte del objeto que cae dentro de los 1írnites de Ia pantalIa. cada punto en modo gráfico se define rnediante: l- bit - resol-ución 640 x 200. 2 bits - resol-ución 320 x 200. Un objeto se define mediante una serie de puntos dentro de un rectángulo. byte l- - di¡nensión x (col-umnas del rectángulo). byte 2 - dimensión y (fitas del rectángul-o). bytes siguientes: puntos que definen e1 rectánguIo. El- origen del- objeto es la esquj-na superior izquj.erda del rectánguIo que define el objeto, Las posiciones en color: o de1 objeto no se representan sobre pantal-Ia, quedando inalterados los puntos que ocupan esas posiciones. Ejemplo en eI caso de 1 bit/punto: x indica color L x x x x x x x x x x x x x = 000000010000000 = 0000 0001- 0000 000 0 = 01 00h = 000000101-000000 = 0000 001-0 L000 000 0 = 02 80h = 0O000l-000100000 = 0000 0100 0L00 000 0 = 04 40h = OO001OO00010000 : 0000 I-OOO 001,0 000 0 = 08 20h = OOOI0OOOOO01000 = 0001 0000 0001- 000 0 = l-0 10h = 0O1O0000O0OO1O0 = OO1O 0000 0000 100 0 = 20 08h = 0I-OO00OOOOOOOI-O = 01OO 0000 00OO O10 O = 40 04h xxxxxxxxxxxxxxx : 111-LLl-111-l-11"LLL = 111L l-11-1 l-11-1 Ll-1 0 = ff feh db L6 ; dimensión x (nro. de co1s.) (núltipfo de 8) db 8 i dimensíón y (nro. de fifas) db 001-h,000h ; fila 1 db 002h,080h ; fila 2 db oo4h,04oh ; fila 3 db 008h,020h r fila 4 db 010h,01-0h r fila 5 db o2oh,008h r fil-a 6 db 040h,004h r fila 7 db offh,ofeh ; fila 8 Ejenplo en el caso de 2 bits/punto: o indica color 3 = 1l-b x indica color 2 = 10b = OO OO OO Ll- 00 00 00 = 0000 0011 0000 00 00 = 03h,00h = 00 0O 1l- l-O l-1- 00 00 = 0000 1l-10 l-l-00 00 00:07h coh 3ah boh = O0 11 10 10 10 11 OO = OO11 1010 l-O11 00 00 = = 11 11 11 11 11 l-l- 1l- = 1l-11 1111 1l-11 11 OO : ffh fch db 8 t di¡nensión x (nro. de colu¡nnas) (núItiplo de 8) db 4 ; dimensión Y (nro. de fil'as) db OO3h,Oooh ; fila 1 o oxo oxxxo ooooooo 442 db 0o7h,0c0h db 03ah, oboh db offh,ofch Parámetros: params sEruc dr^/ retorno dd p]dd ; fila ; fila ) 3 4 bp sal-vado por 1a subrutina dirección de retorno dirección paránetro 1 (ent) x0 , y0 , nbits , ope, obj ero x = columna del origen del objeto (1 palabra) y = fita de] origen del objeto (1 pal-abra) nbits : nro. de bits por punto (1 o 2) (1 byte) ope : operación (1 byte): O - borrar objeto 1 - Áih,rirr nhiaf¡ objeto = prirner byte que define eI objeto 6ñ.1e i t Símbolos: nret equ offset rx equ 640 ry equ 20o - offset retorno ; argumento de ret ; resol-ución x (nro. de cofunnas) ; resolución y (nro. de filas) Procedimientos externos: extrn pgspunto:far p1 datos segmenE para x0 dr¡/ ? dw? dw? d\^¡ ? db? y0 x v col-or i ) xdim ydin OI4t ( of/ I cth¡ a dl4t ? AD IC db? oD( db? datos ends nbits car codigo i pgsobj Ah? x origen objeto y origen objeto col-unna fiLa cofor del punto índice sobre eje x índice sobre eje y dinensión x objeto dirnensión y objeto operación número de bits por punto contador bits dentro deL byte (de izq. a der.) carácter de fa definición de1 obj eto segment assume cs:codigo,ds:datos public pgsobj proc far push bp mov bp,sp ; sal-var bp ;bP=sP salvar registros afectados Push ds push es M3 push ax push si i direccionar segmento de datos con ds mov axrdatos mov dsrax i recoger parárnetros 1es si, [bp].pL ¡nov ax,es: Isi] mov x0,ax add sí,2 mov ax,es: Isi] mov yO,ax i seguirl: seguir2: add sí,2 mov a1,es: Isi] mov nbitsral inc si mov a1,es: Isi] nov ope,aI inc si nov alres: Isi] cmp alro jg seguirljnp fin ¡nov ah,0 mov xdirn, ax inc si mov alres: Isi] cmp a1,0 lS seguir2 jnp fin mov ahr0 mov ydirn,ax mov ibit,8 es = segmento, si = despfazamiento ax = col-umna xo : col-umna si=si+2 ax = fi-la yo : fj-1a si:si+2 ax : fila nbits = nro. dé bits por punto si=si+1 aI = operación ope = operación si=si+1al = dimensión x de1 objeto xdi¡n : dimensión x del objeto si:si+L aI = dirnensión y del objeto ydirn = dirnensión y del- objeto es: [si+1] es e1 prirner byte del objeto ibit : contador de bits dentro de1 byte (de izquierda a derecha) ; dibujo puntos del objeto mov j ro t índice sobre eje y mov axry0 t y:y0 mov Y,ax ; loop filas (j = o, I, ... , ydin-1) bucley: mov i,0 ;indice sobre eje x mov ax,xo ;x=x0 nov x,ax t l-oop co]umnas (i- = o, 1, ... , xdin-1) bucLex: 444 ,' extraer bits de Ia definición del- objeto ihif a jb extrab inc si mov aI,es3 [si] ¡¡r iLi+ extrab: sumabits: r1 ^ jmp sumabits mov cl,nbÍts shl car,c] I aLLtt usf !yue. r no ... bifurcar ; apuntar a nuevo carácter del objeto ; extraerlo ; car = carácter de 1a definición deI objeto ; poner a cero e1 contador de bits i cl- = nro. de bits por punto t el punto está en fos nbits primeros ; a1 = nbits ; incrernentar contador de bits dentro del byte mov al,nbits add ibit, aI ; obtener coLor de l-os nbits pri¡neros de car unbit: despla 3 mov aL, car cmñ nhi te 1 je unbit mov cl-,6 jnp despla ;aI:car , ¿1 bj-t? ; si ,.. bifurcar mov cL,7 ;c1 =7bj-tsadespLazar ; desplazar a 1a derecha cl bits sfrr aL, clmov color,al :cl=6hifeádésnlazar . ^^1 ^F á^1 uEr ^'rh+^ Pu¡ruv cmp colorr0 ; si es color 0, ignorarlo je nuevo cmp oper l ; si operacj-ón = borrar, dibujar color 0 je dib mov col-or, 0 ; dibujar punto en posición (x,y) de Ia pantalla dib: push ds l-ea ax, x ; xry,coLor push ax call pgspunto i chéqueo fin colurnnas inc i .incx mov ax,i cmp axrxdim j1 buclex i chequeo fin filas inc j inc y mov ax,j cmp ax, ydirn jSe fin jnp bucley 445 i restaurar registros afectados fin: pop si pop ax pop es pop ds pgsobj codigo mov sp,bp pop bp ret nret endp ends end 446 t sp = bp ; restaurar bp PGSPUNTO.ASM Subrutina: PGSPUNTO. na<^ri h^i Áñ. Poner color en una posición de la pantalla gráfica. Parámetros: params struc dw retorno dd prdd anA e i ; Símbolos3 nret i ; ? ; bp salvado por 1a subrutina ? i dirección de retorno ? i dirección parámetro 1- (ent) i X¡Y ¡C ; x : columna (1 palabra) (1 palabra) ; Y = fila (1 byte) i c = color equ offset pl - offset retorno ; argumento de ret ---------- codigo segnent para assume cs:codigo i pu!rru ^ Ir9spUnE.O i pgspunto proc far push bp mov bp,sp ñrrkl ; salvar bp ; bp = sp salvar registros afectados push es push ax push cx push dx push si recoger parámetros 1es si, [bp].p1 mov cx,es: Isi] mov dxres: Isi+2] mov alres: Isi+4] mov ahroch int 10h ; es = segmento, si = desplazarniento i cx = x (col-unna) idx=y(fita) ; al = col-or i funcion: escribir punto ; lfanar aI BIOS restaurar registros afectados pop si pop dx pop cx pop ax pop es mov sprbp ret nret sp=bp restaurar bp 447 pqspunto endp ends end 448 PGSPUNX.ASM t ; Subrutina: PGSPUNX. t Descripción: ; Dibuja un punto sobre Ia pantaLfa qráfica en al-ta resolución ; rnediante acceso directo a 1a mernoria de pantalla. ; Parámetros: params struc dr¡, ? ; bp salvado por Ia subrutlna retorno dd ? ; dirección de retorno pldd ? ; dirección parárnetro l- (ent) i x'Yr c ; x = colunna (0 a 639) (1 Palabra) (o a l-99) (1 Palabra) t y = fil,a (0 o 1-) (1- byte) i c = color params ends r Simbolos: pantalla byten nret t áoaigo equ ob8ooh ; segmento memoria de pantalla equ byte ptr es: [di] t byte de l-a memoria de pantalla equ offset p1 - offset retorno ; argumento de ret segnent para assume cs:codigo public pgspunx pgspunx proc far push bp mov bp,sp ; sal-var bp ; bp = =n i --i sa]var registros afectados push ds push es push ax push bx push cx push dx push si push di i direccionar mernoria de pantalfa con es mov axrpantal-Ia mov es, ax i recoger parámetros lds si, [bp].p1 mov cx,ds: [si] nov bx,ds:[si+2] i ds = segrnento, si = desplazamiento i cx = x (columna) i bx = y (fila) i estructura de 1a ¡nemoria de pantal-fa: ; Filas pares (0, 2, 4, ... ' 198): ; Desplazamiento = 0. t Longitud = 80 x 100 = 8000 bytes. t Filas irnpares (I , 3, 5, ... , 1-99) . M9 Desplazamiento = a1-92 = 2OOOh. i ; Longitud = 80 x l-00 = SOOO bytes. t cáIcu1o despJ.azarniento (di) en menoria de pantalla por fila innrr. ; si fila par, desplazarniento = O. ; si fila impar, desplazarniento = 2OO0h. mov dir 0 ; desplazamlento mov dx,0 mov ax,bx ; ax = fila mov si,2 div si ; frla/2. cociente en ax, resto en dx cmp dx,0 ; ¿fi1a par? 'ia t si ... bj.furcar rs¡ mov di,2000h ; desplazaniento : 2000h i i calcular e1 desplazamiento * 80 cociente(fila/2) ; correspondiente a la fifa: mov dxr0 ; ax = cociente de ft]_a/2 nov si,80 mul si ; nultiplicar por 80, resultado en ax add di,ax i y sumarlo a1 despl-azamiento anterior t i calcu]ar e1 desplazaniento correspondiente a la columna: ; cociente(colunna/8) mov dxr0 mov axrcx mov si,8 div si add di,ax i ax = columna t 8 puntos/byte ,' cociente en ax, resto en dx i y surnarlo al desplazamiento anterior i i el resto de la división (dx) es eI número deL bit afectado ; (de izquierda a derecha) empezando con cero. t mov c1,dl i cf = nro, de bits a rotar a Ia izquierda push cx ; guardar desplazamiento cnp cl-, o ; ¿es eL primer bit de la izquierda? je rcolor ; si, bifurcar ro1 byten,cl i rotación lógica a Ia izquierda ; eI bit afectado es eI primero de la izq. ; recoger parámetro : coLor rcolor: i l-ds si, [bp].pli ds = segmento, si : desplazamiento mov al",ds:tsi+4 1 ; af = col-or i nro. de bj-ts a despl-azar en cofor shf al, cL ; poner bit de cofor a la izquierda ; poner col-or en bit izquierdo and byten,oTfh ; poner bit izquierdo a o or bytemral ; poner color en bit izquierdo í i colocar fos bits en su sitio pop cx ; recuperar desplazamiento 450 cmp cl-,0 je fin ror byten,cl :oc al nrimar hif si, bifurcar rotar a Ia derecha da ]a izquÍerda? ; restaurar registros afectados rln: pop di ' pop si pop dx pop cx pop bx pop ax pop es pop ds mov sp,bp ret endp codigo nret sp=bp restaurar bp ends end 451 PGSPUNXX.ASM Subrutina: PGSPUNXX. Descripción: Dibuja un punto sobre la pantal-la gráfica en media resolución ¡nediante acceso directo a 1a rne¡nori-a de pantal-La. Parámetros: params slruc bp salvado por 1a subrutina dirección de retorno dirección paránetro 1 (ent) x,Y tC x = columna (0 a 3r-e) (1 pal-abra) (oa 1001 l1 palabra) Y=fila t^ v^ 3) (t byte) ^ - ^^1^\v dr^¡ retorno dd pldd params ends i Símbol-os: pantafla byten nret equ 0b800h i segmento memoria de pantalla equ byte ptr es: [di] i byte de 1a rnernoria de pantaLla equ offset pL - offset retorno i argumento de ret i codigo segnent para assune cs:codigo h!rhl t i ^ ry_punxx pgspunxx proc far push bp mov bp,sp i salvar bp t bp = sp i --i safvar registros afectados push ds push es push ax push bx push cx push dx push -: push di direccionar memoria de pantaLla con es mov ax,pantalla Inov es, ax recoqer paránetros i ds = segmento, si = desplazamiento i cx = x (colunna) i bx = y (fila) estructura de la mernoria de pantalla: Fil-as pares (o,2, 4, ... ' 198): Desplazaniento = o. Longitud = 80 x l-0o = 8oO0 bYtes. Filas impares (1", 3,5, ... | )-99). lds si, [bp].p1 mov cx,ds: [si] mov bx,ds:[si+2] 452 Desplazamiento = 8192 = 2000h. Longitud = 80 x l-00 = 8000 bytes. cáLculo desplazarniento (di) en memorj-a de pantalla por fila nrr n innrr. si fila par, desplazamiento = 0. si fila impar, desplazamiento = 2000h. nov di,0 ; desplazamiento mov dx,0 mov ax,bx mov si t2 div si ; ax = fila ; fila/?. cociente en axr resto en dx cmp dx,0 ia h^r ;. ¿fi1a par? nov di,2000h i despl-azamiento = 2oooh ci hi f,rra¡r i ; ca]cuLar eI desplazarniento correspondiente a l-a fila: t cociente(filal2) * 80 mov dx,0 ; ax : cociente de fíl-a/2 mov si r 80 mul si t ¡nultipl,icar por 80, resultado en ax add di,ax i y sumarl-o a1 desplazaniento anterior calcul-ar el desplazamiento correspondiente a 1a colurnna: cociente (colunna/4 ) mov dx,0 mov axrcx t ax = columna mov sir4 ; 4 puntos/byte div si i cociente en ax, resto en dx add di,ax ; y sumarl-o aI despl-azamiento anterior I eI resto de Ia división (dx) nul-tiplicado por 2 es eI número del; bit (de izquierda a derecha) empezando con cero primero afectado. sh1 dx,1 mov c1,dl push cx cmp cl,0 je rcoLor rol byten, cl^ñd hvfén 3fh i recoger parámetro = color ; dx = dx*2 t cI = nro. de bits a rotar a Ia izquierda ; guardar desplazamiento ; ¿es eI prirner bit de Ia izquierda? ; si. bifurcar i rotación lógica a Ia izquierda ; los 2 bits afectados son los primeros ; por 1a izquierda ; borrar esos dos bits í rco10r: 1ds si, lbp].plmov al,ds3 [si+4] mov c), ,6 shl a1, cI or bytenral pop cx cmp c1r 0 je fin ror bytemrcl i ds = segnento, si : desplazamiento r af = color i nro. de bj.ts a despl-azar de color i l-os 2 bits de1 color están a la izq. ; poner color en esos 2 prirneros bits ; recuperar desplazarniento i ¿es et primer bit de la izquierda? ; si ... bifurcar i colocar fos bits en su sitio 453 i ; restaurar registros afectados fin: pop di pop si pop dx pop cx pop bx pop ax pop es pop ds mov sp,bp ret pgspunxx endp codigo ends end 4V nret sp=bp restaurar bp PGSRASTE.ASM Subrutina: PGSRASTE. Descripción: Dibujo de un carácter raster por 1a pantalla gráfica. Los códigos ASCII posibles son de 0 a 255. Para los códigos 1-28 a 255 es necesario haber ejecutado previamente el comando GRAFTABL, que carga una tabl-a en ¡nemoria de definición de estos caractéres. Dirección tabla ROM (caracteres O a L27) 3 F000:FA6E. Dirección tabla RAM (caracteres )-2a a 255l.: La del vector de interrupción l-Fh. Los caracterés se definen en una matriz de 8 x 8. como ejénplo de definición, eI carácter A = 41h = 65: db 03 0h, 078h, occh, occh, ofch, occh, occh, 000h BitS Byte 7654321O O 1 2 3 4 5 6 binario XX XXXX XX XX XX XX X XXXXX XX XX XX XX o0l-l_ 0000 30h ol-11, 1000 78h l-l-00 l-100 cch 1l-00 1-100 cch 111-l- l-l-00 Fch l-l-00 1100 cch 1100 1l-00 cch 0000 0000 00h 7 Parámetros: params struc bp salvado por 1a subrutina dirección de retorno direccj-ón paránetro 1 (ent) (9 bytes) dvt retorno dd pldd x, y, xm, ym, código x = colu¡nna esquina superior carácter (l- pal-abra) y = fila esquina superior carácter (1 pal-abra) xm = tarnaño en x de cáda punto (1 pal-abra) yrn = tamaño en y de cada punto (1 palabra) código = código del carácter (o a 255) (1, byte) params ends ; SÍmbolos: col-or equ lnret equ offset i color offset retorno i argumento de ret p1- - t Procedimientos externos: extrn pgsb]oc: far ; ---------- datos datos segmenc para x0 y0 xm yn x1 y1 x2 y2 c ends dw? dw? dw? d$, ? dw? dw? dw? dw? db color x esquina superior izquierda y esquina superj-or izquierda tarnaño en x de cada punto del carácter tamaño en y de cada punto del carácter x inicial bfoque y inj-cia1 bloque x final bloque v fiñil hl^drré color a dibujar 455 ; ; ---------- codigo segnent para assutne cs: codigo, ds: datos public pgsraste pgsraste proc far push bp mov bp,sp ; salvar bp ; bp = sp i salvar registros afectados push ds push es push ax push bx push cx push dx push si ; direccionar segmento de datos con ds mov ax,datos mov ds,ax i recoger parámetros de entrada les si, tbpl.pl mov ax,es: [si] mov x0,ax ; es = segmento, si = desplazarniento ; x esquina superior izq. mov ax,es:Isi+2] mov y0rax ; y esquina superior izq. nov ax,es: [si+4] i tamaño .en x de cada punto mov xm,ax mov ax,es: [si+6] ; tarnaño en y de cada punto mov ytn, ax mov al,es: [si+8] t al_ = código del- carácter ; ver si código en la tabla ASCff ROM (O a I27) o én la tabla ASCII ; extendida RAM (cargada con GRAPHTABL) cmp a).,127 ja exten i conparar código (jon !27 t bifurcar si superior ¡ tabla ROM (caracteres O a L27) i buscar carácter en 1a tabla de generación de caracteres gráficos nov si,Ofa6eh ; si = desplazamiento cornienzo tabfa i direccionar segmento ROM con ds mov dx,ds ; salvar ds mov bx,of000h mov ds,bx i ds = segmento RoM .inn I 456 áóeñl ^ l t tabl-a RAM cargada por GRAFTABL en 1a dirección apuntada por e1 vector ; de interrupción l-Fh exten: sub al,128 i ; direccionar despla: ; restar 128 segrnento RAM con ds mov dxrds i saLvar ds mov bxr0 mov ds,bx ;ds=0 mov sj-,ds: []-Fh*41 ; desplazamiento mov bx,ds: []_Fh*4+21 i segmento mov dsrbx i ds = segrnento tabla RAM i ax = al- * 8 (desplazarniento de La defj-nición en 1a tabla) ; (8 es Ia longitud de cada definición en l_a tabla) aX=a1 ax = ax*2 ax = ax*2 ax = ax*2 si = desplazamiento comienzo definición car. si = desplaza¡niento fin definición car. i afmacenar la definición del carácter en 1a pila mov cx,8 ;Sbytes std ; dirección hacia atrás 11 : lodsb r al = ds:[si]r si = si - lpush ax ; ponerlo en la pila Loop 11 nov ds,dx ; restaurar ds i obtener el punto inicial cbh¡ sa1 ax,1 sal- ax,1 sal axr l add si,ax add si,7 12i mov ax,x0 nov xl-,ax mov axry0 nov Yl-,ax mov cx,8 i x1 = x0 t y1 = y0 mOV axrx]n i contador de I filas ; obtener siguiente fila t a1 = yn i ax = y1 + yn - 1 ,y2= yl+yn-1 ; salvar contador ; contador de 8 bits ; af = xn test dI,8Oh jz 14 ; ax = xl- + xn - li xZ = xl_ + xm - l; chequear bit ; bifurcar si cero PoP dx mov ax,ym decaxiax=ym-1 add ax,ylnov y2,ax push cx nov cxrS decaxiax=xn-1 add ax,x1 mov x2,ax 457 push ds lea ax,x1 push ax ; dirección de xL,yI ,x2,y2,c call pgsbloc i dibujar r rectángulo (x1, y1) - (x2,y2') mov axtxz i ax = x2 l-ncaX;aX=X2+I mov xl-,ax ; x1 : x2 + rol- d1,1; el- bit izquierdo de df es eI nuevo bit Ioop 13 ; bucle para punto siguiente pop cx i restaurar contador filas L mov ax,xo ; ax = x0 mov xl-¡ax ; x1 : x0 mov ax,y2 ; ax : y2 incax;ax=y2+I mov y1,ax t y1 = y2 + loop 12 ; bucle para siguiente fila i restaurar registros afectados pop sr pop dx pop cx pop bx pop ax pop es pop ds 1, mov sp,bp pop bp ret nret pgsraste endp evsfYv ^^Ai -^ 458 ^ñr^ anA t sp : bp i restaurar bp PGSTXTRA.ASM Subrutina: PGSTXTRA. noc¡ri n¡ i Án. Escribir texto en pantalla gráfica mediante l-a definición de 1os caracteres raster. EI delimitador de fin de texto es el carácter Parámétros: params struc bp salvado por Ia subrutina dirección de retorno dirección parárnetro 1- (ent) xry,xm,ymrtexto x : columna esquina superior izquierda (1 palabra) y = fila esquina superior izquierda (l- palabra) : xn tamaño en x de cada punto (1- palabra) yrn = tarnaño en y de cada punto (l- pal-abra) texto=textoaescribir dr4t retorno dd p1 dd params ends t SÍmbolos: panta]1a equ 0b800h ; dirección memoria de pantalla nret equ offset p1 - offset retorno ; arüunento de reE ; Procedimientos externos: extrn pgsraste: far ; ---------- datos segment x y xm ym cod deltax dw dr¡¡ dw dw db dw datos ends ; ? ? ? ? ? ? ¡ x esquina superior izquierda , y esquina superior i-zquierda ; tamaño en x de cada punto ; tamaño en y de cada punto icarácterarepresentar i separación entre dos caracteres sucesj-vos ---------- codigo segrnent assune cs: codigo, ds: datos publ,ic pgstxtra pgstxtra proc far push bp mov bp,sp t salvar bp t bp = sp salvar registros afectados push ds push es push ax push bx push cx push si 459 push di ; direccionar segmento de datos con ds mov ax,datos mov ds,ax ; recoger parárnetros de entrada l-es si,tbpl.pl i es : segmento, si = desplaza¡niento mov ax,es: [si] ; ax = x (colunna) mov x,ax i x add si,2 ¡nov ax,és: [si] ; ax = y (fila) nov Y,ax , y add sl-,2 mov ax,es:[si] ; ax = xn (tanaño en x de cada punto) mov xmrax i xm add sí,2 mov ax,es:[si] i ax : yn (tanaño en y de cada punto) mov ym,ax ; ym add si,2 t es: [si] apunta al primer car:ácter i calcular deltax = separación en x entre dos caracteres = 8*xm mov axrxm i ax = xm mov c1,3 ; cl=3bitsadesplazar shl ax,c} t ¡nuLtiplicar por I mov deltax,ax ; defta = 8*xm ; bucl-e caracteres del texto de entrada bucle: mov al,es: Isi] cmp af,,It je fin carácter de entrada fi ' c'i h +óv+^2 hi frrr^^r representar carácter ras cer mov cod, al- cod : carácter Push ds l-ea ax, x push ax call pgsraste inc si mov ax, del-tax add x,ax jnp bucLe t siguiente carácter ; x : x + deltax (siguiente posición) i restaurar registros afectados pop di pop si pop cx pop bx 460 pop ax pop es pop ds mov sprbp pop bp ret nret sp=bp restaurar bp pgstxtra endp i codigo ends end 461 PGSVECTO.ASM Subrutina: PGSVECTO. Descripción: Dibujo por pantalla gráfica de un objeto definido mediante una lista de vectores. Cada vector sé define ¡nediante tres canpos: campo 1 (L byte) = operación: A = pluma arriba, B : plurna abajo canpo 2 (1 pal-abra) = coordenada x respecto a la esquina superior. campo 3 (1 palabra) = coordenada y respecto a 1a esquina superior. EI final de l-a lista de vectores se indica mediante ilFr. E j eÍrplo: (,At r0,0)r(tBr ,2I ,Q>,<r Br,O,11>, <tBt ,2I ,11->,<rAr ,g,5> ,<r8r,16,5> <rFt,0,0> 01-2 or23 4567 A9 0\23 45 67 89 0]-23 . . . 00 XXXXXXXXXXXXXXXXXXXXXX 1 X ) ? 4 5 XXXXXXXXX 7 ó 9 X 10 XXXXXXXXXXXXXXXXXXXXXX L 1 Parámetros: paralns struc i bp safvado por 1a subrutina ,' dirección de retorno i dirección paránetro 3 (ent) ; fista de vectores que definen e1 objeto ; dirección parámetro 2 (ent) (1 palabra) ; y (fila) esquina superior de1 objeto ; direccj-ón parárnetro 1 (ent) (1 pal,abra) ; x (columna) esquina superior de1 objeto dn¡ retorno dd p3 dd p2 p1 dd dd params ends SÍmboLos: xfac equ I yfac equ 8 color equ ! nret equ offset t factor de rnultiplicación en x i factor de rnultiplicación en y , coLor Líneas pl - offset retorno ; argumento de ret Procedi-mientos externos: extrn pgslinea:far 462 datos segment para ; estructura de un vector vector struc db ? ; código dw?icoordenadax dw ? ;coordenaday vector ends datos xo yo x1 y1 x2 y2 c ends t x esquina superior izquierda ; y esquina superior izquierda dw? ;xiniciallÍnea dw? ;yiniciallÍnea dv¡? l-inea ;xfinal dw? linea ;yfinal db color ; color lÍnea dw ? dw ? i ---------codigo segment para assume cs:codigo,ds:datos public pgsvecto pgsvecto proc far push bp ; salvar bp mov bp,sp ; bp = sp ¡ --; salvar registros afectados push ds push es push ax push cx push dx push si ; direccionar segmento de datos con ds mov ax,datos nov dsrax ; recoger parámetros de entrada l-es si, [bp] .pl- ; es = segrnento, si -- desplazamiento mov axres: [si] ; x esquina superior izq. mov xOrax 1es si,[bp].p2 ; es = segmento, si = despl-azamiento mov ax,es: [si] t y esquina super.ior izq. mov y0,ax les si, [bp].p3 ; es¡ [si] = Lista de vectores i recorrer la lista de vectores nov al,es: [si] cmp al,trFrr je fin i aI = código ; ¿fin de la lista? t sl ... fin i actual-izar coordenada x posición actual 463 mov axrx2 i xI=x2 mov x1,ax mov ax,es: Isi+1-] ; ax = x vecEor nov cxrxfac mul- cx i nuLtipficar por e1 factor add axrxo ; x2=x0+x mov x2,ax i actuaLizar coordenada y posición actual . nov ax,y2 mov yl-rax mov axres: [si+3] mov cx,yfac mu1 cx add ax,yo mov y2,ax ' 1L - y¿ i ax = y vector ; nultipJ-icar por el factor de escal-a en y , y2 = y0 + y i ver el tipo de operación cmp byte ptr es:[si],rrArr ; ¿pluma arriba? je mas t si ... bifurcar dibujar Iínea entre (x1-,yl-) y (x2,y2') ; push ds Iea ax, xl- push ax ca]l pgslinea ; siguiente vector ; dibujar lÍnea mas: add si,size vector jrp vec i bifurcar i restaurar registros afectados r.In: pop si pop dx pop cx pop ax pop es pop ds mov sprbp pop bp ret nret pgsvecto endp i ^^v uvu ^^a r\j ^ñt^ end 464 de escal-a en x sp=bp restaurar bp El teclado El teclado del IBM PC consta de 83 teclas, divididas en tres grupos: ¡ A la izquierda: Teclas de funciones. o En el centro: Teclas estándares de máquina de escribir. o A la derecha: Teclado numérico. El teclado se comunica con el BIOS a través de puertos e interrupciones. detectar las teclas pulsadas e informar de ello al BIOS. Si se pulsa una tecla durante más de medio segundo, el controlador del teclado envia la información relativa ala tecla pulsada a razón de l0 veces por segundo. El teclado se comunica con el BIOS a través de puertos e interrupciones. Cada vez que se pulsa una teclá, la acción se reporta con una interrupción tipo 9 (interrupción de acción de teclado). La rutina correspondiente a esta interrupción lee del puerto 96 (60h), que a su vez genera dos bytes: ¡ El identificador de la tecla (número de la tecla, I a 83). Se llama también byte auxiliar o primer código. o El código ASCII correspondiente a esa tecla (si existe). Se llama también byte principal o segundo código. Si el segundo código es cero, ello indica que la tecla es especial, que no existe código ASCII asociado, como, por ejemplo: las teclas de funciones, las teclas de control del cursor, etc. En este caso, debe examinarse el primer ¿t65 código, que es normalmente el identificador de la tecla y que se llama código extendido. Se pueden pulsar combinaciones de teclas. Normalmente, son las teclas de tipo modificador (Alt, Mayúscula y Ctrl) acompañadas de otra tecla. En el caso de que se tecleen directamente los códigos ASCII (pulsando Alt y el número decimal del código ASCII), el primer código es cero y el segundo código contiene el código tecleado. La excepción es el código cero, que se reserva para indicar un carácter no ASCII. Hay, por supuesto, combinaciones de teclas que la rutina BIOS no reconoce en absoluto y que no generan códigos. La tabla al final de este capítulo indica los códigos asociados a cada tecla o combinación de teclas. Las teclas modificadoras y combinaciones de las mismas que generan código son: Mayúscula, Alt, Ctrl y Alt Ctrl. La rutina BIOS del teclado tiene su propia memoria buffer para almacenar los códigos de hasta l5 teclas o combinaciones de teclas (30 bytes). Combinac¡ones de teclas espec¡ales Las combinaciones de teclas siguientes tienen significado especial: Alt Crrl Del Ctrl Break Carga del sistema. Se invoca la interrupción BIOS lBh (Break de tecla- do). Devuelve AL : AH :0. Ctrl Num-Lock - La rutina de teclado se para hasta que se vuelva a pulsar cualquier otra tecla (excepto Numlock). Sirve para suspender temporalmente una operación (listar, imprimir, etc.), para reanudarla después. Mayúscula PrtSc - Se invoca la rutina tipo 5, que es escribir pantalla alfanumérica por impresora (hordcopy). Si se ha ejecutado el comando GRAPHICS.COM y la pantalla está en modo gráfico, el hardcopy se hace pixel a pixel. Bytes de estado del teclado Se encuentran en el área de datos del BIOS (segmento 40h), con los nombres y direcciones siguientes: 466 Nombre Dirección KB--FLAG KB__FLAG-I 40h l7h:4r7h 40h l8h = 418h El significado de cada bit KB__FLAG KB__FLAGJ Ins (estado) Caps-Lock (estado) Ins (pulsado) Caps-Lock (pulsado) Num-Lock (estado) Scroll-Lock (estado) Num-Lock (pulsado) Scroll-Lock (pulsado) Ctrl Num-Lock (estado) No se usa No se usa No se usa Bit Alt (pulsado) Ctrl (pulsado) Mayúscula izquierda (pulsado) Mayúscula derecha (pulsado) Para "estado", l indica activo y 0 inactivo. Para "pulsado", l indica pulsadoy0nopulsado. La interrupción BIOS 16h con AH = 02h devuelve el primer byte de estado (KB-FLAG). Interrupc¡ones asociadas al teclado Número Tipo Descripción 09h BIOS BIOS BIOS Acción sobre el teclado (rutina del sistema). Funciones varias, según el valor de AH. Rutina del usuario para el proceso de Ctrl-Break, si el control lo tiene el BIOS. Funciones varias, según el valor de AH. Rutina del usuario para el proceso de Ctrl-Break, si el control lo tiene el DOS. l6h lBh zth 23h DOS DOS FUNCIONES BIOS CORRESPONDIENTES A LA INTERRUPCION 16h AH Función 00h Lee de la memoria (buffer) de teclado los códigos asociados a una tecla o combinación de teclas sobre AX y avanza el puntero del buffir al carácter siguiente. Si el buffer está vacío, espera a que se pulse alguna tecla. Salida: AH: Identificador de la tecla pulsada. AL : Código ASCII del carácter. 01h Devuelve el estado del buffer de teclado. 467 Salida: si buffer vacio ZF:I si buffir no vacío ZF:0 AH : Identificador de la tecla pulsada. AL : Código del carilcter. 02h Devuelve el byte de estado del teclado (KB-FLAG). Salida: AL : Bvte de estado del teclado. FUNCIONES DOS CORRESPONDIENTES A LA INTERRUPCION 21h AH Función 01h Esperar para leer un carácter del teclado y escribirlo por pantalla (con chequeo de Ctrl-Break). Salida: AL : Carácter tecleado. 06h Leer un carácter del teclado, sin salida por pantalla (sin chequeo de Crtl-Break). Salida: AL : Carácter tecleado, si disponible. 0, si carácter no disponible. 07h Esperar para leer un carácter del teclado, pero sin escribirlo por pantalla (sin chequeo de Ctrl-Break). Salida: AL : Carácter tecleado. 08h Esperar para leer un carácter del teclado, pero sin escribirlo por pantalla (con chequeo de Ctrl-Break). Salida: AL = Caútcter tecleado. OAh Leer caracteres del teclado y almacenarlos en un área de memo- ria. El primer byte del área debe ser distinto de cero e indica el número máximo de caracteres a teclear (incluido el retorno de carro). El segundo byte del área indica el número de caracteres tecleados (sin incluir el retorno de carro). Los datos se almacenan a partir del tercer b¡e. Entrada: DS:DX: dirección del área de memoria. OBh Obtener el estado del teclado (con chequeo de Ctrl-Break). ¿168 Salida: AL : FFh si carácter disponible. 0 si carácter no disponible. OCh Borrar buffer de teclado y llamar a una función de entrada de teclado. Entrada: AL : Número de la función de teclado (1, 6,7,8 o A). Salida: La de la función. Gódigos generados por las operac¡ones (Teclado español y KEYBSP residente) El signo : indica el mismo código anterior. El signo .. indica valor indeterminado. I Esc 2 l¡ J )t 0l lB 02 3l 03 32 04 33 05 34 06 35 07 36 08 37 09 38 02 AD 03 A8 04 23 05 24 06 25 07 2F 08 26 09 2A =_ OC 2D OD 3D OC 5F OD 28 l4 Retroceso l5 t6 t7 Tabulador 0E 08 0F 09 l0 7l lp oo l8 t9 E 4 l 6 7 8 9 10 ll t2 l3 3# 4$ 5Vo 6/ 7& 8* e( 0) a w R 2l T Y 22 U 20 23 I 24 o 25 P 26 27 áá áe 28 29 Enter 30 A 3l S 32 D JJ F 34 C Ctrl 0A 39 0B 30 ll 77 t2 65 13 '72 t4 74 l5 79 t6 '75 t7 69 18 6F t9 '10 lA .. lB 60 IC OD lD .. lE 6l lF 73 20 64 21 66 22 67 0A 28 0B 29 0l 13 03 00 78 00 79 00 7A 00 78 00 7C 00 7D 00 7E 00 7F 00 OC IF 80 00 81 00 82 00 83 00 OE 7F l0 ll l0 00 l1 t7 ll 00 t2 05 t2 00 13 52 13 00 t4 54 14 00 15 59 16 55 15 00 16 00 18 4F 19 50 18 00 19 00 l7 49 t7 00 IA FE IB 5E 1 <D IAA JD IB 5D IC OA lE 0l lE 00 22 07 22 00 lF 13 lF 00 20 04 20 00 2t 06 21 00 469 Tecla Normal Mayúscula 23 68 24 6A 25 68 26 6C 27 A4 28 38 29 87 2A .. Número 35 H 36 J 37 38 K 39 40 L ñ 4l 42 44 Z 45 X 46 47 C 48 B 49 50 N M 5l ,| 52 I 53 54 Mayúscula 55 PrtSc )t 58 59 39 20 3A .. 38 00 6l F3 62 63 F4 65 F5 F6 F7 F8 F9 33 3F 34 21 54 00 55 00 56 00 57 00 58 00 59 00 3C 00 3D 00 3E 00 3F 00 40 00 4t 00 5A 00 Ft0 Num Lock Scroll Lock 7l Home 7 flecha arr. 8 PgUp 9 46.. 72 t5 74 i) flechaizq.4 76 ) 77 78 79 flecha der. 6 80 82 flecha aba. 2 PgDn 3 lns 0 83 Del 8l + End I 32 0D 2B 2C 00 2D 00 2E 00 2F 00 30 00 31 00 32 00 = 72 00 69 70 67 68 28 IC 2< 1't 42 00 58 00 43 00 5C 00 44001 5D 00 66 23 00 24 00 25 00 26 00 2F t6 30 02 31 0E 3',7 5E Espacio Caps Lock FI 23 08 24 0A 25 0B 26 0C AIt-Ctrl 36 38 F2 AIt 2C IA 2D r8 2E 03 2E 63 2F 76 30 62 31 6E 32 6D 33 2C 34 2E 35 27 Alt 60 64 2B 3E 2C 7A 2D 78 V Ctrl 28 3A 2B 3C 43 56 Mayúsc. a<l"l I 47371 48381 5E 00 5F 00 60 00 6t 00 62 00 63 00 64 00 65 00 66 00 67 00 77 00 4e3el 84 00 48341 73 00 I 74 00 4A2Dl 4c3s 4D36 4E2B 4F311 s0321 | I 5t 1? | I s2301 53 2El 75 00 76 00 68 00 69 00 6A 00 6B 00 6C 00 6D 00 6E 00 6F 00 70 00 7l 00 00 07 00 08 00 09 37 00 38 00 00 04 00 05 00 06 00 0l 00 02 00 03 Carga Sistema Aplicaciones Programas: TEPFLE TEPLEER TEPTECLA Prueba subrutina TESFLE. Lee de teclado y lo escribe por pantalla. Prueba subrutina TESLEER. Prueba subrutina TESTECLA. Subrutinas: TESESPER TESFLE TESLEER TESTECLA Poner en estado de espera a la máquina hasta que se pulse cualquier tecla. Obtiene los incrementos (x,y) correspondientes a una tecla de movimiento del cursor. Leer de teclado. Obtiene los códigos asociados a una operación de teclado. 471 TEPFLE.ASM ! Dr^dr^ñ^. TFDFT F i : naqñri h- i Áñ. Prueba subrutina TESFLE. ; ; Símbol"os: cr equ l-3 ; retorno de carro ]f equ L0 ; alirnentación de 1ínea i ; Procedinientos externos: extrn tesfle: far extrn pastexto: far ; ---------- ; pila segment stack db pila ; 1-28 dup ('pila,) ends ---------- datos segnent xy fabel word I $ii tder tarr tizq taba tizqarr tizqaba tderarr -' . .,-,I) db ¡Derecha¡rcr,lfr'$l db tArriba' , cr, If, ' gl db'Izquierdar,cr,lf,'$t db tAbajot,cr,lf,rg' rgl db'Izquierda Arribar,cr,If, rSr db'Izquierda Abajot,cr,1f, db tDerecha Arrihar .r tf rql datos ends "l*::n:li:IÍ:i:3:1) tderaba db'Derecha il;i;;,¿;;í;;f$I ---------codigo segrnent tepffe proc far assune cs : codigo, ds : datos , ss : pila ; poner dirección de retorno af DOS en La pila t push ds sub axrax push ax ; dÍreccionar segnento de datos con ds mov ax,datos mov ds,ax tecla tipo ffecha o Enter leer: 472 push ds 1ea axrx segmento ax = despLazamiento de x push ax ; desplazarniento push ds ; segnento ; ax = desplazarniento de y ; desplazarniento ]ea áXry push ax calL tesfl-e t escribir texto según tecl-a 1eída o salir al DOS si se pulsó Enter cmp xYro i ¿Enter? jne compa ; no ... bifurcar jnp fin compa: arr: emp xy,00100h je der crnp xy, o0 0 f fh IA cnp xy,offooh je ízq cmp xy,00OO1h je aba cmp xy,offffh je izqarr cmp xy,offo1h je izqaba cmp xy,001-ffh je derarr cnp xy,00l-01-h je deraba jnp fin izqarr: izqaba: derarr: deraba: mover: ¿flecha abajo? ¿izquierda arriba? ¿izquierda abajo? ¿derecha arriba? ¿derecha abajo? push ds ; segmento texto ; desplazarniento texto push ds ; segnento texto ; desplazaniento texto push ds i segnento texto ; desplazarniento texto push ds ; segmento texto ; desplazamiento texto push ds i segnento texto ; desplazamiento texto push ds ; segmento texto ; desplazamÍento texto push ds i segmento texto ; desplazarniento téxto push ds ; segmento texto i desplazaniento texto l-ea ax, tder j¡np mover l-ea ax, tarr jnp mover aba: ¿flecha derecha? ¿flecha arriba? ¿f1écha izquierda? lea ax,tizq jmp mover lea ax,taba jnp mover lea axrtizqarr j¡np mover 1ea ax,tizqaba jnp mover 1ea ax,tderarr jmp mover Lea ax,tderaba 473 push ax t escribir texto por pantalla calL pastexto imn 1 aar i ; vol-ver al fin: DOS ret endp i ends end tepf l-e 474 ; despfazaniento TEPLEE R.ASM i P.ogr.*u, : na<¡r'i TEPLEER. n¡ i Án. Lee de1 tecl-ado y 10 escribe por pantalIa. Prueba subrutina TESLEER. i i i Sínbolos: maximo equ 20 cr 1f equ 13 equ 10 ; nro. máximo de caracteres a teclear t (incluyendo retorno de carro) ,. retorno de carro ; afinentación de }Ínea ; Procedimientos externos: extrn tesleer: far extrn pastexto: far : ---------- pila segment stack 128 dup (rpila') db pifa ends datos segment para area db naximo ncars db ? entrada db db salto db datos ends : maxirno dup (t ' ) 2 dup(?) cr,If, r$¡ i nro. náximo de caracs. a teclear¿ t (incfuyendo retorno de carro) ¡ núnero de caracteres tecleados ; (sin incluir retorno de carro) ; caracteres teclead.os ; (incl-uyendo retorno de carro) ; espacio para insertar lf y g ; salto de l"ínea ---------- codigo segment tepleer proc far assume cs : codj-go, ds : datos , ss : pila i poner en la pil-a Ia dirección de retorno al DOS , push ds sub axrax push ax ; direccionar segmento de datos con ds mov axrqaEos mov ds,ax i --i leer de teclado push ds lea axrarea 475 push ax caLL tesleer saltar 1ínea push ds l-ea ax, sal-to push ax cal-1 pastexto inserta If y t$t detrás del" úl-tino caracter l-eído mov alrncars ; a1 = nro. de caracteres tecleados mov ah,o t ah = 0 mov si,ax ; si = nro. de caracteres tecleados mov entrada[si+].1 , If ; rnover If mov entrada[si+2],'$' ; mover deli¡nitador fin de rnensaje escribir texto 1eído push ds 1ea axrentrada push ax cal-l- pastexto retorno al DOS 476 tepleer endp codigo ends end tepleer TEPTECLA.ASM i Prograna: TEPTECLA. . nae¡r'i n¡ i Án. Prueba subrutina TESTECIA. Para terminar el programa, pulsar ctrl-Break. ; ; ; SÍmbofos: cr equ 13 1f equ l-0 ; retorno de carro ; alinentación de línea Procedimientos externos: ; extrn testecla: far extrn pastexto:far ; Macros: i-f1 include comcrhx.asn endif ; ---------- pila ni ¡ ; segrnent stack db l ¡ óñ.le L2a dup (rpilar) ---------- datos segment tecla db 2 dup(?) datos ends ; códigos correspondientes a una operación de t teclado mensa db I Códigos: t hexl db 2 dup(?) i caracteres hexadecimales del carácter izq. db,yl hex2 db 2 dup(?) ; caracteres hexadecimales deL carácter der. db crrLf, t$t i codigo segnent teptecl-a proc far assume cs: codigo, ds: datos, ss: pila ; poner dirección de retorno aL DOS en fa pila push ds sub ax,ax push ax ; direccionar segménto de datos con ds Inov ax, qaEos mov dsrax ; leer tecla o combinación de teclas leer: push ds 477 lea ax,tecla calI testecla push ax convertir a hexadecimal eI pri.rner código comcrhx teclarhexlconvertir a hexadecimal eI segundo código comcrhx tecla+1-'hex2 escribj-r por pantall-a Ios códigos en hexadecimal nrr <h ¡l c Iea ax lnensa nrrch ¡ w ' .ál I nAqfpYto ; inn I óér t teptecla endp ¡a^ i aa añ.]c pnd 478 tpnttrcla . hi€,rr^.r á léér TESESPER.ASM Subrutina: TESESPER. Descripción: Poner en estado de espera a Ia náquina hasta que se pulse cualcfuier tec]a. ¡^A i ¡^ segment para assume cs:codigo pubLic tesesper I'esesper proc far push ax mov ah,o int 16h pop ax salvar ax función: leer tecl-a l-Lamar al- BIOS restaurar ax ret endp codigo ends end 479 TESFLE.ASM Subrutina: TESFLE. ñ^^^,i ue-u! h^i ÁF. rPe¡v¡¡. Obtiene los incrementos (x,y) correspondientes a una tecla de movirniento del cursor: ', _1./\ (-1, 0) /^ _1.,\ .-l t_1 \ I I - - (1r_1) (1'o) (0,1) (1,1) (-1,1) , Si se pulsa la tecla Enter, devuelve (o'0). Parámetros: parans struc dw retorno dd dd p2 dd params ends bp salvado por la subrutina di-rección de retorno dirección parámetro 2 (sal) (l- byte) l-ncremento y dirección parámetro l- (sal) (1 byte) incremento x ; SÍrnbolos: nret equ offset p1 - offset retorno i argumento de ret codigo tesfle segment assume cs:codigo ueÉr -..L1r ^ .^^:l"e Puv¿re proc far push bp mov bp,sp salvar registros afectados hrr<h ée push si push ax i l-eer tecla tecla: nov ax,o int L6h 48h 47It 4bh 4fh I - 50h ; función: leer una tecl-a ; ll-a¡nada al BIOS ; ah = código 1 ; aI = código 2 49h 4dh código 1 51h cnp a1,0dh i compara con Enter je ent ótp ah,4dh i colnpara con fLecha derecha ¿l80 je der cmp ah,4bh je izq cmp ah,48h )e arr cmp ah,50h je aba cmp ah,47h je ízqarr cmp ah,4fh je izqaba cmp ah,49h je derarr cmp ah,5Lh je deraba j.p tecla arr: aba: r z qarr: izqaba: derarr: deraba: i compara con fl,echa izquierda i conpara con fLecha arriba i compara con flecha abajo i compara con Home i compara con End i compara con PgUP i compara con PgDn mov axr 0 jnp Ya i tecl-a Enter mov ax, o0100h jnp Ya ; flecha derecha (1,o) mov ax,000ffh jnp ya t flecha arriba (0,-L) mov ax,0ffo0h jnp ya ; ftecha izquierda (-1,0) mov ax,0000lh jmp ya ; flecha abajo (0,1-) mov ax,0ffffh j¡np ya ; Home (-1,-1) mov ax,0f f0l,h jnp ya r End (-L,1) mov ax, oo1ffh jnp ya PgUp (1-,-1) mov ax,00101-h i PgDn (1,1) parámetros de salida i ya: 1es si, lbp].p1 mov es: Isi],ah 1es si, [bp].p2 mov es:[sj-]fal- es = segnento/ incremento x í es = seg¡nento, despl-azamiento despl-azamiento i incremento Y ; restaurar regj-stros afectados pop ax pop si pop es mov sPrbP pop bp ró+ nrat 481 tesf l-e endp codigo ends end 482 TESLEER.ASM subruclna: noc¡ri t.L5Lt¡-K. n¡ i Án. Leer de teclado. Parámetros: cf rr1^ bp salvado por La subrutÍna dirección de retorno dirección paránetro 1 (ent/sal) byte l- - nro. náxino de caracteres a tec]ear (incluyendo retorno de carro). byte 2 - nro. de caracteres leidos (sin incluir retorno de carro). byte 3 en adelante - caracteres tecleados (incluyendo retorno de carro). df^t retorno dd dd óh.l < sínbol,os: hPó+ ; codigo ódrr - offset retorno ; argumento de ret segment assume cs: codigo public +óc l áár ñ1 ^ff<ó+ ñr^^ tesleer f^r push bp t salvar bp ; bp = sp mov bp,sp salvar registros afectados push ds push ax push dx leer de teclado lds dx, tbpl.prmov ah,Oah int 21h i i restaurar registros pop pop pop dx mov sP, bP pop tesleer endp codigo ends ; ds = segmento' dx = deplazamÍento ; función: Ieer de teclado ; llamar al Dos afectados ax ds nret rsp=bp ; restaurar bp end 483 TESTECLA.ASM Subrutina: TESTECLA. Descripción: obtiene los códigos asociados a una operación de teclado. Si eL buffer de teclado está vacÍo, se espera a que se pulse alguna tecl-a. Parámetros: params struc dw retorno dd p1 dd params ends t bp salvado por l-a subrutina r dirección de retorno ; direccj-ón parámetro 1 (sal) (2 bytes) t códigos ; SÍmbol,os: nret equ offset p1 - offset retorno ; argurnento de ret ; ---------- codigo segrnent assume cs:codigo public testecla testecl-a proc far push bp mov bprsp salvar registros afectados push es push si push ax . i I ó6r +ó^l ^ nov int axro l,6h ; función: l-eer una tecl-a i. llamada al- BIoS ^L - ^Áll^^ vvqr9v t al = código 1 r 2 poner paránetro de salida les si, Ibpl.pl ; es = segnento, si = desplazamiento mov es:[si],ah ; código 1 nov es: Isi]+1,al ,' código 2 restaurar registros aféctados pop pop pop ax nov sp, bp pop ret 4U nret testecl"a endp codigo ends end 485 La impresora en modo alfanumérico El interfaz paralelo permite conectar al PC con una impresora. Este interfaz se encuentra integrado en el adaptador monocromo o puede ser independiente. Cada carácter se envía sobre ocho líneas de datos (una línea por bit). Existen también líneas de control como: o señal de autoalimentación, r impresora ocupada, o reconocimiento (desde la impresora al PC), o fin de papel, . error de entrada/salida, o inicialización impresora, o selección (impresora en línea). Ciertas impresoras, incluyendo la impresora gráfica IBM, se pueden configurar para que generen un salto de línea después de imprimir el carácter de retorno de carro (13 :ODh). Esto no es deseable, pues los ficheros de texto en DOS contienen al final los caracteres lf (line feed: l0 : 0Ah) y cr (corriage return: 13 :0Dh). 486 Interrupciones asociadas a la impresora en modo alfanumérico Descripción Número Tipo 05h BIOS Hardcopy de pantalla. 17h BIOS 2rh DOS Entrada,/salida de impresora. Función AH:05h. FUNCIONES BIOS CORRESPONDIENTES A LA INTERRUPCION 17h Las tres retornan un byte de estado en AH: Bits Contenido Impresora no ocupada (0: ocupada, I : no ocupada) Reconocimiento desde la impresora (0 : señal, I : normal) Fin del papel (0: con PaPel, I : sin papel) Seleccionada (0 : impresora no en línea, I : en línea) Error de entrada/salida (0 : error, I : normal) No se usa No se usa Tiempo excedido (0: no, I : si). Para saber si se puede enviar un carácter, se puede chequear el bit "reconocimiento" o, mejor aún, el bit de "ocupada", pues, si no lo está, se puede enviar un carácter. AH Función 00h Imprimir un carácter. Entrada: AH:00h. AL : Carácter a imprimir. Salida: AH : Byte de estado de la impresora. 0lh Inicializar impresora. Entrada: AH:01h. DX : Impresora a usar (0 - 2). Salida: AH: Byte de estado de la impresora. 02h Leer estado de la impresora. 487 Entrada: AH:02h. DX: Impresora a usar (0 - 2). Salida: AH : Byte de estado de la impresora. FUNCION DOS CORRESPONDIENTE A LA INTERRUPCION 21h AH Función Imprimir un carácter. Entrada: DL:Carácter a imprimir. ra8 24 ta impresora en modo gráf¡co La realización de gráficos por impresora se logra utilizando el modo imagen de bit (bit image) de la impresora matricial (el modo normal es el modo texto), es decir, direccionando los puntos (dots) de impresión. Estos dos modos no son independientes entre sí, pues los parámetros de modo texto siguen activos en modo imagen de bit. Vamos a centrarnos, como ejemplo, en un determinado tipo de impresora: la impresora gráfica IBM (Graphics Printer). El tratamiento para otro tipo de impresoras es similar. El direccionamiento de los puntos se hace mediante las agujas de la cabeza de la impresora, que son ocho y alineadas verticalmente. cada aguja se corresponde con un bit de un b¡e de la manera siguiente: aguJa bit X 7 x x 6 X 4 5 X J x x 2 papel impresora I 0 ( [ es la matriz de la cabeza de impresión) ¿189 Los ejes de coordenadas que se consideran son: Eje Definición Sentido positivo X longitudinal (largo del papel) Y transversal (ancho del papel) de arriba abajo de izouierda a derecha El eje X es, pues, ilimitado. La limitación del eje Y es el recorrido de la cabeza de impresión. El origen de coordenadas corresponde a la posición tope de la cabeza de impresión a la izquierda. La distancia física entre dos agujas es de l/72 pulgadas, es decir, la densidad a lo largo del eje X es de 72 puntos por pulgada. Respecto al eje Y, la densidad se selecciona en el momento de escribir una cadena de bytes. Existen los modos siguientes (véase FX Printer Operation ManuaD: Modo Tipo de densidad 0 normal I doble doble cuádruple gráficos pantalla 2 J A 5 plotter 6 gráficos pantalla II Densidad Velocidsd (puntos/pulgada) 60 120 l6 r20 l6 240 8 80 72 90 l2 8 8 8 Si se selecciona el modo plotter (72 puntos por pulgada), las densidades sobre ambos ejes coinciden. La memor¡a de impresora gráfica ¿Cómo se hace un dibujo? De manera similar a como se dibuja por la pantalla en modo gráfico, es decir, hay que reservar un área de memoria (buffe| y activar (poner a l) los bits correspondientes acada punto que se desea representar sobre la impresora. En este caso sólo hay un bit por punto, pues no se considera el color. Para calcular la dimensión de esta área de memoria, hay que considerar las variables siguientes: : Largo del papel (pulgadas). - dimx del papel (pulgadas). dimy - denx :: Ancho según el eje X. Densidad - deny : Densidad (puntos/pulgada) (puntos/pulgada) según el eje Y. 490 puntosx : denx * dimx : Número total de puntos según X. puntosy : denY * dimy: Número total de puntos según Y. : puntosx/8 : Número de líneas a imprimir según X. nx : puntosy : Número de caracteres a imprimir según Y. ny Para el caso dimx : 11" , dimy = 8" (hoja estrecha) y denx :72 y deny:66, puntosx :'12 * Il : 792 puntos. Puntosy : 60*8 : 480 puntos. nx ny :792/8 : 991íneas. :480 caracteres,/linea. Y el área de memoria será de nxxny:99x480 :47520 bytes( 64 Kb. La subrutina básica de impresión es la que activa un punto (x,y), siendo cada coordenada un número de 16 bits: 0(x(puntosx-l 0 ( y ( puntosy-l Una vez desarrollada esta subrutina, con el algoritmo de Bresenham se puede dibujar una línea entre dos puntos dados (xl,yl) y (x2,y2). lmpresión de la memor¡a de impresora Una vez que hemos "dibujado" sobre la memoria de impresota, pata obtener la salida física es necesario realizar la secuencia de operaciones siguiente: l. En primer lugar, inicializar la impresora: MOV AH,l ; función: inicializar impresora MOV DX,0 ; impresora a utilizar INT l7h ; llamar al BIOS 2. En segundo lugar, seleccionar el espaciado entre las líneas a imprimir. Se hace imprimiendo la secuencia de códigos de pontrol: DB 27 DB '3' NES DB 24 escape selección espaciado entre lineas indica el espaciado en l/216 pulgadas El espaciado (pulgadas) es NES/216: 8 agujas, por la distancia entre dos agujas (l/72 pulgadas). 491 ll NES. ---!- - 8.-+-, de donde NES : 24 zto tz 3. Por cada línea a imprimir en modo imagen de bit hay que escribir la secuencia: MODO N DB DB DB DW 27 0 ; escape ; modo imagen de bit ; modo densidad normal ; número de bytes a imprimir Y a continuación los N bytes de datos. 4. Una vez impresos los N bytes, y finalizada la línea, es necesario ha- cer un retorno de carro (escribir carácter 13 :ODh) y un salto de línea (escribir carácter 10: OAh). 5. Finalizada la escritura de todas las líneas. es conveniente saltar de página (escribir carácter 12 :OCh). Para imprimir el contenido de un byte, se mueve sobre el registro AL y se ejecutan la instrucciones: MOV AH,O ; función: escribir carácter por impresora MOV DX,O ; impresora a utilizar INT l7h : llamar al BIOS Dibujos grandes Si queremos hacer un dibujo de tamaño superior al que nos permite el buffer, es necesario dividir el dibujo en "ventanas" (definidas por los intervalos x tax2eytay) y generar tiras de papel que luego habrá que juntar para obtener el dibujo completo. Cada tira de papel corresponde a un intervalo entre dos ordenadas (yr e y2), que define la anchura de la ventana según Y. Latira de papel es la concatenación de ventanas a lo largo del eje X. Aplicaciones Módulos: IGMCOMUN - Segmento de datos comunes de las subrutinas de dibujo por impresora gráfica. Programas: IGPERSE.FOR - Prueba subrutinas de dibujo en impresora gráfica (programa FORTRAN). El dibujo generado por este programa puede verse en la página siguiente. 492 .\ t--...-. I ,t ti ,.1 il""t \ --"..1 !- \.Í:'j:a:-.\hiri ,\i i ji t,.. \,, \ ..\ I "=,...*,1.,u) *¿;---,t:::+---.*1. Í.f1,*-".T.'r, -¡' iT Subrutinos: IGSBAN Definición y borrado de la memoria de la impresora gráfica. IGSLIN Dibujar una línea en impresora (modo gráfico). IGSPRT Imprime la memoria de impresora gráfica. IGSPUNTO- Almacena punto sobre la memoria de impresora gráfica. IGMCOMUN.ASM Módulo: IGMCOMUN. Descripc j.ón: Segrnento de datos conunes de las subrutinas de dibujo por impresora gráf i-ca. comun segment para cornnon dirnx db ? dirny db ? denx db ? deny db ? puntosx dw ? puntosy d\r ? nxdw? 494 ny d$/ ? nes db comun ends ? I comunl ; largo del papel (pulgadas) ; (11) ; ancho de1 papel (pufgadas) r (8) ; densidad (puntos/pulgada) según x i (72) ; densidad (puntos/pulgada) según y ; (60) ; puntos totales según x , (ue¡¡^ --^xII:792) ; puntos totales según y ; (deny x diny = 60 x I = 480) ; nro. de bytes a irnprirnj-r según x ; (puntosx/a : 72 x LL / I : 99) ; nro. de bytes a inprimir según y ; (puntosy = 480) ; espaciado : nes/2A6 pulgadas ; (8 x (2).6/denx) = I x (216/72) -- 24) IGPERSE.FOR Prograna: IGPERSE. Descripción: Prueba subrutinas de dibujo en impresora gráfica. dimension x(30),y(30),xn(30),yn(30) c ix(xx) = (r+xx)*idenx iY(YY) = (r+YY)*ideny write(*,600) 600 format(/t Prueba Dibujo por irnpresorar) parárnetros del dibujo c dimensión x = largo del- papel- (pulgadas) idi¡nx : 11dirnensión y = ancho del papel (pulgadas) idinY : s densidades idenx : 72 idenY : 69 número de lados del polÍgono incremento vértices inc=3 nro. total- de configuraciones a dibujar n=50 radio de1 círculo circunscrito r : idimy Y : r/2. fracción a avanzar (pulgadas) delta = l./LO. ::::T_:::::_::_ri::::::1 \^trite ( *, 6o1) 601 fornat(/t Borrar memoria de irnpresorat) call igsban(idinx, idinY) valores inici-a1es c 495 nval-or = lpi = 3.14L59265 ang = 2.o*piln doLi=L,n angulo = ang*i x(i) = r*cos(angulo) Y(i) = r*sin(angulo) 1 continue :::=_r:r!:tr1 r^¡rite(*r 602) 602 format(/' do2j=1,n iz=t Generación de1 gráfico') do 3 i = 1rn ir - ¡. í2=il-+inc if (i2.9t.n) i2 = í2 - int(i-zln) *¡ 'l ina> Aihrri>r nxt- = ix(x(i1) ) nyL = iy(y(i1) ) nxz = ix(x(iz) ) nyz = iy(y(i2)) call iqslin (nx1,ny1,nx2,ny2,nvalor) vx=x(i2) -x(i1) vy=y(i2) -y(il) xn(i1) = x(il) + delta*vx yn(il) - y(ir) + delta*vy 3 continue do 4 i -- l-,n x(i) - xn(i) y(i) = yn(i) 4 continue 2 continue ::t:::::_::i::t:-9:-ti::::::: \^/rite ( *, 603 ) 603 fornat(/' Salida de Ia memoria de inpresorar) ¡:1 I stop end 496 iacnrl- IGSBAN.ASM subrutina: IGSBAN. Descripción: Defiñlción y borrado de l-a ¡nernoria de la irnpresora gráfica. Ü (¡natriz de la cabeza de irnpresión) Parámetros: parans struc pL dr.r dd? dd? dd? params ends retorno p2 t sÍ¡nbolos: densx densy dinxy nnax nret ? t bp salvado por la subrutina i dirección de retorno ; dirección parámetro 2 (1 byte) ; dimensión y (ancho) del papel (pulgadas) ¡ dirección parárnetro 1 (1 byte) ; di¡nensión x (largo) del papel (pulgadas) ; densidad (puntos,/pulgada) según x ; densidad (puntos,/pulgada) según y i pulgadas cuadradas (náxi¡ro) eqo 72*72*L1 i nro. rnáxi¡no de bytes en memoria de irnpresora i corresponde a una hoja de 8x1.1 u llxg con t densidad horizontal y vartical 72. egu offset pl - offset retorno i argu¡nento de ret equ 72 equ 60 equ 11*8 ; l,lódu1os: , include igmconun. asm codigo segment para assume cs:codigords:comun publJ,c banco public igsban igsban proc far tnov bp, sp push bp t saLvar bp ibP=5n salvar registros afectados push ds push es push ax push cx push dx push si push di ; direccionar segrnento co¡nun con ds mov ax, co¡nun 497 mov ds,ax ; recoger parámetros dinx y dimy les si, [bp].pl mov al_,es: Isi] mov dimxraL i es = segmento, si = despl-azamiento ; dimx l-es si, [bp].p2 mov aL,es: [si] mov dimyral ; es = segnento, si : desplazamiento ; diny i densidades x, y mov denx,densx ; densidad según x (puntos por pulgada) mov deny,densy ; densidad según y (puntos por pulgada) ; cál-culo de puntosx = denx*dimx (puntos totales según x) mov ah,O t ah : 0 mov al,denx ; al = denx mul- dimx i ax = denx*dimx mov puntosx,ax i puntosx = ax ; cál-culo de puntosy = deny*diny (puntos totales según y) mov ah,O ; ah = 0 mov al-,deny t af = deny mul dirny ; ax : deny*¿1¡O mov puntosy,ax i puntosy = ¿¡ i t cáIculo de nx = puntosx/8 (número de l-ineas a imprirnir) mov dx,o t dx = 0 mov ax,puntosx i ax : puntosx rnov si,8 ; si = I div si i ax = puntosx/g mov nxrax i nx = ax ; cálculo de ny = puntosy (núnero de bytes a irnprirnir por linea) mov axrpuntosy ; ax = puntosy rnov nyrax ; ny : ax ; cáfculo de nes (espaciado = nes/216 pulgadas) mov nesr S* (2J-6/densx) i direccionar mernoria d.e irnpresora con es3 [di] mov axrseg banco tnov es , ax mov di,offset banco ; poner a ceros binarios el- banco (nx 1íneas de ny caracteres) mov cx,nx ; cx : nro. de lÍneas vert : push cx ; sal-var cx mov cx,ny i cx = nro. de caracteres por ]-ínea horiz: mov byte ptr es:[dí],0 ; poner a cero inc di ;di=di+1 498 l J.oop horiz ; bucle caracteres 1Ínea pop cx ; recuperar cx Loop vert ; bucl-e l-Íneas : rFstñt¡rar reoistros afectados ; pop di pop si pop dx pop cx pop ax pop es PoP ds cn hn pop bp ret nret i ¡ehrn ;sp=bp ; restaurar bp 6h¡lh i ¡aA i ; i an óñAe ---------- datos banco datos segment para 1abe1 byte org db? i memorj-a de irnpresora nmax ends end 499 IGSLIN.ASM Subrutina: IGSLIN. Descripción: Dibujar una línea en irnpresora (nodo gráfico) Parámetros: params struc bp sal-vado por la subrutina dirección de retorno dirección paránetro 5 (1 byte) d\4t retorno dd p5 dd p4 dd val-or (0 o 1) dirección parárnetro 4 (1 palabra) coordenada y finaL dirección parárnetro 3 (1 palabra) coordenada x final dirección parárnetro 2 (l- pal-abra) coordenaila y inicial, dirección paránetro L (l- pal,abra) coordenada x inicial" p2 plparams SÍmbolos: nret equ offset p1 - offset retorno Procedinientos externos: éxtrn igspunto: far datos segmenc para x v dw? d$/ x1 y1 d¡¡/ dhr dw? valor x2 y2 dt^I delr delrx delry deldx deldy defre d\^¡ dw? delde dl^t dr¡¡ dw? dt^/ ahr O\,t datos ends ; ? ? ? ! ? ; coordenada x punto de Ia Iínea i coordenada y punto de Ia línea i valor punto i coordenada x iniciali coordenada y inicial ; coordenada x final i coordenada y final ! ? ! ! ! ---------- codj-go segment para assume cs: codigords: datos ñ!rl-'l i^ LYi^sIin Psvr¿v iaclin nrn¡ f¡r push bp rnov bp, sp salvar reqistros afectados 500 ; argunento de ret ; salvar bp tbP:sP push ds push es push ax push bx Push cx push dx push si push di ; direccionar segmento datos con ds mov ax,datos mov ds,ax recoger parámetros Les si, lbp] . pl" mov axres: Isi] mov xl-, ax les si, lbp].p2 nov axres: Isi] mov yl,rax fes si, Ibp].p3 mov ax,es: Isi] mov x2,ax les si, [bp].p4 mov axres: Isi] mov y2,ax les si, Ibp].ps mov a1,es: Isi] ir- l ^F .l es = segmento, sI = desplazaniento x1 = coordenada x iniciaf es = segnento, si = desplazarniento y1 = coordenada y ini-ciales = segnento, si- = despl"azamiento x2 = coordenada x finaf es = segnento, si = despl-azami-ento y2 = coordenada y final es = segmento, si = despfazamiento val-or = vaLor incre¡nentos inicial-es mov si, L mov di, L i comenzar con l- para increnentos de x i conenzar con l- para i-ncrernentos de Y calcul-ar /y2-yI/ ahnay: mov dx,y2 sub dx,yl, jge almay neg di neg dx mov deldy,d ; calcu]ar /x2-x1-/ mov cx,x2 sub cxrxl jge almax neg si neg cx almax: Inov deldx, si dx=y2 ¿¡=yZ-y1 bifurcar si y2 - YL es no negativo mover en dirección -y valor absoluto de y2 - YI ; almacenar incre¡nento de Y Para i movj-¡nientos diagonales cx=x2 cx=x2-x1 bifurcar si x2 - xL es no negativo rnover en direcci-ón -x valor absoluto de x2 - xI al-macenar incremento de x Para novinientos diagonal-es 501 i i cfasificar /y2-y1,/ y /xz-fl-/ cmp cx,dx ; compara delr con delp jge setdiag i bifurcar si recta en dirección x mov si,o t si Línea vertical, incremento de x = o xchg cxrdx ; e interca¡nbiar diferencias jnp alma setdiag: mov di,O ; si línea horizontal, incremento de y = 9 ; al,macenar delr, de1p, delrx y delry alma: mov delr,cx t canbio en 1a dirección de la recta mov delprdx t cambio en fa perpendicular a l-a recta mov del-rx,si i increnento de x en 1a dir. de l-a recca mov delryrdi i incremento de y en Ia dir. de Ia recta ; obtener valores inicial-es para x e y . mov sirxlmov di,yl- ; coordenada x ; coordenada y ; calcular valor inicial e incrernentos para Ia función de error mov ax, del-p sa1 ax, l; 2*defp mov del,rérax t cambio si rnovimiento recto sub ax,cx ; 2*defp - delr mov bx,ax i valor inicialsub ax,cx ; 2*delp - 2*delr mov delde,ax i cambio si novimiento diagonal ; ajustar contador inc cx i estructura deL bucfe principal bucle: mov xrsi mov y,di ; dibujar punto (x,y) con val,or = valor push ds l-ea ax, x push ax push ds 1éa áXry push ax push ds lea ax,valor push ax i 5A2 call igspunto crop bx, 0 i ¡¿ JYV rl i r¡nn¡ I ; ver si- IÍnea recta o diagonal ; caso Ii.nea recta ¡AÁ ei .lólrv add di, del"ry ¡d¡l I ^^h imn }.v dalrp hrr- l ó f i n ; incrementar x i ancrementar y ; actualizar término de error i punto siguiente ; ; caso lÍnea diagona] diagonal: add si, del-dx add di, deldY add bx,delde loop bucle . . iF^vóbóñfAr 1ñ^Fóhóntar v v : ¡ctilalizar termino de error ; Punto siguiente ; restaurar registros afectados fÍn: pop di pop si pop dx pop cx PoP bx pop ax pop es pop ds mov sP, bP ret nret pop igslin codigo sp=bp restaurar bp endp ends end 503 IGSPRT.ASM ; Subrutinas IGSPRT. i Descripción: ; Imprime la ¡nemorj.a de irnpresora gráfica. i Símbolos: cr equ l-3 If equ l-0 escape eqo 27 i retorno de carro i al-imentación de línea i carácter de escape ; VarÍabfes externas: extrn banco:byte ; Módulos: include igmcornun.asm ; ---------- codigro segment para assume cs : codigo, ds : conun publ-ic j-gsprt r-gsprt proc far push bp mov bprsp t sal-var bp ;bP=5n sal-var registros afectados push ds push es push ax push cx push dx push si push di direccionar segmento comun con d.s mov ax,comun mov ds,ax t i direccionar ne¡noria de impresora con es: Idi] mov axrseg banco mov esrax mov di,offset banco ; espaciado entre lineas de inpresora: escáperr3rrnes nov ^^ aLrescape l 1 ñF+^-F nov ¡:I I al , rt3 r nr+¡r¡ mov alrnes ¡¡ l I nr+¡rr ; escape ;. escribir carácter flrtt i escribi-r carácter i nes (espaciado - nes/2L6 pulgadas) t escribir carácter bucle 1Íneas mov cx,nx 504 ; cx = nro. de líneas i caracteres de control (bit irnage) para cada IÍnea vert: mov aI, escape escape call prtcar escribir carácter rrKrl Inov a1, densidad norrnal,: 60 puntos/pulgada .^l I ñr+^ár escribir carácter mov al,byte ptr ny ; carácter inferior de ny n¡ l 1 nr+¡:¡ ; escribir carácter <rrnari^Y h\t nov al,byte ptr ny + 1 | .aYÁ-far call prtcar ; escribir carácter ^ó i bucle caracteres de una I ínea push cx salvar cx mov cx,ny cx = nro. de caracteres de 1a 1ínea horiz: mov al,es: ldi] al- = carácter call prtcar escribir carácter inc di di=di+1 loop horiz pop cx restaurar cx ; fin de línea mov a1,cr ; retorno de carro cal_1 prtcar mov al,1f i alimentación de Iínea call prtcar loop vert ; restaurar registros afectados ran: pop di pop si pop dx pop cx pop ax pop es Pop ds mov pop igsprt ; sP, bP ret sp=bp restaurar bp endp ---------- prtcar proc near ; procediniento para irnprirnir un carácter por impresora ; entrada! a1 (carácter a inprimir) push ax push dx ; salvar registros nov ah,0 mov dx,o ; impresora a usar int 17h i l-l-amar al BIOS 505 pop pop prtcar codigo 506 ret endp ends end dx i restaurar regLstros IGSPUNTO.ASM Subruti-na: IGSPUNTO. Descripción: Almacena punto sobre 1a rnernoria de irnpresora gráfica. Parámetros: params rer.orno dw dd dd p2 dd p1 dd params ends ? ,' bp sal-vado por l-a subrutj-na ? ; dirección de retorno ? ; dj-rección parámetro 3 (1 byte) ; valor (0 o 1) ? ; dirección parámetro 2 (! paLabra) ; coordenada y del punto ? ; dirección parámetro 1 (1 palabra) i coordenada x de1 punto i símbol-os: bytén equ byte ptr es: [di] r byte de la memoria de impresora nret equ offset pl- - offset retorno ; argumento de reE Variables externas: extrn banco:byte Módulos: j-nclude igrncornun. asm codigo segnent para assume cs:codigo,ds:comun public igspunto r,gspunto proc far push bp mov bprsp ; salvar bp ;bP=5O salvar registros afectados push ds pusfr es push ax push bx push cx push dx push si push di recogerparámetrosxey fds si, [bp].p1 mov cx,ds: Isi] ;cx lds si, [bp].p2 mov bx,ds: Isi] ids ;bx segmento, desplazamiento segnento, despl-azamiento v direccionar segmento comun con ds mov axrcomun mov ds, ax 507 direccionar banco con es: Idi] mov ax,seg banco mov es, ax catcul-ar el desplaza¡niento correspondiente a mov di,bx ;di=y cal-cu1ar e1 despl-azamiento correspondiente a x: cociente(x/8)*puntosy mov dx,0 nov ax,cx ci div q si rnov dx, 0 -i -r, nrrn*¡¡r' ¡/urruu>y mul si add di, ax ;dx=0 . . a hrrñf ¡nnionfe ^c /l-\\t+6 en av resto en dx i salvar resto de x/B ;dx=0 . ci hrlnl-^cv = Pq¡¡uvJJ ; ax : cociente(x/8)*puntosy t di : y + cociente(x/el*puntosy i i sumar a di el- desplazarniento de banco ; nov ax,offset add di, ax banco ; ax = desplazamiento de banco ; sumarsero a o.L eI resto de La división (dx) es el núnero def bit afectado (de izquierda a derecha) empezando con cero. pop dx recuperar resto de x/8 Al cI = nro. de bits a rotar a Ia izquierda ^l guardar desplazamiento cnp cL,0 ¿es eI prirner bit de la izquierda? ia rrral^r si, bifurcar rotación Iógica a Ia izquierda ro1 byten, cl el bit afectado es e1 pri:nero de l-a izq. i i recoger paránetro valor rval-or: lds si, [bp].p3 i ds = segnento, si : despl-azamiento mov al-,ds: [si] i al- = valor nov cI,7 i nro. de bits a despl-azar en val-or shl- al-, cf ; poner bit de val-or a La izquierda i ; poner val"or en bit izquierdo and byten,oTfh i poner bit izquierdo a 0 or bytem,al ; poner valor en bit izquierdo ; colocar los bits en su sitio pop cx i recuperar despfazamiento i. ¿es el primer bit de 1a izquierda? ^1 n ci hifrrr¡¡r je fin r rotar a la derecha ror bytem, clv+, v i restaurar registros afectados f i.n: 508 pop pop da pop dx pop cx pop bx pop ax pop es pop ds mov sP, bP e^+ nret pop igspunto endp ; codigo rsp=bp i restaurar bp ends end 509 Acceso a disco El sistema de almacenamiento en disco constituye el soporte externo de la información. Los datos se registran sobre la superficie del disco sobre una serie de circunferencias concéntricas llamadas pistas. Una pista es la cantidad de información accesible desde una determinada posición de la cabeza de lecturalescritura. La información de cada pista está dividida en bloques del mismo tamaño llamados sectores. Un sector es la unidad básica de entrada/salida. Un disco tiene una serie de superficies de grabación llamadas caras. Cada cara se corresponde con una cabeza de lectura/escritura. Vamos a estudiar principalmente dos tipos de discos: el diskette (o disco flexible) de 360 Kb y el disco duro (o fijo) de l0 Mb. Anatomía de un diskette El BIOS permite formatear las pistas con sectores de 128, 256, 512 ó 1024 bytes. El DOS, hasta ahora, ha utilizado los sectores de 512 bytes y nueve sectores por pista (a partir del DOS 2.0). El hecho de que exista flexibilidad en el tamaño y número de sectores dentro de una pista es por lo que se habla de sectorización por software (soft sectors). Longitud de un sector :512 bytes : 0.5 Kb : 200h. 510 El comando FORMAT del DOS siempre crea nueve sectores por pista. Con la opción /8 sólo se utilizan ocho de los nueve sectores creados. La tabla siguiente relaciona las capacidades entre los diferentes elementos de w diskette de doble cara y nueve sectores/pista, que es el más utilizado: Diskette Cara Pista Caras por Pistas por 2 80 Sectores por 720 40 360 9 Kb por 360 180 4.5 Sector 0.5 Un sector consta de dos secciones: o La cabecera del sector. Comienza con los 6 bytes siguientes: PCSTICRC p : pista C: C€tf€t S : número de sector T : indicador tamaño del sector 0 : 128, l : 256, 2 : 512, 3 : 1024 El CRC (código de redundancia cíclica) es una suma de autocomprobación de los b¡es anteriores y se calculan cuando se escribe el sector. Cuando éste se lee, el CRC leído se compara con el recalculado. Si no coinciden, se produce un error de CRC. El resto de la cabecera del sector contiene información para el controlador. o Los datos del sector. Terminan también con 2 bytes CRC, que se crean en el momento de grabar el registro. Al volver a leerlo, también se calcula y se compara con el leído. Anatomía de un disco duro Un cilindro se define como la cantidad de información accesible desde una determinada posición de la cabeza de lectura/escritura. Esta definición puede ser extensible al caso de diskette. La longitud de un sector es también de 512 Kb. La tabla siguiente relaciona las capacidades entre los diferentes elementos de un disco duro de 10 Mb: 511 Caro Cilindro Pista Sector 305 68 l7 Sectores por 20.740 5 185 Kb por 10.370 2592.s 4 68 34 8.5 0.5 Disco Caras por Cilindros por Pistas por 4 Numeración y acceso Para acceder a un sector vía BIOS se necesita un sistema de cuatro coordenadas: o Unidad .: 0 a 3. Corresponden a las unidades A, B, C y D. ....: 0a | (diskette) ó 0a 3 (disco duro). o Pista de la cara .: 0 a 39 (diskette) ó 0 a 304 (disco duro). o Sector de la pista: I a 9 (diskettel ó I a 17 (disco duro). ¡ Cara Una vez leído el sector en memoria, para acceder a un byte específico del sector es necesario especificar además: o Desplazamiento dentro delsector: 0 a lFFh. El DOS localiza la información por número de sector lógico o absoluto, numerados de fuera a dentro (es decir, por pista, cara y sector, en este orden), siendo el primer sector el cero. En el caso de diskette: Sector lógico 0: pista 0, cara 0, sector l. Sector lógico 1: pista 0, cara 0, sector 2. Sector lógico 8: pista 0, cara 0, sector 9. Sector lógico 9: pista 0, cara l, sector l. Sector lógico 719: pista 39, cara l, sector 9. Areas en disco reservadas para el DOS Las áreas creadas por el comando FORMAT del DOS son cuatro. Por orden de almacenamiento son: l. El registro de autoarranque (boot). 2. Primera y segunda copia de la FAT. La tabla de ubicación de ficheros (File Allocstion Toble, FAT) se usa para registrar los clusters asignados a cada fichero. Un cluster es la unidad de reserva de espacio en disco (serie de sectores adyacentes). El tamaño del cluster depende del tipo de disco: Tipo de disco Tumoño cluster Sectores /pista Simple cara Simple cara Doble cara Doble cara Disco duro 8 9 8 9 t7 I sector : I sector 512 bytes :0.5 Kb 512 bytes :0.5 Kb I :I 2 sectores :1024 bytes: 2 sectores -- 1024 bytes Kb Kb 8 sectores :4096 bytes:4 Kb En el caso de cluster de dos sectores quiere decir que cualquier fichero de longitud entre I y 1024 bytes consumirá dos sectores; si es de 1025 bytes, consume cuatro sectores' etc' Como el control de la ubicación de todos los ficheros se encuentra en la tabla FAT, como medida de seguridad para el caso de daño del cluster donde se encuentra la propia FAT, existe una segunda copia. 3. El directorio raiz. Se usa para almacenar los nombres de los ficheros contenidos en el disco. 4. Area para los ficheros. Aparte de estas áreas, el resto del espacio en disco puede ser asignado a cualquier fichero. Existen dós ficheros especiales que, si existen, deben ocupar posiciones determinadas para poder realizar su función: el IBMBIO.COM Y EL IBMDOS.COM. EL REGISTRO DE AUTOARRANQUE Consiste en un pequeño programa en lenguaje máquina que arranca el proceso de carga del DOS en memoria. Lo primero que hace es comprobar que el disco contiene el sistema (los ficheros IBMBIO.COM e IBMDOS.COM). Se encuentra siempre en la pista 0, cara 0, sector l. Todos los diskettes tienen este registro, contengan o no el sistema operativo. A partir del byte 4 (desplazamiento 3) del registro, existe lo que se llama el bloque de parámetros del BIOS: 513 Desp. Long. a J ll l3 t4 t6 t7 l9 2l Descripción 8 Identificación sistema (por ejemplo, IBM 2.0). 2 Bytes/sector. I 2 Sectores/ cluster. Número de sectores reservados al comienzo. Número de copias de la FAT. Número de entradas en el directorio raiz. Número total de sectores en el disco. Identificación del formato (véase primer byte FAT) Número de sectores,/FAT. Número de sectores/pista. Número de caras. Número de sectores especiales reservados. I 2 2 I 22 24 26 2 2 28 2 2 El programa en sí se encuentra en los tres primeros bytes (0, I y 2) y continúa tras el bloque de parámetros. EL DIRECTORIO Cada entrada del directorio ocupa 32 bytes, es decir, existen 512/32:16 entradas por sector. La estructura de una entrada es: Desp. Long. 0 8 8 J t2 I l0 ll 22 24 26 28 2 2 2 4 Campo Nombre del fichero. Extensión del fichero. Atributo del fichero. Reservado. Hora de creación o de la última actualización Fecha de creación o de la última actualización Cluster inicial (bytes en orden inverso). Tamaño del fichero (bytes en orden inverso) El primer b¡e del nombre del fichero indica el estado del fichero: Primer byte 00h E5h (o) 2Eh (.) Significado No existen más entradas en el directorio (entrada no utilizada). Entrada vacía (se usó, pero el fichero se ha borrado). Entrada correspondiente a un subdirectorio. Si el segundo byte es también 2Eh, el campo de cluster inicial indica el comienzo del directorio padre, excepto cuando el padre es el raiz, en cuyo caso el campo de cluster inicial es 0000h. XXh Cualquier otro valor es el primer carácter del nombre del fichero. 514 El byte de atributo del fichero puede tener los valores (o suma de valores) siguientes: Bits Atributo Signfficado 0lh 20h Fichero de sólo lectura. Fichero oculto. Fichero del sistema. Indica etiqueta del disco (en bytes I a I l). Subdirectorio. Fichero modificado desde el último BACKUP. 40h 80h No se usa. No se usa. 02h 2 J 4 04h 08h l0h Los fichos IBMBIO.COM e IBMDOS.COM son ocultos y del sistema. En este caso, el b¡e de atributo es 06h. El formato de los campos hora y fecha son: FEDCBA987 65432t0 FEDCBAg8765 43210 hhhhhmmmmmmxxxxx aaaaa a ammmmddddd Hora Fecha siendo: hhhhh (5 bits, bits 15 a l l) : Horas (0 a23). mmmmmm (6 bits, bits l0 a 5) : Minutos (0 a 59). (5 bits, bits 4 a 0) : Incrementos de 2 segundos (0 a29). Hora:horasx 2048+ minutos x32+ incrementos/2 xxxxx aaaaaaa (7 bits, bits 15 a 9): Año a sumar a 1980 (0 a ll9). Indica años 1980 a2099. mmmm (4 bits, bits 8 a 5) : Mes (l a l2). ddddd (5 bits, bits 4 a 0) : Día (1 a 31). Fecha : (año- 1980) x 512 + mes x 64 + dia El tamaño del fichero indicado en la entrada del directorio puede ser superior al real. El final de un fichero se marca con el byte Ctrl-Z (lAh), mientras que el valor en el directorio puede ser un múltiplo de 128 bytes. Cuando el DOS lee un fichero, se reporta el final del fichero cuando se alcanzan los bytes del directorio o al final de la cadena FAT (el primero que se encuentre). El tamaño del directorio en un diskette de doble cara y nueve sectores/ pista es de siete sectores. El tamaño del directorio en un disco duro depende de la partición. Si la partición es el disco entero (305 cilindros), el directorio es de 32 sectores (4 clusters\. 515 LA FAT GILE ALLOCATION TABLE) Empieza siempre en: cara : 0, pista : 0, sector : 2 (es decir, sector lógico l). Sigue al registro de autoarranque. Si es mayor de un sector, los sectores son contiguos. La FAT es básicamente una tabla que consta de una entrada por cada cluster del disco. El contenido de cada entrada indica si el cluster está libre. defectuoso o asignado a un fichero. Si está asignado a un fichero, indica si es el último cluster del fichero o cuál es el cluster siguiente del fichero. Cada entrada de la FAT es de 1.5 bytes de longitud (12 bits o 3 nibbles), es decir, hay dos entradas por cada 3 byes: bytes - clustersLas dos primeras entradas (tres primeros bytes) son especiales y corresponden a los clusters teóricos 0 y l: Byte Contenido 0 Indica el tipo de disco y el formato I FFh FFh 2 Primer byte FAT FFh FEh FDh FCh F8h Tipo de disco Número Sectores de caras por pista Diskette Diskette Diskette Diskette Disco duro 2 8 I 8 2 9 I 9 Sectores directorio pista 0 pista 0 Número ents. cars 0 cqra l directorio 4,5,6,7 4,5,6,7 6,7,8,9 6,7,8,9 rzrJ tt2 1,2,3 t12 L 64 64 obsérvese que, para el caso de los diskettes de doble cara y nueve sectores por pista, existen siete sectores para el directorio. como existen 16 entradas por sector, hay 16 x7:ll2 entradas como máximo en el directorio. El resto de las entradas de la FAT (cluster 2 en adelante) indican lo si- guiente: 516 Contenido Significado 000h Cluster disponible FFFh FFTh Ultimo cluster del fichero Cluster defectuoso XXXh Número del siguiente cluster del fichero La primera vez que se asigna espacio a un fichero se recorre la FAT desde el principio, asignándosele el primer cluster disponible. El tamaño de la FAT en un diskette de doble caray nueve sectores/pista es de dos sectores (tn cluster). El tamaño de la FAT en un dis duro depende de la partición. Si la partición es el disco entero (305 cilindros), la FAT es de ocho sectores (un cluster). Cuando se borra un fichero, se hacen dos operaciones: o Se pone o: E5h como primer byte del nombre del fichero' o Se ponen a cero las entradas de la FAT correspondientes alos clusters asignados al fichero. Mapa de un drskette (doble cara, 9 sectores/pistal Area Sector lógico inicial Número de sectores Registro de autoarranque Area FAT Area FAT (copia) 0 I I J 2 2 Directorio Total ) 1 Area Registro de autoarranque Area FAT Area FAT (copia) Directorio Directorio Total (l cluster) (l cluster) l2 sectores Sectores I 2 2 4 J Ubicación P:0,c:0,s:l P:0,c:0,s:2y3 P:0,c:0,s:4Y5 p=o,c:0,s:6a9 P:0,c:l,s:1a3 l2 r".tor.t 517 Disponibles para ficheros de datos (a partir del sector lógico 12): 720-12 :708 sectores :708/2 clusters : 354 clusters (del 2 al 355). Total sectores : 708 -r 12:720 (del0 al 719). Mapa de un disco duro Para el caso de partición de 305 cilindros (el disco completo): Areo Sector lógico iniciql Número se sectores Registro de autoarranque Area FAT Area FAT (copia) 0 I I 8 9 8 Directorio t7 32 Total (l cluster) (l cluster) (4 clusters) 49 sectores Disponibles para ficheros de datos (a partir del sector lógico 49): o Teóricos: 20.740- 49 =20.691 sectores =20.691/8 clusters:2.586 clusters (del 2 al 2587). o Reales: 2.586 clusters x 8 sectores/c/zster:20.688 sectores El total de sectores del disco es 20.688 * 49:20.737 sectores (sectores lógicos 0 a 20.736). Refación entre cluste,rs y sectores La fórmula que se utiliza es: : (c- 2) * I + i siendo: s : número del sector lógico c : número del cluster. I : longitud del cluster (bytes). i : número del sector lógico inicial del área de datos. s Hay que tener en cuenta que los clusters se numeran del 2 en adelante, de ahí la razón de restar 2. 518 Tipo de disco Fórmula Diskette doble cara y 9 sectores,/pista Disco duro s:(c-2)*2+12:c,*2+ 8 s:(c-2)*8+49:c*8+33 Su bdirectorios Existen dos tipos de directorios: el directorio raiz y los subdirectorios. El contenido es el mismo, pero tienen características distintas: o El directorio raiz tiene un tamaño fijo y se almacena en una posición fija del disco. r Un subdirectorio puede tener cualquier tamaño y puede almacenarse en cualquier posición dentro del disco. Se crea como un fichero cual- quiera. Los subdirectorios están conectados al directorio padre, que puede ser el directorio raiz t otro subdirectorio. Se crea así una estructura jerarquizada en varios niveles (árbol). Existe una entrada en el directorio padre para cada subdirectorio. Esta entrada contiene atributo : 4 y longitud del fichero :0. El tamaño real del subdirectorio se obtiene a través de la FAT. Cuando se crea un subdirectorio, se crean dos entradas con los nombres "." y "..", eue sirven como referencia para futuros subdirectorios. La primera se refiere al propio subdirectorio. La segunda se refiere al directorio padre. El número del cluster inicial en ambas entradas nos indica la posición del propio subdirectorio o de su directorio padre. En este último caso, si este número es cero, quiere decir que el directorio padre es el direc- torio raí2. Acceso a disco desde ensamblador Cuando se programa en ensamblador se tiene completo control para acceder a cualquier sector del disco, pudiéndose acceder a ficheros ocultos, al área del directorio, alárea FAT, e incluso al registro de autoarranque. Las interrupciones de acceso a disco son: Número Tipo Desuipción 13h BIOS 25h 26h DOS Entrada,/salida de disco. Lectura de disco absoluta. Grabación en disco absoluta. Funciones DOS. 2rh DOS DOS 519 MANEJO DE ERRORES Cuando se utilizan estas funciones, es necesario considerar los posibles errores. Al contrario que el DOS, que detecta y procesa todos los errores de hardware, las rutinas BIOS esperan que nuestro programa detecte los posibles errores y la recuperación de los mismos. Las funciones BIOS y DOS retornan un valor de estado en AH. Si AH:0, la-operación se realizó con éxito: AH Eror 00h Ninguno Marca de dirección no encontrada Disco protegido contra escritura Sector no encontrado 02b 03h 04h 08h 40h Error DMA Error CRC Error en el controlador de disco Error de búsqueda 80h Tiempo excedido l0h 20h Causa probable del enor Disco defectuoso Disco protegido Disco defectuoso Adaptador mal Disco defectuoso Adaptador mal Unidad mal Unidad mal o no preparada La primera vez que se emite una función de lectura puede retornar un error, aunque no existía tal error ni en el hordware ni en el disco. Esto se debe a que el motor del disco consume medio segundo en alcanzar la velocidad máxima y el BIOS nos espera. Por ello, cualquier función de lectura con el BIOS debe repetirse tres veces antes de determinar que existe realmente un error. En cambio, en DOS la lectura se repite cinco veces antes de En las operaciones de grabación, el BIOS espera a qlúe el motor alcance la velocidad máxima. FUNCIONES BIOS CORRESPONDIENTES A LA INTERRUPCION 13h AH Función 00h Restaurar el controlador de disco. Esta función nos permite inicializar el hardwore de interfaz de disco. Normalmente no es necesario utilizarla, puesto que esta función la realiza el DOS. Sin embargo, si al realizar una operación de entrada/salida en disco, nos encontramos con una condición de error, entonces es necesario usar esta función antes de volver a intentar la operación de entrada/salida. Olh Leer estado. Esta función nos permite obtener el estado de la ultima operación realizada. Salida: AL: Byte de estado. 02h Leer sectores. Esta función permite transferir datos desde disco. Los datos se transfieren por sectores. Entrada: DL : Número de la unidad (0- 3). DH: Número de la cara (0- l). CH: Número de la pista (0-39). CL : Número del sector (l - 9). AL = Número de sectores (l 9). ES:BX: Dirección de| buffer.Salida: AL : Número de sectores leídos. CF :0, no error y AH :0. CF : l, error y AH : byte de estado. 03h Grabar sectores. Entrada: DL = Número de la unidad (0- 3). DH: Número de la cara (0- l). CH : Número de la pista (0-39). CL : Número del sector (l - 9). AL : Número de sectores (l ES:BX: Dirección del bu.ffer. 9). Salida: AL : Número de sectores grabados. CF :0, no error y AH:0. CF : l, error y AH : byte de estado. 04h Verificar sectores. Entrada: DL : Número de la unidad (0- 3). DH = Número de la cara (0- l). CH: Número de la pista (0-39). CL = Número del sector (l - 9). AL : Número de sectores (l - 9). Salida: AL : Número de sectores verificados. CF :0, no error y AH:0. CF : 1, error y AH : bj¡te de estado. 05h Formatear una pista. Entrada: AL : Número de sectores (l- e). DL : Número de la unidad (0- 3). 521 DH: Número de la cara (0- l). CH : Número de la pista (0-39). Salida: CF :0, no error y AH:0. CF: l, error y AH: byte de estado. INTERRUPCIONES DOS o ^y'. 25h Función Lectura de disco absoluta. Tras la ejecución, las banderas salvadas (por la instrucción INT) están todavía en la pila y deben restaurarse con POPF. Esto se hace así porque cierta información de salida se sitúa en las banderas. Además, tocios los registros (excepto los registros de segmentos) se destruyen. Entrada: AL : Número de la unidad (0-3) (0: A, 1 : B, etc.). CX = Número de sectores a leer. DX : Número del sector lógico inicial. DS:BX: Dirección del buffer. Salida: CF :0. no error. CF : 1, error y AX : número del error. AL : código del error DOS. AH : byte de estado. z6h Grabación de disco absoluta. Es análoga a la anterior, pero referida a grabación. FUNCIONES DOS (INTERRUPCION 21h) AH Función lBh Obtener la dirección de la FAT (File Allocotion Table) para la unidad por defecto. Salida: DS:BX: Dirección primer b¡e de la FAT. DX: Número de clusters en el disco. AL : Número de sectores Pot cluster. CX : Tamaño del sector físico' 522 lch Idéntica a la anterior, pero de una unidad determinada. Entrada: DL : Número de la unidad (0: defecto, I : A, etc.). Salida: DS:BX: Dirección primer byte de la FAT. DX : Número de clusters en el disco. AL : Número de sectores por cluster. CX : Tamaño del sector físico. Estas funciones utilizan el registro DS, por lo que debe ser salvado previamente: PUSH DS MOV AH,lBh INT zth MOV AH,[BX] POP DS salvar DS función: obtener información FAT disco actual llamar al DOS AH: primer byte FAT restaurar DS Aplicaciones DIMSECG - Grabar sectores en diskette, DIMSECL - Leer sectores de diskette. DIPDIR - Listado del directorio de un diskette mediante funciones BIOS. Caso de diskettes de doble cara y 9 sectores/pista. DIPFMT - Formatear pistas de un diskette. DIPSECL - Listar sectores de un diskette. Subrutinas: DISFMT - Formatear una pista de un diskette. 523 DIMSECG.ASM MacTo: DIMSECG. Descripción: Grabar sectores en disquete Entrada: dI = unidad (0 a 3) (o=A, 1=B, 2=C, 3=D) dh = cara (o a t-) ch : pista (0 a 39) cl- : sector ini-cial (1 a 9) aL = núnero de sectores a grabar (1 a 9) es: [bx] = dirección área de ¡nemoria con la inforrnación a grabar Sal ida : ah = o- orabación correcta ah = L, error ; ---------- dirnsecg macro loca1 secgb,secgf secAb: secgf: mov ah,3 int l-3h jnc secgb ; función: grabar sectores ; Ilamar al- BIOS ; bifurcar si no error mov ahrljnp secgf i error mov ahro i no error endn DIMSECL.ASM Macro: DIMSECL. nac¡ri n¡ i Án. Leer sectores del disquete Entrada: dl- = unidad (0 a 3) (o=A, 1=B, 2=c, 3=D) dh : cara (0 a l-) = pista (0 a 39) "¡ = sector inicial- (1 a 9) cI aI = número de sectores a leer (l- a 9) es: [bx] = dj-rección área de lectura sal-ida: ah = 0, lectura correcta elt=1 dimsecl macro 1oca1 secl,secl-b,sec1f push di secl-: seclb: mov di,3 push ax mov ahro2h int l-3h jnc secLb mov ahro int l-3h dec di cílp di,o r-J ¡rs ; sal-var registro ; hacer 3 intentos de lectura ; función: leer sectores i l-l-anar al BIoS i bifurcar si no error i función: restaurar disquete ; llamar al BIos ; contador intentos t ¿ya 3 intentos? .. bifurcar pop ax ññir^h1.érro!. jnp seclf pop ax ^hn.h^eI.I.o!. secl f: pop di i restaurar registro i endm 525 DIPDIR.ASM Prograna: DIPDfR. Descripción: Listado del- directorio de un disquete mediante funciones BIOS. Caso de disquetes de doble cara y 9 sectores/pista. Slmbofos: unidad equ 0 ; unidad donde se encuentra el disquete ;O=A,1=8,2=C,3=D nums ec equ 7 ; nro. de sectores que contienen ef directorio nument equ 16*nunsec i nro. de entradas que contiene el directorio t (16 entradas/sector) equ 13 ; retorno de carro ff equ 10 ; alinentación de linea l4acros: if1 include dirnsecl.asn include pamesct.asn include pamescc.asn endif i ---------- pila segment stack db pil-a ends áatos L28 dup ( 'pil-a' ) segment directorio db numsec dup(512 dup('?t)) ; numsec sectores de 512 bytes ; sectores donde se encuentra el- directorio (pista O) secdir nensae bl-ancos áatos i codigo dipdir db db db db db 0,6,4 ; cara 0: a partir del- sector 6, 4 sectores LtL,3 ; cara L: a partir de1 sector 1, 3 sectores ; indica eI final, de la tabla 'Fr r**,t error de acceso aI disquete ***r,cr,If,,$' 4 dup(t t),t$t ; separación entre nonbres ends segnent proc far assume cs: codigo, ds: datos, es:datos, ss:pita poner dirección de retorno aL DOS en la pila ; push ds sub ax,ax push ax ; dj-reccionar segmento de datos con ds y es nov axrdatos mov dsrax mov esrax 526 F I) leer los sectores de1 directorio mov mov lea secEores: mov dl,unidad chro bx,directorio si,o tunidadaleer , pista 0 I bx = desplazarniento directorio ; índice para recorrer La lista ; direccionar segrnento de datos con ds y es ¡nov ax, datos nov dsrax mov esrax mov dh,secdirIsi] i cara a leer cnp dh, rFr ; ¿fin Lista de sectores a leer? je listar mov cl,secdirtsi+11 ; sector inicial a leer' mov alrsecdirIsi+2] i núrnero de sectores a leer dimsecl t leer sectores cmp ahrl i ¿error? jne bien i no ... bifurcar pamesct mensae ; escribir rnensaje de error j¡np f in bien: push bx push dx mov ahr0 ¡nov bx ,5L2 mul bx pop dx pop bx add bxrax add si,3 j¡np sectores II) escribir i salvar bx i salvar dx i ax = nro. de sectores leÍdos , bx = 5)-2 i ax = nro. de bytes leidos ; recuperar dx i recuperar bx i apuntar a siguiente área de lectura ¡ apuntar'a siguiente entrada de l-a lista 1as entradas de1 directorio por pantalla Ii star: direccionar segmento de datos con ds y es nov axrdatos mov dsrax mov esrax 1ea bx, d j-rectorio mov cxrnunenc entrada: push bx cnp byte ptr [bx],0e5h je otra cnp byte ptr [bx]'00h jne escnom pop bx jnp fin i bx = despl-azaniento directorio r nro. de entradas deL directorio ; sal-var registro i ¿entrada vacía? ; si ... bifurcar ¡ ¿fin de entradas del directorio? i no .,. bifurcar i restaurar registro ; escribir nombre 527 nombre: mov d1r8 i 8 = fongitud del nombre del fichero mov al, [bx] ; obtener carácter escribir carácter por pantafla inc bx i apuntar a siguiente carácter dec dli ¿más caracteres? jnz nombre t si ... bifurcar | | ñ^ñóe^^ escribir carácter por pantalla h.ñóe^^ ^l escribir extensión ex ten: mov d1r3 ; 3 = longitud de 1a extensión mov a1, [bx] ; obtener carácter pamescc al; escribir carácter por pantalla inc bx ; apuntar a siguj-ente carácter dec dl t ¿nás caracteres? jnz exten ; si ... bifurcar pamesct blancos ; escribir texto por pantalla ; apuntar a la siguiente entrada de1 directorio otra: pop bx i recuperar registro add bxt32 i 32 es la longitud de cada entrada loop entrada ; volver aI DOS AinAi¡ ends end dipdir 528 DIPFMT.ASM . í . Dr^drrñ.. nTDFMT nae¡rin¡iÁn. Formatear pistas de un disquete. i i SÍmbolos:'iñi nic+r édr! "a pista_fin equ 39 cr equ 13 If equ l-0 . t nicfr r¿vvs inini¡l ; pista final ; retorno de carro r alinentación de linea ; Procedimientos externos: extrn di-sfmt: f ar extrn pastexto:far pila pila ; segment stack 128 dup('pj.Iai) db ends ---------- datos písta cara sector segment para tdatosl db db db i mensai db db ^L db db mensam db Ah mensab db pp d$/ db Áh? Ah error db datos ends i codigo Aihfñ+ ; numero de Ia pj,sta (o a 39) ; numero de Ia cara (0 o l-) i numero del- sector (l-a 9) ? ? ? cr,l-f rFormatear pistas de un disqueter rcrrlf t-----_____ ---_____-_t ^- 1 t cr,l-f r$' r*** Error al formatear pista ***r,cr,If t<l rPista: ? I ^P ? t cara: I 1€ lcl ; indicador error (1 = si, 0 = no) segment hF^^ fr? assume cs 3 codigo , ds : datos , ss : pila i poner dirección de retorno a1 DOS en l-a pila Push ds sub axrax push ax ; direccionar segnento de datos datos con ds mov axrdatos mov ds,ax 529 escribir mensaje inicial por pantalla push ds lea axrnensai push ax call pastexto ; formatear pistas i cal-l- procéso ret Áinfn{. ; ; retorno al- DoS óñAñ ---------- proceso proc i formatear pistas nov pista,pista_ini r pista inicial- t ; bucle pistas hrl^1a ñie. mov carar0 i cara 0 ; bucle caras bucle car: push ds l-ea ax, p j-sta push ax t Pista push ds 1ea ax, cara push ax ; cara push ds ; indicador error l-ea push ax ^^ i . I l disf¡nt escribir nensaje call ¡hanrr¿a fin fornatear pista bucfe caras i inc cara cara,1 bucle_car i ; chequeo fi.n bucle pistas cmp cara=cara+1 , €¡ ¿rrrr - ^^-^^t udroó: il6 J'* inc i fproceso: 530 . cmp pista, pista_ fin il6 hrr^ló hi< , nic+r r4seq : nicf: ; ¿fin pistas? +1 ret óhÁñ ; emensa proc ; ver si formateo correcto (error : 0) o no (error = 1) cmp error,l t ¿error aI formatear? je ma1 ; si ... bifurcar i ; escribir mensaje de pista y cara formateada mov ah,0 ^l hicfa mov bI,10 dj-v b1 add ax, r00' mov PP,ax mov al,cara add a1, rOt mov cc,al , aX = pfsra ; bl- = 10 (constante) ; ah : resto, aI : cociente i convertir a carácter ascii ; pp : pasta ; al = cara ; convertir a carácter ascii ; cc = cara lea ax,mensab i apuntar aI mensaje a escribir jnp escri al- formatear, escribir rnensaje escr.l-: Lea ax,mensam ; apuntar a1 nensaje a escribir push ds call pastexto femensa: éménca i codigo rec onÁn ends end dipfnt 531 DIPSECL.ASM ; Programa: DfPSECL. ; Descripción: ; Listar sectores de un disquete. t SÍmbolos: unidad equ 0 ; unidad (0=A, 1=B, 2:C, 3:D) cr equ l-3 ; retorno de carro 1f equ 10 i aliméntación de linea t Procedimientos externos: extrn pasborra: far extrn pastextos far extrn pastxt: far extrn tesleer: far extrn tesespersfar i Macros: if1 include dimsecL.asm incfude pamcur.asm endif pila pila ; i segment stack db 128 dup ('pila') ends ---------- datos par xdb? vdb? n bloque seqment label byte dr^¡ db rnensai db db db rnensac db db ; colu¡nna ; fila 5L2 i nro. de bytes de bloque 512 dup(?) i área de entrada rTeclear Pista(O-39): Cara(O-1): cr,Lf, | (Enter para terminar) r,cr,lf,cr,1f '$, t==> Pulsar una tecfa para continuart r$t ; area de parámetros para lectura de teclado 't nro. naximo de caracteres a teclear ; (incluyendo cr) ? ; numero de caracteres tecl-eaLos ; (sin inclui.r cr) 2 dup(?) ; caracteres tecl-eados rrt** [¡¡q¡ de lectura ***t entrada 1abe1 byte maxcars db ? numcars db ent db nensae db 532 cara pista sector ^h datos ends db db db Sector(1-9): vL, ^F ? ? ? lf LL. lQl J , cara (0,1) ; pista (o-39) i sector(]--g) codigo segment dipsecl proc far assume cs : codigTo , ds : datos , es : datos , ss : pila ; poner dirección de retorno aL Dos en J-a pila push ds sub ax, ax push ax ; direccionar segmento datos con ds y es mov axrdatos mov dsrax mov es, ax i borrar l-a pantalla empezar: cal-f pasborra poner cursor en (0,0/ pamcur 0r 0 escribir rnensaje inicialpush ds 1ea ax,mensai call pastexto push ax leer de teclado eL núnero rla l¡ nicl.¡ pamcur 21,10 i posicionar cursor en campo pista nov maxcars,3 i 2 dígitos rnáxi¡no push ds t área de entrada 'lpa aw onfrad¿ push ax call tesl-eer clnp numcars, 0 ; ¿se pulsó enter? jne con_pis ; no ... bifurcar j¡np f in ; convertir pista de ascii a binario con_pis: ^l 6ñl. sub al-, r 0l mov bI,10 ¡nul b1 mov pista,al nov alrent+L sub al, r0l add pista,al dígito superior convertir a binario bL = 10 (constante) aL = l-O*dÍgtito superior pista = 1o*dÍgito superior al = digito inferior convertir a binario leer de teclado el número de la cara pamcur 37'0 ; posicionar cursor en campo cara mov maxcars,z , f digito máximo 533 push ds 'I ea ; área de entrada aY. pntrada push ax cal-l tesleer convertir cara de ascii a binario ¡lov al, ent ; al = cara (carácter ascii) sub a1, ¡0 | - .; a1 = cara (binario) mov cara,al, i leer de tecl-ado e1 número de1 sector ,' posicion¿¡r cursor en campo sector ; área de entrada pamcur 54 r 0 push ds Lea ax,entrada push ax cal-1 tesleer ; convertir número del- sector de ascii a bi,nario mov aL,ent i al = nro. def sector (carácter ascii) sub al,r0l ; al = nro. del- sector (binario) -ó^+^e 5I leer sector de disquete mov dl, unidad Ah ¡¡r¡ mov ch,pista mov cl,sector mov al-, 1 l-ea bx, bl-oque ; dl- = nro. de La unidad ; dh = nro. de la cara t ch = nro. de 1a pista i cI = sector inicial a l-eer i aI = nro. de sectores a feer i bx = desplazamiento bloque dimsecl ; Ieer sector iah=0=bien,ah=1:mal; ; investigar si lectura correcta o errónea cmp ahr l i ¿el.ror? ; si ... bifurcar 1e mal; lectura correcta mov Xr0 rnov y ,4 ;x=cofumna0 ;Y=fi1a4 ; escribir directamente en nemoria de pantaffa eI sector feÍdo push ds 1ea ax,par ; par push ax Larr PasL^L ; escribir mensaje de continuación sequir: pamcur 0,24 i posicionar cursor en (O,24) push ds lea ax,mensac pusfr ax caLl- pastexto 534 ^ál I +ócé<hór jnp empezar ; espera a que se Pulse una tecla error de fectura ; posicionar cursor en (0,4) eserihir mensaie de error pamcur 0,4 push ds Iea ax, mensae cal,l pastexto jmp seguir push ax fin: cal-f pasborra ret A i n<a¡l ; borrar pantafla ; retorno al Dos a¡¡ln ; ¡aÁ i an a¡¡lc end dipsecl- 535 DISFMT.ASM Subrutina: DISFMT. Función: Formatear una pista de un disquete. Parámetros: params struc bp salvado por 1a subrutina dirección de retorno dirección parámetro 3 (sa1) (1 byte) indicador error (0 = no, 1 = si) dirección paránetro 2 (ent) (l- byte) d\,/ retorno dd p3 dd p2 dd p1 dd a params ends SÍmbolos: núnero de la cara (0 o l-) dirección paránetro 1 (ent) (1 byte) número de 1a pista (o a 39) unj-dad equ 0 nsectores equ 9 Lsector equ 2 cr 1f nret áato= nro. de Ia unidad (0=A, 1=B, 2=C, 3=D) nro. de sectores/pista indicador longitud sector O - 128 bytes L - 256 bytes 2 - 512 bytes 3 - 1-024 bytes equ 13 retorno de carro equ 10 alinentación de linea equ offset pL - offset retorno i argumento de ret segment ; Campo asociado a cada sector de una pista: crh,r,n i c - nro. de la pista (0 a 39) ; h = nro. de 1a cabeza (0 o 1) i r = nro. del sector (l_ a 9) i n = indicador nro. de bytes por sector info db O,O,L,lsector ; sector ldb OrO,2tlsector ; sector 2 db 0,0,3,1-sector i sector 3 db O,O,4, l-sector ; sector 4 db O,O15,l-sector i sector 5 db O,O,6,1sector i sector 6 db 0,0,7,lsector i sector 7 db 0r0r8,1sector i sector 8 db O,O,9,l-sector ; sector 9 i pista db ? i nro. de l-a pista cara db ? i nro, de l-a cara sector db ? i nro. de} sector datos ends ; ---------- codigo ; disfnt 536 segment assume cs: codigo, es:datos public disfrnt proc far push bp i salvar bp bp, sp ,!P--P safvar registros afectados push ds push es pusfr ax push bx push cx push dx push si direccionar segnento de datos con es mov ax,datos mov es,ax i recoger parámetros de entrada lds si, [bp].pl; ds = segmento, si = desplazamiento mov af,ds: Isi] ; pasta pista, mov al Ids si, Ibp].p2 mov al,ds: Isi] nov cara,al i ds = segmento, si : desplazamj-ento t cara i ; relleno de los campos de información de una pista mov sector, I i sector inicial mov bl-,4 (constante) ;b1=4 mov cxrnsectores ; cx = contador bucfe ; bucLe sectores bucle: mov al", sector dec al mu1 b] mov s1,ax mov al,pista mov infoIsi],a1 mov al, cara mov infotsi+11,al inc sector Ioop bucle i formatear pista f orma]: mov bx, offset info mov ch, p j-sta mov al,nsectores mov dl,unidad mov dh,cara mov ah,5 int l-3h jc formal mov aI,0 jnp movind a1 : sector a1:sector-L ax:4*(sector si:4*(sector nnr¡ar nicl-a - 1) - 1) mover cara sector=sector+l- bx = desplazamiento inf. pista es:bx = dirección inf. pista pista "¡ = de sectores a formatear nro. d1 = unidad dh : cara funcion: formatear sectores 'L-Lamar ar lJ-Lu5 bifurcar si cf:1 (error) aI = 0, fectura correcta 537 mov al-, 1 : al : 1 lectlrra crróoea ; poner parámetro de sal-j.da novind: lds si, [bp].p3 i ds = segmento, si : desplazatniento mov ds: Isi],a1 ; indicador error ; restaurar regfistros afectados pop si pop dx pop cx pop bx pop ax pop es pop ds mov pop ret disfnt endp codigo ends end sp, bp bp nrec resEaurar bp 26 Acceso a f¡cheros Hemos visto que el BIOS suministra servicios de acceso a los sectores individuales de un disco. Pero normalmente las aplicaciones crean y actualizan ficheros. Un fichero es una colección de registros de datos. Cada fichero se almacena en el disco con un nombre único, nombre que se registra en el directorio. El DOS suministra justamente el soporte necesario para este tipo de acceso, es decir, el acceso a ficheros de datos. Para ello gestiona la reserva del espacio físico necesario en el disco y nos informa de condiciones de error, como, por ejemplo, si se ha agotado el espacio disponible. Los niveles de entrada/salida de disco quedan reflejados en el esquema siguiente: Entrada/Salida de ficheros Entrada/Salida de sectores 539 Comandos adaptador de disco Señales hardware Unidad de disco Registros y bloques Un registo es la unidad de información de un fichero. Puede tener uno o más b¡es, pero este número es constante para un fichero dado. Desde el punto de vista del programa, los datos se leen o escriben a nivel de un registro cada vez. Los registros a su vez se agrupan en bloques. Cada bloque puede contener hasta 128 registros. Los registros de un bloque se numeran de 0 a 127. Los bloques se numeran a partir de cero. Para localizar un registro sobre el fichero, el DOS necesita, pues, que se le suministren dos números: ¡ El número del bloque. o El número del registro dentro del bloque El número de registros por bloque es también una constante para un fichero dado, con la excepción del último bloque del fichero, que puede estar incompleto. Areas referenciadas por el DOS Las funciones DOS referencian dos áreas de datos en memoria: El FCB o Bloque de Control de Fichero (File Control Block). Por cada fichero que deseemos procesar es necesario crear un FCB. El FCB contiene información que necesita el DOS para poder gestionar el acceso al fichero. El DTA o Area de Transferencia de Disco (Disk Tronsfer Area). Es un área de memoria (buffed que se utiliza para la entrada/salida. EL FCB O BLOQUE DE CONTROL DE FICHERO (FrLE CONTROL BLOCK) Son 37 b¡es, con la estructura siguiente. Desplaz. Longitud Campo 0 I Unidad (l a 4, que corresponde con A a D) I 8 Nombre del fichero Extensión del fichero Bloque actual Tamaño del registo (bytes) 9 t2 t4 2 2 l6 + Tamaño del fichero (bytes) (bytes en orden 20 22 2 l0 32 I JJ 4 Fecha de la última actualización Reservado para el DOS Registro actual dentro del bloque (0 a 127) Registro relativo (bytes en orden inverso) inverso) La directiva STRUC es muy útil enieste caso para hacer una referencia cómoda a los campos. Por ejemplo, ep el programa FIPSEC se define: FCBS STRUC UNIDAD DB ? ; unidad (l-4, que corresponde ; conAaD) NOMBRE DB 8 DUP(?) ; nombre primario EXTENS DB 3 DUP(?) ; exrensión NROBLO DW ? ; número del bloque LONGREG DW ? ; longitud del regisrro LONGFIC DW 2 DUp(?) ; longitud del fichero FECHA DW ? ; fecha de la última actualización NROREG 3B NROREGR IO DUP(?) : fjtrJ.f:J?:ffiI3"' DB 2 DUP(?) j número del relistro relarivo FCBS ENDS EL DTA O AREA DE TRANSFERENCIA DE DISCO (DISK TRANSFER AREA) Al leer un fichero, los datos se sitúan en el DTA. Al grabar, los datos se supone que se encuentran sobre el DTA. El DTA debe ser lo suficientemente grande para que albergue el bloque de datos más grande a leer o escribir. Cuando el DOS pasa el control al programa (desde el procesador de comandos COMMAND.COM), el DTA se fija en la posición 80h del PSP v1 (Prefijo de Segmento de Programa). Como la longitud del PSP es de l00h :256 b¡es, la longitud del DTA inicial es l00h-80h : 80h -- 128 bytes. Mediante una función DOS puede cambiarse la dirección del DTA. Proceso de un fichero Se realiza con las funciones DOS (interrupción 2lh). Cada función se corresponde con un valor de AH. Estas funciones permiten crear ficheros, leer y grabar registros, crear directorios, etc. El proceso del fichero implica los pasos siguientes: . Se sitúa la unidad y el nombre del fichero sobre el FCB. o Se abre el fichero con DS:DX apuntando al FCB. Con esta operación, el DOS localiza el fichero en el disco y sitúa información sobre el FCB. El DOS rellena concretamente los campos: tamaño del fichero, fecha y el campo reservado. . A partir de este momento se puede leer o escribir sobre el fichero mediante las correspondientes funciones DOS. Existen tres tipos de accesos al fichero. . Secuencial. . Al azar (Random). . Al azar por bloques (Random Block). o Una vez procesado el fichero, es necesario cerrarlo. Esto se hace mediante una función DOS, con DS:DX apuntando al FCB. ACCESO SECUENCIAL El acceso a los registros del fichero comienza en el primer registro del fichero, luego con el segundo, etc. Cuando se ejecutan las funciones DOS de lectura/escritura secuencial, el DOS accede al registro especificado por los campos bloque actual y registro actual del FCB, actualizando a continuación estos campos para que apunten al siguiente registro del fichero. Se debe especificar el tamaño del registro en el correspondiente campo del FCB e inicializar los campos de bloque actual y registro actual con cero. Con ello nos aseguramos de que el proceso empezará desde el principio del fichero. A partir de este momento, estos campos los acttalizará el DOS de forma automática. il2 ACCESO AL AZAR Este sistema permite acceder a un registro determinado del fichero. Se utilizan para ello las funciones DOS de acceso al azar. El registro a acceder se especifica mediante el número de registro relativo. El primer registro del fichero tiene como número de registro relativo el valor cero. En el campo "registro relativo" del FCB hay que especificar dicho número. El DOS lo convierte en sus equivalentes "número de bloque actual" y "número de registro actual" antes de que tenga lugar la operación. ACCESO AL AZAR POR BLOQUES Este sistema es similar al anterior con la particularidad de que se puede transferir más de un registro a la vez. En este caso hay que especificar un número de registro relativo en el FCB y el número de registros a transferir en CX (contador). Proceso de errores Cuando el DOS detecta un error crítico, se ejecuta la interrupción 24h, que a su vez pasa el control al gestor de errores que reside en el COMMAND.COM. El usuario podría definir su propia rutina de gestión de errores cambiando el vector de interrupción 24h. El Fíle Handle A partir del DOS 2.0 existe un procedimiento mucho más sencillo de acceso a ficheros, no existiendo necesidad de utilizar el FCB. Para ello se utiliza: o Cadena ASCIZ del nombre del fichero. Se compone de unidad, camino o sendero (path), nombre del fichero y un byte de ceros binarios (00h) al final. Tras invocar la función de abrir el fichero. la función devuelve en una palabra el número identificador del fichero (File Handle), con el que en adelante se referencian las restantes funciones. Los identificadores de ficheros predefinidos por el DOS son: s¿lil Identificador (File Handle) 0 I 2 3 4 Dispositivo | estándar de entrada I estándar de salida | estándar de salida de errores I estándar auxiliar | estándar de impresión Los ficheros tipo texto Los ficheros creados con un editor (EDLIN, EDIT, PE) son de tipo texto. Las características de estos ficheros son: ¡ Cada registro del fichero es de un byte de longitud. Cada registro contiene un carácter ASCII. o El final de cada línea se denota mediante los caracteres: . Retorno de carro (corriage return: 13 :ODh). . Alimentación de linea (line feed : l0: 0Ah). Con objeto de ahorrar espacio en disco, normalmente los caracteres blancos se comprimen de la manera siguiente: cuando una serie de blancos consecutivos alcanzan una posición en la línea de texto que corresponde a una posición del tabulador (tab stop), que es siempre un múltiplo de 8, entonces la serie de blancos se sustituye por el carácter de control 09h (tabulador). Un programa que trate de acceder al fichero (programa FIPSEC) debe convertir cada carácter de tabulación en una serie de blancos hasta la siguiente posición múltiplo de 8. Por ejemplo, la serie de caracteres: l2 0l 2345678901234567 890 - poslclones se convlerten en l2 0t234567801234567890 ABC H DEFHGHI siendo H :09h. ilA + pOSrClOfl€S Funciones DOS correspondientes a fa interrupción 21h AH Función ODh Restaurar disco. Elimina los buffirs de todos los ficheros. Los ficheros no cerrados no quedan bien registrados en el directorio. OEh Seleccionar unidad de disco por defecto. Entrada: DL : número de la unidad (0: A, I : B, etc.). Salida: AL: número de unidades lógicas en el sistema (dos para el caso de una sola unidad física). Observaciones: o Una alternativa es la interrupción BIOS 11h. 0Fh Abrir fichero existente. Entrada: DS:DX : dirección FCB sin abrir. Salida: si fichero encontrado AL :0 si fichero no encontrado AL: FFh si FCB (unidad¡ :6 FCB (unidad): unidad actual (l : A, 2: B, etc')' FCB (bloque actual) : Q. FCB (longitud del registro) : 80h. FCB (tamaño del fichero) : información directono. FCB (fecha) : información directorio' Observaciones: o Tras la apertura, hay que especificar los campos del FCB: . Longitud del registro (si 80h es insuficiente). . Registro al azar/registro actual. l0h Cerrar fichero. El directorio se actualiza para reflejar el estado del FCB. 545 Entrada: DS:DX: dirección FCB abierta. Salida: si fichero encontrado AL:0 AL: FFh si fichero no encontrado llh Buscar la primera entrada. Se pueden usar los caracteres globales "*" y "?" en el nombre del fichero. Entrada: DS:DX: dirección FCB sin abrir. Salida: si algún fichero encontrado AL:0 DTA (primer byte) : unidad actual (l : A, 2 =8, etcétera). DTA (b¡es siguientes) :32 bytes de la entrada del directorio. si ningún fichero encontrado AL: FFh r2h Buscar la siguiente entrada. Entrada: DS:DX:dirección FCB (la misma que en llh). Salida: si algún fichero encontrado AL:0 t DTA (primer byte) : unidad actual (l : A, 2: B, etcétera). DTA (bytes siguientes) : 32 bytes de la entrada del directorio. si ningún fichero encontrado AL: FFh l3h Borrar fichero. Entrada: DS:DX : dirección FCB sin abrir. Salida: si fichero encontrado AL:0 si fichero no encontrado AL: FFh 14h Lectura secuencial sobre DTA (área de transferencia de disco). Se Iee el registro apuntado por los campos FCB "bloque actual" y "registro actual". Tras la lectura, se incrementa la dirección del registro. Entrada: DS:DX: dirección FCB abierta. a$ Salida: si operaclon sln error AL:0 si operación con error AL+O Errores: AL : l, no hay datos en el registro. AL:2, no hay espacio en el segmento para el registro. AL:3, registro leído parcialmente. l5h Grabación secuencial desde DTA (área de transferencia de disco). Se graba el registro apuntado por los campos FCB "bloque actual" y "registro actual". Tras la grabación se incrementa la dirección del registro. Entrada: DS:DX: dirección FCB abierta. Salida: si operación sin error AL:0 si operación con error AL É,0 Errores: AL: l. disco lleno. AL :2, no hay espacio en el segmento para el registro. l6h Crear fichero. Si el fichero existe, se abre y la entrada en el directorio se pone con longitud 0. Entrada: DS:DX: dirección FCB sin abrir. Salida: si fichero encontrado AL:0 AL: FFh si fichero no encontrado t7h Renombrar fichero. Cada aparición del primer nombre en el directorio activo se cambia por el segundo. Entrada: DS:DX : dirección FCB que contiene un segundo nombre de fichero en FCB + 17. Salida: si algún fichero encontrado AL :0 si ningún fichero encontrado o se intentó renombrar con un nombre ya existente AL: FFh l9h Obtener el número de la unidad por defecto. il7 Salida: AL : número de la unidad por defecto (0 : A, I : B, etcétera). lAh Establecer el DTA (área de transferencia de disco). Entrada: DS:DX = dirección del DTA. zlh Lectura al azar sobre DTA (área de transferencia de disco). Se lee el registro apuntado por el campo "registro al azar" del FCB. Entrada: DS:DX : dirección FCB abierta. Salida: si operación sin error AL:0 si operación con error AL#O Errores: AL: l, no hay más datos disponibles. AL = 2, no hay espacio en el segmento para el registro. AL = 3, registro leído parcialmente. 22h Grabación al azar sobre DTA (área de transferencia de disco). Se graba el registro apuntado por el campo "registro al azaf" del FCB. Entrada: DS:DX: dirección FCB abierta. Salida: si operación sin error AL:0 si operación con error AL+O Errores: AL: 1. disco lleno. AL: 2, no hay espacio en el segmento para el registro. 23h Obtener el tamaño del fichero (en registros). Entrada: DS:DX: dirección FCB sin abrir. FCB Qongitud registro) : valor. Salida: si fichero encontrado AL:0 FCB (registro al azar): número de registros del fichero. si fichero no encontrado AL: FFh 24h Especificar registro al azar. 548 Entrada: DS:DX: dirección FCB abierta. Salida: si fichero encontrado AL :0 FCB (registro al azar): información correspondiente a FCB (bloque actual) y FCB (registro actual). si fichero no encontrado AL: FFh 27h Lectura de bloque al azar sobre DTA (área de transferencia de disco). Se leen los registros apuntados por el campo "registro al azar" del FCB. Tras la lectura, los campos "registro al azar", "bloque actual" y "registro actual" se actualizan para apuntar al siguiente registro. Entrada: DS:DX: dirección FCB abierta. CX = número de registros a leer. Salida: CX número de registros leidos. = si operación sin error AL:0 si operación con error AL +O Errores: AL: 1, fin de fichero. AL: 2, no hay espacio en el segmento para los registros. AL: 3, bloque leído parcialmente. 28h Grabación de bloque al azar desde DTA (área de transferencia ('rede disco). Se graban los registros apuntados por el campo gistro al azar" del FCB. Entrada: DS:DX: dirección FCB abierta. CX : número de registros a grabar. Salida: CX : número de registros grabados. si operación sin error AL:0 si operación con error AL +O Errores: AL: l, no se escribió ningún registro (disco lleno). 2Fh Obtener la DTA (área de transferencia de disco). Salida: ES:BX: dirección de la DTA activa. 39h Crear un subdirectorio. 549 Entrada: DS:DX : dirección cadena ASCIZ con la unidad y los nombres de los caminos del directorio. Salida: si operación sin error CF:0 si operación con error CF:l AX : número del error (3, 5). 3Ah Borrar un subdirectorio. Entrada: DS:DX: dirección cadena ASCIZ con la unidad y los nombres de los caminos del directorio. Salida: si operación sin error CF=0 si operación con error CF:l AX: número del error (3, 5). 3Bh Cambiar el subdirectorio activo. Entrada: DS:DX: dirección cadena ASCIIZ con la unidad y los nombres de los caminos del directorio. Salida: si operación sin error CF:0 si operación con error CF:l AX: número del error (3). 3Ch Crear un fichero. Entrada: DS:DX: dirección cadena ASCIZ con la unidad. camino y nombre del fichero. CX: atributo del fichero. Salida: si operación sin error CF :0 ¡Y: file handle si operación con error CF :1 AX: número del error (3, 4, 5\. Observaciones: o Si el fichero no existe. se crea un nuevo fichero con acceso lectura/escritura. o Si el fichero existe, su longitud se trunca a cero. 550 3Dh Abrir fichero. Entrada: DS:DX: dirección cadena ASCIZ con la unidad, camino y nombre del fichero. AL: código de acceso: 0 - lectura I - escritura 2 - lecturayescritura Salida: si operación sin error CF :0 ¡y: file handle si operación con error CF:l AX : número del error (2, 4, 5, l2). Observaciones: r El puntero de lectura/escritura se posiciona en el primer byte del fichero. 3Eh Cerrar fichero. Entrada: 9y : file hundle. Salida: si operación sin error CF:0 si operación con error CF:l AX: número del error (6). 3Fh Leer fichero. Entrada: gY : file handle. CX: número de bytes a leer. DS:DX: dirección del buffer. Salida: si operación sin error CF :0 AX: número de b¡es leídos (si AX:0, se leyó el fin de fichero). si operación con error CF:l AX : número del error (5, 6). 40h Grabar fichero. Entrada: gY = file handle. CX : número de bytes a grabar. DS:DX: dirección de los datos a grabar. 551 Salida: si operación sin error CF :0 AX: número de bytes grabados si operación con error CF:1 AX = número del error (5, 6). 4lh Borrar fichero. No se permiten caracteres globales en el nombre del fichero. Entrada: DS:DX: dirección cadena ASCIZ con la unidad. camino y nombre del fichero. Salida: si operación sin error CF :0 si operación con error CF:1 AX: número del error (2, 5). 42h Mover el puntero de lectura/escritura. Entrada: B.Y: file handle. CX,DX: desplazamiento (CX es el valor más significativo). AL: método. 0 - el puntero se mueve desde el comienzo del fichero. I - el puntero se desplaza desde la posición actual. 2 - el puntero se mueve desde el final del fichero. DS:DX: dirección cadena ASCIIZ con la unidad. camino y nombre del fichero. Salida: si operación sin error CF: O DX,AX: nueva posición del puntero (DX es el valor más significativo). si operación con error CF:l AX = número del error (1, 6). 43h Obtener/poner el atributo de un fichero. Entrada: DS:DX: dirección cadena ASCIIZ con la unidad. camino y nombre del fichero. AL: código de la función. 0 - obtener atributo del fichero. I - poner atributo del fichero. 552 CX: atributo del fichero. Salida: si operación sin error CF :0 si AL:0 CX: atributo si operación con error CF:l AX: número del error (3, 5). 47h Obtener el directorio activo. Entrada: DL : número de la unidad (0: defecto, I = A, etc.). DS:SI : dirección del área de 64 bytes donde se va a guardar el nombre del directorio activo, desde el directorio raiz, y terminando con 00h. Salida: si operación sin error CF :0 si operación con error CF:l AX: número del error (15). 4Eh Buscar primer nombre de fichero en el directorio activo. El nombre puede incluir caracteres globales "*" y "?". Entrada: DS:DX : dirección cadena ASCIIZ con la unidad, camino y nombre del fichero. CX: atributo de los ficheros a buscar. Salida: si operación sin error CF :0 si operación con error CF:1 AX: número del error (2, l8). Observaciones: o Si se encontró el fichero, el DTA activo tendrá: 21 bytes - reservados para el DOS. I byte - atributo del fichero. 2 bytes - hora del fichero. 2 b¡es - fecha del fichero. 2 bytes - palabra inferior con tamaño del fichero. 2 bytes - palabra superior con tamaño del fichero. l3 bytes - nombre y extensión del fichero encontrado, seguido por un byte de ceros binarios. 553 4Fh Buscar siguiente nombre de fichero. Entrada: DTA con información anterior. Salida: si operación sin error CF:0 DTA con la estructura de la función anterior. si operación con error CF :1 AX: número del error (18, si no se encuentran más ficheros). 56h Renombrar un fichero. Entrada: DS:DX: dirección cadena ASCIIZ con la unidad, camino y nombre del ficher'o. : ES:DI dirección cadena ASCIIZ con el camino y nombre del fichero nuevo. Salida: si operación sin error CF =0 si operación con error CF :1 AX: número del error (3, 5, I7). 57h Obtener/poner fecha y hora de un fichero. Entrada: AL :00h (obtener) o AL:Olh (poner). p'y:file handle. si AL:01h DX: fecha CX : hora Salida: si operación sin error CF :0 AX:0 si obtener DX: fecha CX : hora si operación con error CF :1 AX: número del error (1, 6). 554 Aplicaciones Mocros: FIMABRIR FIMCERR FIMCREA FIMCRAB FIMLEER FIMPUNT Abrir un fichero ya existente. Cerrar un fichero. Crear un fichero nuevo o truncar a cero la longitud de un fichero existenteGrabar un registro en un fichero. Leer un cierto número de bytes de un fichero. Mover puntero de lectura/escritura al final del fichero. Programos: FIPLISTA FIPREGS FIPSEC Listado de un fichero por pantalla. Ejemplo de utilización del identificador de fichero (file hondle). Crea una serie de registros iguales en un fichero nuevo o añade esos mismos registros a un fichero ya existente. Listado fichero secuencial mediante FCB. Subrutinas: FISERROR FISPARAM Escribe un mensaje de error asociado a un número de error en acceso a ficheros. Obtener el nombre del fichero del PSP en forma de cadena ASCIIZ. 555 FIMABRIR.ASM MacTo: FIMABRIR. Déscripción: Abrir un fichero ya existente. E1 puntero de lectura/escritura del fichero. Parámetros se posiciona en el prirner byte 3 fichero : cadena asciiz con unidad, sendero y nombre del" fichero. acceso = código de acceso (ent) (L byte) (variable, registro, valor inmediato): 0 - sóIo lectura 1 - só1o escrÍtura 2-lecturayescritura handle = Identificador fichero (fil-e handLe) (sal-) (l- pal-abra) (variable) . error = Núnero de1 error (sal) (l- palabra) (variable). si no hay error, error = 0. Los errores posibles son 2, 4, 5 y 1,2. : ----+----- finabrir macro fichéro, acceso,handle, error Iocal bien, fin salvar regj-stros afectados ; push ax push dx i recoger parámetros de entrada Lea dxrfiehero r dx = desplazarniento fichero mov alracceso t a1 = acceso ; t abrir el fichero rnov ah,3dh int 2Lh función: abrir fichero llarnar al- DoS si no error, cf = 0 y axX = identificador fichero si error, cf = L y ax = código del error jnc bien si cf = 0, bifurcar error, ponér parárnétros mov error,ax ; de salida código del- error i no errór, poner parámetros de salida bien: mov handlerax ; file handle mov errorro i error = 0 i restaurar registros afectados t1n: pop dx pop ax éndm 566 FIMCERR.ASM i ; MacTo: FTMCERR. . i nóc^Fiñ^iÁñ. Cerrar un fichero. ; Parámetros: ; hand]e = Identificador fichero (fiIe handle) (ent) (1 palabra) (variable, registro bx). i error i = Número del error (sal) (1 palabra) (variabfe). si no hay error/ error : 0. E1 error posible es eI 6. ; : ---------- fimcerr macro handle,error ; salvar registros afectados push ax ; ; recoger parámetro de entrada nov bx,handle i bx = identifi-cador fichero ; cerrar el- fichero mov ah,3eh ; función¡ cerrar fichero int 2l,h ; l-l-anar aI DoS : si no error- cf = 0 cf = 1- y ax = código del- error ; si error, i jnc bien ; si cf = 0, bifurcar ; error, poner parámetro de salida mov errorrax -inn f i n ; código de1 error ; ; no error, poner parámetro de salida bien: mov errorro t error = 0 i ; restaurar registros afectados fin: pop bx pop ax endrn 557 FIMCREA.ASM Macro: FIMCREA. Descripción: crear un fichero nuevo o truncar a cero 1a lonqitud de un fichero existente. Parámetros: fichero = cadena asciiz con unidad, sendero y nombre del fichero. atrib = atributo del fichero (ent) (L pa]abra). 0 - lectura/escritura. handl-e = Identificador fichero (file handle) (sa1) (1 palabra) (variable) . error = Número deI error (sal) (l- pal-abra) (variabLe). Si no hay error, error = 0. Los errores posibles son 3, 4 y 5. ; ---------- fimcrea macro ficheroratribrhandlererror locaI bien, fin ; salvar registros afectados push ax push cx push dx i recoger parámetros de entrada lea dx, fichero ; dx = desplazarniento fj.chero mov cx,atrib i cx = atributo del fichero ; crear el, fichero mov ah,3ch i función: crear fichero int 2l-h r l]amar a1 DOS ; si no error, cf = 0 y ax = identificador fichero cf = 1 y ax = código del- error ; si error, i jnc bien ; si cf = 0, bifurcar i error, poner parámetros de salida mov error,ax ; código del- error jnp fin i no error, poner parámetros de salida bien: i mov handle,ax mov errorro ; fil-e handle t error = 0 i restaurar regj-stros afectados fin: pop dx pop cx pop ax endm 558 FIMGRAB.ASM í ; Macro: FfMGRAB. i Descripción: i Grabar un registro en un fichero. ; Los bytes se graban a partir de la actual posición del- puntero ; sobre el- fichero. ; Parámetros: t handle : fdentificador fichero (file handl-e) (ent) (l- palabra) (variable o registro bx). t ; nbytes1 : Número de bytes a grabar (ent) (1 palabra) (variable, registro cx, valor inmediato). i area i = Area a grabar (ent) (variable). t nbytes2 = Número de bytes grabados (sal) (l- palabra) (variable). Si es cero, se ha tratado de leer a partir del- fj.n ; ; de fichero. error i = Número deI error (sal) (1 palabra) (variable) Si no hay error, error = 0. t Los errores posibles son 5 y 6. , ; ---------- iirngrab macro handle, nbytesl , area , nbytes 2 | error Local bien, fin i salvar registros afectados push ax push bx push cx push dx ; t""oger parámetros d.e entrada mov bx,handlé i bx = identificador fichero mov cxrnbytesl i cx = nro. de bytes a grabar l-ea dxrarea t ds:dx apunta a área a grabar i grabar registro mov ah,40h int 2Lh t t t ; función: grabar registro r 1lamar al Dos I ax = nro. de bytes qrabados si no error, cf = 0 si error, cf = l- y ax = código del error jnc bien ; si cf = 0, bifurcar i error, poner parámétro de salida mov error,ax t código del error jnp f j-n i no error, poner parárnetro de salida mov nbytes2,ax mov errorr9 i nro. de bytes grabados , error = 0 i restaurar registros afectados 559 fin: pop pop pop pop endn 560 dx cx bx ax FIMLEER.ASM MACTO: FIMLEER. Descripción: Leer un cierto número de bytes de un fichero. Los bytes se leen a partir de 1a actual posición de1 puntero sobre el- fichero. Si e1 número de bytes Ieídos es cero' se alcanzó e1 fin de fichero. Parámetros 3 handle = Identificador fichero (fite handle) (ent) (l' pafabra) (variable o registro bx). nbytesl = Número de bytes a Leer (ent) (1 palabra) (variable, registro cx, valor inrnediato). area = Area de lectura (sal) (variable). nbytes2 : Núnero de bytes l-eídos (saf) (1- palabra) (variabfe). Si es cero, se ha tratado de l-eer a partir del- fin de fichero. error = Número de] error (sa1) (1 palabra) (variable) Si no hay error, error = 0. Los errores posibl-es son 5 Y 6. ; ---------- fimleer macro handlernbytesl,area,nbytes2,erÍor local bien, fin ; salvar regj-stros afectados pusn ax push bx push cx push dx i recoger parámétros de entrada nov bx,handle ; bx = identificador fichero mov cxrnbytesl ; cx = nro. de bytes a leer 1ea dx,area ; ds:dx apunta a área de lectura ; leer registro de1 fichero ; función: leer registro r l-famar al DOS i ax = nro. de bytes leídos mov ah,3fh int 21h : i í i si no Frror. cf = 0 cf = L Y ax = códigto de1 error si error, jnc bien ; si cf = o, bifurcar ; error, poner parámetro de salida -imn arrñr f i n av . t ¡Ádian vvv4Yv dpl qv¡ éfl.of v ; i no error, poner parámetro de salida bien: nro. de bytes leidos mov nbytes2rax "; error = 0 mov errorro i restaurar registros afectados 561 fin: pop dx pop cx pop bx pop ax endm 562 FIMPUNT.ASM ; ; MacTo: FIMPUNT. ; Descripción: . Mñ\'ér nrlnfér^ dé Iéctr1r^/eqeritrrra al- final deI fichero. I ; .Parámetros: ; handle = Identificador fichero (fil-e handle) (ent) (1 palabra) (variabl-e, reqistro bx). ; : Número de] error (sal) (L pa1abra) (vari.able). ; error si no hay error, error = 0. ; Los errores posibles son el 1 y e} 6. i l t f i:mpunt rnacro handle, error locaJ- bien, fin i salvar registros afectados push ax push bx push cx push dx ; recoger parámetro de entrada mov bx,handle i bx = identificador ; despl-azamiento puntero mov cx,o mov dx,0 mov aI,2 fichero icx,dx=0(desplazaniento) ; indica mover puntero aI flnal del fichero ; rnás despfazanj-ento ñrrh+ór^ í . t i rnov ahr42h int 21h ^i *^ ^--^- ^r ; funcj-ón: mover puntero ; lfamar a1 Dos = o si error, cf = L y ax = código del error jnc bien t si cf = o, bifurcar i error, poner parámetro de salida lnov error,ax t código def error jmp fin nnnor n:¡¿¡etro de safida i bien: mov errorfo ; error = 0 i i restaurar registros afectados fin: pop dx pop cx 563 pop bx pop ax endm 564 FIPLISTA.ASM i P.ogr.^., FIPLISTA. ; Descripción: ; Listado de un fichero por pantalla. ; Ejernplo de utilización del identificador de fichero (file handle). i Parámetros: ; fichero = Nombre del fichero a listar. Puede incluir opcionalmente 1a unidad y eI sendero. t ; Simbolos: nb equ 2000 nf equ 40 ; l-ongitud del área de entrada ; nro. máxino de cars. del- nombre del- fichero ; (incluyendo opcionalmente unidad y sendero) cr equ 13 ; retorno de carro 1f equ 10 t alimentación de l-Ínea nret equ offset p1 - offset retorno ; argurnento de ret ; Procedimientos externos: extrn fisparan:far extrn fÍserror: far extrn pastexto: far t Macros: if1 include firnabrir. as¡n include fimleer.asm include fimcerr.asm endlr i ; ---------- pila segment para stack 'pilar db pila ; ends 3-2a dup ( rpilar ) ---------- datos segment para db nb dup (r ') ; área de fectura db '$' ; deli¡nitador . ñrihérñ rlé hvféq nbytesl d\,, nb ^ Leef nbytes2 dr¿¡ ? i númeró de bytes leÍdos hand]e d\^¡ ? ;. file handle hrihór^ .la l árr^r /ó nñ h^\t érrñr\ error dr"¡ ? fichero db nf dup(t ') i cadena asciiz nombre fichero mensa db 'I{ay que especifi-car un nonbre de fichero$r area datos ends t ¡n^ian finl <ódñó¡f icl-^ hrñ. f^r assume cs : codiqo , ds : datos , ss : pifa i poner en l-a pila ta dirección de retorno al DOS push ds sub axrax 565 push ax ; direccionar segmento de datos con ds mov ax,datos mov dsrax ; --; obtención de1 nombre del- fichero en forma de cadena asciiz push ds l-ea ax, fichero push ax ; nornbre de1 fichero call fispararn i ver si se especifj-có un nombre de fichero crnp fichero,O ; ¿cadena asciiz nufa? jne abrir ; no ... bj_furcar t escribir rnensaje push ds Iea ax,mensa cal_1, pastexto jnp fin i abrlr fichero abrir: finabrir fichero,O,handle,errol cmp error,O push ax ino sseellor ; abrir el- fichero ; ¿error? ; si, bifurcar ; feer del- fichero feer: fimleer handle, nbytesl- , area , nbytesz , error cmp error,o t ¿error? jne escerror ; si, bifurcar mov axrnbytes2 i ax = número de bytes leidos cmp ax,o ; ¿fin de fichero? je cerrar ; si ... bifurcar i ver si er úLtimo carácter leÍdo es ctrr-z = 1Ah (fin de fichero) mov si'nbytes2 t si = nro. de bytes leídos cnp area[si-1],1Ah i ¿carácter fin de fichero 1eído? jne esc dec si ;si=si-t ; escrj.bir por pantaLLa n bytes leidos def área d.e lectura esc: mov areaIsi],tg' push ds l-ea ax, area push ax call pastexto jnp l-eer 566 i insertar defirnitador ; ; escribir mensaje de error h,rch .lq l-ea ax, error push ax caII fi-serror ; ; cerrar eI fj,chero fimcerr handle'error ; ¿e'rYor? clnp error,O jne escerror ; si, bifurcar ; volver aI DOS fin: rél t fiplista endp i¡n evv¡Yv ^aÁ and< end fiPlista 567 FIPREGS.ASM i ; Programa: FIPREGS. ; Descripción: i crea una serie de registros iguates en un fichero nuevo o ; añade esos mismos registros a un fichero ya existente. ; Parámetros: ; fi-chero : Nombre del_ fichero. , Puede incluj.r opcionalmente l-a unidad y eI sendero. ; SinboLos: nregs équ 5 , nro. de registros a grabar nf équ 40 i nro. máximo de cars. del- nombre del fichero t (incluyendo opcionalmente unidad y sendero) cr equ 1-3 ; retorno de carro ]f equ l-0 ; alinentación de lÍnea nrét equ offset pL - offset retorno ; argumento de ret ; Procedimientos externos: extrn fispara¡n: far extrn fiserror: far extrn pastexto:far ; Macros: if1 include fimabrir.asrn include fimcrea.asn include fingrab.asrn include fincerr.as¡n include f irnpunt. asrn endif i pila ni l ¡ i datos segrnent para stack 'pilat db 6h.lc I2A dup ('pi1a') segment para fichero db nf dup(r ') registro db rregistrot ,cr,If nbytesl dw $ - registro nbytes2 dw ? handle error dw ? d\^¡ o datos ends nensa ; cadena asciiz nombre fichero t registro a crear i número de bytes a grabar ¡ número de bytes grabados file handLe nro. de1 error db rHay que especificar un nornbre de fichero$t ---------- codi,go segment fipregs proc far assume cs : codígo, ds : datos , ss : pila ; ponér en 1a pila l-a dirección de retorno aL DOS Push ds 568 sub ax,ax Push ax t direccionar segmento de datos con ds mov axrdatos mov ds,ax ; obtención del nornbre del fichero en forrna de cadena asciiz push ds ; nombre del fichero l-ea ax, fichero push ax cal I fi snaram ; ver si se especj-ficó un nombre de fichero cmp ficheroro ; ¿cadena asciiz nula? jne abrir ; no ... bifurcar ; escribir rnensaje push ds 'lpa push ^Y ax méhsa caJ-J- pasEexr.o j¡np f in ; abrir fichero con acceso 1 (grabar) abri-r: finabrir fichero,l",handle,error ; abrir el fichero cmp érror,0 t ¿existe el- fichero? jne crear i no .. ' crearl-o ; posicionar puntero a1 final del fichero fimpunt handfe,error crnp error,0 ; ¿error? je regs i no ... bifurcar ; escribir rnensaje de error escerror: push ds lea axrerror push ax call fiserror jnp fin ; crear e1 fichero con atributo o (l-ectura/escrj-tura) crear: f imcrea f ichero, 0, handle, error ; ¿error? cmp error,o ine escerrór t si ... bifurcar i ; crear registros regs: 569 bucle: mov CX,nregS ; Cx = nro. de regs. a crear push cx fimgrab handfe , nbytesl , registro, nbytes2 , error pop cx cmp errorr0 t ¿error? jne escerror ; si ... bifurcar loop buclé ; cerrar el- fichero cerrar : fimcerr handle,error cmp error,o ; ¿error? je fin ; no ... bifurcar jnp escerror i volver aI DOS fin: ; fipregs codigo 570 endp ends énd f i nrac¡g FIPSEC.ASM i Prograrna: FIPSEC. ; Descripción: ; Listado fichero secuencial mediante FcB. ; simbol-os: cr equ 13 lf equ 1,0 ; retorno de carro ; alimentación de lÍnea ; Macros: if1 incfude pamesct.asn incfude pamescc.asm en(ll r i ; ---------- pila pila : segment stack db ends I2a dup ( 'pi.]a' ) ---------- datos segrnent ; estructura FCB fcbs struc unidad db ? ; unidad (I - 4, que correspondé con A a D) nombre db I dup(?) i nombre prirnario extens db 3 dup(?) ; extensión nrobl,o dw ? ; nro. del bl-oque Iongreg dw ? ¡ longitud del registro l-ongfic dr¡¡ 2 dup(?) r longitud del f ichero fecha d\"¡ ? , fecha de fa úItirna actualización db 10 dup(?) i reservado para ef DOS nroreg d\^¡ ? ¡ nro. del registro nroregr dI^¡ 2 dup(?) i nro. del registro relativo fcbs ends fcb fcbs <> ; bloque de control de fichero (FcB) dta db ? ¡ área de transferencia de datos (DTA) i db 0 t desplazamiento de1 carácter en eI registro mensae db | *** err6r de acceso aI ficher6 *** | , Cr, If, t $ t datos ; ends ---------- codigo fipsec segrnent proc far assume cs: codigo, ds:datos, es: datos, ss:pila i poner dirección de retorno al DOS en ta pil-a push ds sub ax,ax push ax i direccionar segrnento de datos con es mov ax,datos 571 mover parámetro (en formato FCB) del PSP a fcb mov si,5ch mov di,offset mov cxrl-2 cld rep movsb ; si = desplazarniento def nombre del ,' fichero en eI PsP (en formato FcB) fcb ; lonqj.tud a mover ; dirección hacia adelante ; mover parámetro a fcb ; direccionar segnento de datos con ds ¡nov ax, qaEos mov ds,ax ; establecer DTA mov dx,offset dta mov ahrl-ah t función: poner DTA int 21h ; l-l-amar al DOS ; abrir el fichero mov dx,offset fcb ¡nov ahr 0fh ; función: abrir fichero int 2I}1 ; llamar al DoS cmp a1,0 i ¿error? ; bifurcar si error )nz error inicializar los campos del- FcB: tamaño del registro, nro. de1 bloque y nro. del registro mov fcb. ]ongregr l i tamaño del registro ¡nov f cb. nrob]o, 0 t. bl-oque = o rÁdicl-r^ mov fcb. nroreg,0 = n ; leer carácter de1 fichero mov dx,offset fcb mov ah,l-4h i función: leer secuencialnente de1 fichero int 21h ; flamar a1 DoS .l n i ¿erroY? jnz error ; bifurcar si error ; a1 = carácter feÍdo mov al,dta i chequear eI tipo de carácter Ieído cmp al,1ah ia fin cmp al,09h 'ia +al.rtl pamescc a1 i-nc i al If jne car mov i,0 jmp car i . t :fin cLL" rle fichpro r se encontró carácter de tabulación 572 = CEfl--Z? r si- ... bifurcar . :6e t^l-\r11 ^dór" ; si ... bifurcar carácter ; escribir ; i = i + 1 (posición de1 carácter en ef reg.) ; ¿es carácter de alinentación de línea? i no ... bifurcar ,' restaurar desplazamiento en eI reqj-stro ; expandir con blancos hasta l"a posj-ción siguiente nú1tipl-o de I t (tab stop) tabul: panescc I | ; escribj.rcarácter inc i ; i: i + 1 (posición del- carácter en el reg') test i¿'7 ; ¿es tab stop? je car ; si ... bifurcar jmp tabul ; continuar expandiendo tabul-ador jmp car i bifurcar a l-eer eI siguiente carácter ; error al- acceder aI disco pamesct mensae ; escribir jnp salir mensaje de error ; fin de fichero fin: rnov dxroffset fcb mov ahrl-Oh i función: cerrar fichero int 21h ; llamar aI DOS sal- i-r: ret ; voJ-ver al DOS f i nqa¡ i i ^^u vvu ^^l rY óh.lñ end fipsec 573 FISERROR.ASM ; Subrutina: FISERROR. ; Descripción: ; Escribe mensaje de error asociado a un número de error en acceso i a ficheros. ,' E1 rango de errores es de n1 a n2 (ver símbol-os). ,' Parámetros: params struc dw ? ; bp salvado por La subrutina retorno dd ? ; dirección de retorno pldd ? ; dirección parárnetro 1 (ent) (1 palabra) número del error params ends ; simbofos3 n1 equ 1 i nro. de error inicialn2 equ l-8 i nro. de error finaL cr equ l-3 i retorno de carro 1f equ 10 ; al-imentación de Iínea nret equ offset p1 - offset retorno ; argumento de ret i Procedimientos externoss extrn pastexto: far ; ---------- codigo segment para assume cs:codigo pubLic fiserror fiserror proc far push bp mov bP,sP i salvar bp ; bp = "n i --- i sa]var registros afectados push es push bx push si ; recoger parámetro de entrada l-es si, [bp].p1 i es = segmento, si : despl-azamiento mov bx,es: [si] i bx = número del error ; el- número deL error debe estar entre 1os lÍrnites definidos cmp bxrnl j1 fin cmp bx,n2 tg fin i cal-cular desplazamiento sobre tabla de direcciones de rnensajes ibx=bx-1 t doblar desplazamiento sobre tabla ; escribir rnensaje de error dec bx add bx,bx 574 push push cs 3 dirnen Ibx] cafl pastexto i restaurar registros afectados fin ¡ pop si pop bx pop es fi cérr^r mov sp,bp pop bp ret nret ;sp=bp i restaurar bp óñ^ñ i i ---------- i mensajes de error mensal db t*** Error en eI nú¡nero de 1a función,,cr,lf,,$' mensa2 db '*** Fichero no existe',cr,If, '$t mensa3 db ¡*** Sendero no exister,cr,If, r$r mensa4 db | *** Demasiados ficheros abi-ertos' , cr, L f, ' $ ' mensas db t*** Acceso denegador,cr,lf, t$t mensa6 db t*** Error en identificador fichero (fi1e handle)r,cr,lf,'$' mensaT db t*** Destruidos los bloques de control de rnemoriar,cr,lf,r$l mensaS db t *** Memoria insufici-entet ,ct,1f, t $ t mensag db r*** Error en la dirección del bloque de menori-ar,cr,ff,'$, mensalo db t*** Error en el- entorno (environment) r,crrff,'$' mensa1l db r*** Error en el formator rcrrlf, r$l mensal-2 db '*** Error en eI código de accesor rcrrlf, r$l mensal-3 db t*** Datos erróneost,cr,ff,,$, mensaL4 db t*** Mensaje no utilizadot ,cr, ff,,$t mensal-s db t*** Uni-dad especificada errónear,cr,If, r$l r$l mensa16 db '*** Intento de borrar eI actuaf directoriotrcrrlf, mensal,T db t*** No es eL misno dispositivo',cr,l-f,t$' ¡nensa18 db t *** No más ficheros t , cr, 1f, | $ | ; direcciones de mensa'ies de error dirrnen t dw mensal dh¡ mensa2 dr"¡ mensa3 dr¡t mensa4 dw mensa5 dw mensa6 dvr mensaT dw mensa8 dv¡ mensa9 dw mensal0 d\^¡ mensaLldr¡r tnensal2 dw mensal-3 dw mensal-4 dw nensals dr^¡ mensal-6 dl¡t mensal,T dw mensa18 ---------- 575 i codigo ends end 576 FISPARAM.ASM Subrutina: FISPARAM. Descripción: obtener e1 nombre de un fichero del- Prefijo de Segnento de Programa (PSP) en forma de cadena asciiz. cadena asciiz quiere decir que incorpora un byte 00h al fj-na1. EI registro ES debe apuntar aI PSP. Ignora blancos inj-cial-es e intermedj-os en el nonbre del- fichero, Parámetros: params scruc dw ? ; bp salvado por Ia subrutina retorno dd ? ; dirección de retorno p1 dd ? ; dirección parámetro L (sal) r cadena asciiz con eI nonbre de1 fichero params ends i i SÍrnbolos nret equ offset p1 - offset retorno ; argumento de ret 3 codigo segment assume cs:codigo public fj-sparam fispararn proc far push bp i salvar bp ;bP=.n rlov bp, sp ; --,' salvar regj-stros afectados push ds pusfr es push ax push bx push cx push si push di ; operaciones iniciales mov si,80h mov bxro 1ds di, tbpl.pl ; si apunta aI área de paránetros ; es apunta aI PsP i bx : desplazarniento en cadena de salida i ds : segmento, di = despLazamiento (parámetro de salida) ; mov chr 0 mov cl,es:[si] crnp cx,o je f in ; cx: Iongitud parámetro i ¿cero? ,' si, bifurcar i bucle caracteres de entrada bucl-e: mov ah,es: Isi] | | ^h je cont ; es: [si] apunta aL carácter de entrada ; ah = carácter de entrada ; ¿es blanco? ; si ... bifurcar 577 i rnover carácter a cadena de sal-ida mov ds: [bx] [di],ah i mover carácter inc bx conE: loop bucle ; añadir byte de ceros binarios a1 final fin mov byte ptr ds: [bx] Idil ,0 i restaurar registros afectados pop di pop si pop cx pop bx pop ax pop es pop ds 3 mov sprbp pop bp ret nret fisparam endp ¡nA i an éñÁe end 578 ; sp = bp ; restaurar bp Comunicaciones sefle El adaptador de comunicaciones serie proporciona al PC la posibilidad de comunicación con otros ordenadores o dispositivos que utilicen el interfaz de comunicaciones RS-232. Los dos tipos de comunicaciones Existen dos tipos de comunicaciones: la serie y la paralelo. En la comunicación paralelo se transmiten simultáneamente todos los bits de un byte. Existen ocho líneas para los datos (una línea por cada bit) y al menos dos líneas de control; es decir, el número mínimo de hilos es de diez. La velocidad de transmisión es relativamente alta y se utiliza en distancias cortas. Interfoz paralelo D|uDsDD¡DDrD lJ,l..t üü J,t C,Q { * D : bit de datos C:bitdecontrol En la comunicación serie, los bits de datos y de control se transmiten de uno en uno. La velocidad de transmisión es menor que en el caso paralelo. Se utiliza normalmente para comunicación a gran distancia. 579 Interfoz serie C' DDoDDDDD'Doq + D: bit de datos C : bit de control El sistema serie es mucho más económico, pues necesita un solo hilo por el que circulan los bits de datos y de control. Además, es posible utilizar el cable telefónico para la comunicación entre dos sistemas distantes (con la inclusión de un modem a cada extremo de la línea para realizar la conversión analógico/digital). El protocolo serie asíncrono En el protocolo serie, los bits circulan por una sola línea. En el esquema siguiente, la anchura de cada bit depende de la velocidad de transmisión (bits,/segundo o baudios): bits finales b bits de datos b ii t de paridad t de comienzo * valor l - valor 0 Cuando no se están transmitiendo datos sobre la línea, el estado de la línea es l. Al transmitir un carácter,lo primero que se envía es un bit de comienzo (start bit) con valor 0, para indicar que a continuación se van a transmitir los bits del carácter. El primer bit que se transmite es el menos significativo. Tras los bits del carácter (que pueden ser 5, 6, 7 u 8), puede existir un bit de paridad, que sirve para detectar posibles errores de transmisión. Y tras este bit opcional están los bits finales (stop bits), que pueden ser 1.5 ó 2. Estos bits representan la cantidad mínima de tiempo que la línea debe estar en estado I antes de que pueda aparecer otro bit de comienzo. Puesto que los caracteres de datos pueden aparecer en cualquier momento, se dice que el protocolo es de tipo asíncrono. El receptor sólo se sincroniza con el emisor cuando se recibe un bit de comienzo de un carácter. l, La velocidad en ambos extremos debe ser la misma, así como el tipo de paridad y el número de bits finales. EI UART Existe en el PC un microprocesador dedicado a realizar la conversión a protocolo serie: el Universal Asynchronous Receiver Transmitter (UART), llamado elemento de comunicaciones 8250. 580 Antes de usar el UART hay que indicarle los parámetros de la comunicación serie, que son: o La velocidad, en baudios o bits por segundo (de 110 a 9600). o El número de bits por carácter (de 5 a 8). o El tipo de paridad (par, impar o ninguna). o El número de bits finales (stop bits). El esquema'de funcionamiento del UART es el siguiente: parámetros ->THR-> TSR- dato a transmitir dato recibido estado Ordenador <- -RDR<_ RSR<_ Línea de UART comunicaciones Desde el ordenador al UART se le pueden transmitir los parámetros de la comunicación o un carácter. El ordenador puede recibir un carácter o el estado. El UART dispone de cuatro registros internos, que son: o THR (Transmitter Holding Register), registro temporal de salida. o TSR (Tronsmitter Sending Register), registro de salida. o RDR (Receiver Data Register), registro de entrada. e RSR (Receiver Shtft Register), registro temporal de entrada. Todo carácter que se transmite se almacena en el THR. Antes de transmitirlo hay que comprobar antes que este registro está vacío. El UART añade los bits apropiados de comienzo y final, lo guarda en el TSR y a continuación lo envía a la línea de comunicaciones. Todo carácter que se recibe de la línea de comunicaciones se almacena (junto con los bits de control) en el RSR. Tras chequear los errores, el carácter se sitúa sobre el RDR, de donde es recogido por el ordenador. Los errores Existen los errores posibles siguientes: o Sobrecarga. Ocurre cuando el UART trata de poner un carácter en el RDR antes de que el ordenador haya recogido el carácter anterior. 581 Paridad. El número de bits (par o impar) es incorrecto. Puede ser debido al ruido de la línea. Formato. Ocurre cuando el UART no recibe el,/los bits finales en el momento en que debería recibirlos. Puede ser debido a que la inicialización no corresponde con la transmisión o a ruido en la línea. Interrupción. Algunos protocolos serie asíncronos permiten una condición especial en la transmisión, que se llama condición de interrupción. Para enviarla, la línea debe mantenerse en estado 0 durante al menos el tiempo de transmisión de un carácter. El modem El interfaz RS-232 realiza la conexión física del UART con el mundo exterior. Dos interfaces RS-232 se pueden conectar directamente, pero a distancias cortas. Para distancias largas es necesario un modem en cada extremo de la línea. Los modems realizan la conversión analógico/digital y normalmente son full-duplex (es decir, pueden recibir y retransmitir datos al mismo tiempo). distancia o líneatelefónica Señales de control del modem o Desde el ordenador al modem: Señal Signfficado DTR (Doto Terminal Ready) El ordenador le dice al modem que el ordenador está encendido y preparado. El ordenador le dice al modem que quiere RTS (Request To Send) enviar datos. ¡ Desde el modem al ordenador: 82 Significado Señal DSR (Data Set Reody) CTS (Clear To Send) Modem encendido y preparado. DCD (Dota Carier Detect) El modem ha establecido la comunicación con el modem del otro extremo de la línea Modem preparado para transmisión de datos. telefónica. El teléfono conectado al modem está so- RI (Ring Indicator) nando. E¡ interfaz físico RS-232 Se trata de un conector macho de 25 agujas. La función de cada agu- ja es: Número de aguja Dirección Función 2 salida datos transmitidos J entrada datos recibidos 4 salida 5 entrada entrada RTS CTS DSR 6 7 8 entrada 20 22 salida entrada tierra DCD DTR RI En el caso de que se conecte directamente un PC a otro PC (sin modems intermedios o con modem nulo), el esquema sería el siguiente: ordenqdor I ordenador 2 )1 ;Ti 44 s-)Cs 6 ./_6 20____-x-20 7_7 Si no se utilizan las señales de control del modem (agujas 4, 5, 6 y 20\, Ias únicas agujas a conectar son las 2, 3 y 7. 583 Interrupciones asociadas a la comunicación serie' Número Tipo Descripción l4h 2lh BIOS DOS Funciones varias, según el valor de AH. Funciones varias, según el valor de AH. FUNCIONES BIOS ASOCTADAS A LA INTERRUPüON 14h El BIOS nos proporciona un acceso cómodo al puerto de comunica- ciones asíncronas RS-232, sin preocuparnos del detalle del hardware. Detodas maneras, algunas características del UART no se pueden utilizar nada más que a través de una programación directa (a través de instrucciones [N y oUT). Existen cuatro funciones, que corresponden a los valores de 0 a 3 de AH: AH 0 Función Inicializar la puerta serie de comunicaciones. Entrada: DX: Número del puerto serie (0 ó l). AL : Parámetros de inicialización: Bits 7-5 4-3 2 1-0 Contenido Velocidad (baudios): 000: 110,001: 150,010: 300,011= 600 100: 1200, l0l:2400, ll0:4800, lll = 9600 Paridad: x0: ninguna, 0l : impar, ll : par Número de bits finales (stop bits) 0: I bit I : 1.5 bits si longitud carácter es 5. I :2 bits si longitud carácter es 6, 7 u 8 Longitud de cada carácter: 00: 5 bits, 0l :6 bits, l0:7 bits, 11 :8 bits Salida: AX : Estado (como en AH : 3). I 584 Enviar carácter sobre la línea. Activa las señales DTR y RTS del modem y no transmite un carácter hasta que no reciba las señales correctas para DSR y CTS. El carácter se enviará a la UART cuando esté vacío el THR. Entrada: DX : Número del puerto serie (0 ó l). , AL:Carácteraenviar. Salida: AH = Estado de la línea excepto: bit 7 : I si carácter no transmitido. 2 Leer carácter de la linea. Activa la señal DTR y no mirará si ha recibido un carácter hasta que no reciba la señal correcta de DSR. Entrada: DX = Número del puerto serie (0 ó 1). i Salida: AL : Carácter leído. AH : Estado de la línea excepto: bits 5 y 6:0. Si AH no es cero es que ha ocurrido un error. 3 Leer la palabra de estado del puerto de comunicaciones. Entrada: DX : Número del puerto serie (0 ó l). Sarida: *1f i f;;?# l!?f:;XZZde Bits de AH comunicaciones Contenido Tiempo excedido. TSR vacío. THR vacío. Interrupción (break). Error de formato (framing). Error de paridad. Error de sobrecarga (overrun). Dato preparado. Bits de AL Contenido DCD (data carrier detect). Rl (rins indicator). DSR (data set ready). CTS (clesr to send). Delta DCD (data carrier detect). Delta RI (ring indicator). Delta DSR (dota set ready). Delta CTS (clear to send). Nota: Delta indica la variación de estado de la señal. 585 FUNCIONES DOS CORRESPONDIENTES A LA INTERRUPCION 21h El Dos inicializa el puerto de comunicaciones serie con: 2400 baudios. sin paridad, un bit final y 8 bits/carácter. AH Función 03h Esperar para leer un carácter de entrada. Salida: AL : carácter leído. 04h Enviar un carácter al dispositivo asíncrono. Entrada: DL: carácter a enviar. 586 El son¡do y la música La producción de sonido sobre el IBM PC se realiza mediante el altavoz interno, al que se le hace vibrar a través de impulsos eléctricos enviados desde el ordenador. Un ciclo de sonido es el generado cuando al altavoz le llega un voltaje mínimo (señal :0), luego le llega uno máximo (señal : l) Y a continuación otro mínimo (señal :0): : Vmáx. 0: Vmín. 1 +-+ ciclo de sonido Un ciclo de sonido se oye como un "clic". Cuando se envían al altavoz un cierto número de ciclos de sonido seguidos, se genera un sonido continuo. La frecuencia de este sonido continuo es el número de ciclos de sonido por segundo o hercios. Puesto que el altavoz y su amplificador no pueden responder a las discontinuidades de la onda cuadrada, la onda resultante será de tipo sinusoidal. Los rangos de frecuencias que hay que considerar son: Espectro audible: 20 a 20.000 hercios. Espectro voz humana: 125 a 1.000 hercios. 18.2 a 1.193.182 hercios. Altavoz IBM PC: w7 El altavoz del IBM PC viene sin control de volumen. Diferentes fre- cuencias pueden producir diferentes volúmenes de sonido. Esta fluctuación (normal en todos los altavoces) no puede controlarse, pues es una conse- cuencia del diseño del altavoz. Funcionam¡ento del altavoz El altavoz está gobernado por el chip PPI (8255 Programmable peripheral Interface). A través del b¡e del puerto B del PPI (puerto 97), al altavoz le llegan dos señales (véase figura). o Bit 0: Señal (0 ó l) indirecta a través del puerto 2 del temporizador (8253 timer'¡. Si la señal es 0, el temporizador no actúa sobre el altavoz. Si la señal es l, el temporizador maneja al altavoz. . Bit l: Señal (0 ó 1) direcra. Si la señal es 0, el altavoz permanece inactivo. Si la señal es l, el altavoz permanece activo. Como consecuencia de este esquema de funcionamiento existen dos métodos para controlar la producción de sonido a través del altavoz: ¡ Indirectamente (a través del temporizador). o Directamente. El sistema que se utiliza normalmente es el primero, por ser el más sencillo, como veremos. En aplicaciones más complejas, podría usarse un método híbrido. 765432t0 byte puerto B del PPI frecuencia del reloj L. Temporizador (puerto 97) activar/desact i var altav oz 588 al microprocesador (interrupción tipo 8) ->Altavoz Método 1= Gontrol del altavoz mediante el temporizador Se utiliza el temporizador (8253 timer) de la placa base para generar un sonido de una cierta frecuencia. Los bits 0 y I del puerto B del PPI deben ponerse ambos igual a uno. Los otros bits no deben alterarse' El temporizador es como el corazón del reloj del sistema. Su función primaria ei medir el tiempo de forma similar a como lo hace un metrónomo para un músico. Funciona de la siguiente manera: El reloj del sistema (8284A) oscila a una frecuencia de 1.193.180 ciclos por segundo (aproximadamente 1.193 MHzs.). El temporizador genera una interrupción de reloj (interrupción tipo 8) una vez cada 65.536 ciclos del reloj, es decir, 1. 193. 180/ 65.536 : 18,2 veces por segundo, aproximadamente. Esta interrupción del reloj se llama un "tic". El BIOS lleva la cuenta de los tics del reloj para calcular la hora del día y emite su propia interrupción (interrupción 28), que se llama interrupción de tic del reloj' Para producir sonido de una cierta frecuencia durante un tiempo determinado son necesarios los pasos siguientes: 1. Convertir la frecuencia deseada al período del temporizador. se utiliza la fórmula: período = 1.193.180/frecuencia. El rango de frecuencias que puede generarse es: o Frecuencia máxima : 1.193.180/1 : 1,193 MHz. o Frecuencia mínima : 1.193.180/65.536:18,2 Hz. (aproximadamente). 2. Preparar al temporizador para recibir el período. Estó se hace enviando el valor 182 al puerto 67 del temporizador. 3. Cargar el período en el temporizador. Esto se hace escribiendo el período sobre el puerto 66 del temporizador. Al recibir el período, el temporizador cuenta los ciclos del reloj hasta que se igualan al período. Entonces genera una señal (en lugar de una interrupción) y comienza otra vez a contar desde cero. 4. Activar temporizador y altavoz, es decir, comienza a producirse el sonido de la frecuencia deseada. Esto se realiza leyendo el byte del puerto B del PPI (puerto 97), poniendo los bits 0 y I con el valor I y volviéndolo a escribir sobre el mismo puerto. 5. lJnavezgenerado el sonido, es necesario controlar la duración. Esto se hace mediante un ciclo de retardo (instrucción LOOP)' que se programa teniendo en cuenta los ciclos consumidos. 589 6. Por último, hay que desactivar el temporizador y el altavoz. Se hace poniendo los bits 0 y I del puerto B del ppl con el valor cero. Para calcular el contador N de las instrucciones: MOV CX,N DEMORA: LOOP DEMORA que provoque una demora de 1 milisegundo, se hace el cálculo siguiente: Si la frecuencia del reloj es V KHzs. (4770 para el 8088), entonces: lciclo de reloj : lll0,I seg. - UI miliseg. El número de ciclos que consume la instrucción Loop es (véase apéndice D): o 17 ciclos de reloj, bifurca. o 5 ciclos de reloj, sisi no bifurca. Por tanto, el número de ciclos consumidos por el bucle es 17 .N + 5. Por no ser demasiado significativo, despreciamos el valor 5. Entonces, el tiempo consumido por el bucle es: 17.N , : _oi-:- milisegs. Y puesto que este valor debe ser l, N : +. l7 La subrutina soSSoNMl es el resultado de la implementación de este sistema. Este sistema es el más utilizado por las siguientes razones: o La duración de un ciclo de sonido es controlada por el temporizador, en lugar de nuestro programa, con lo cual la CpU queda libre para otra tarea. ¡ El ritmo de funcionamiento del temporizador no depende de la verocidad de proceso de la CPU, lo cual hace que el sistema sea independiente del modelo de microprocesador. Métod o 2: Control d¡recto del altavoz Consiste en activar (señal l) y desactivar (señal 0) el altavoz alternativamente para producir ciclos de sonido. Esto se hace mediante el bit I de esta590 do del puerto B del PPI para generar la onda cuadrada, alternando el va- lor de este bit. La duración asociada a cada señal (0 ó 1) se controla mediante un bucle de demora. Mediante este sistema Se puede controlar la duración de un ciclo de sonido (t,) y la distancia (tr) entre dos ciclos sucesivos: <- t1 t2 La frecuencia del sonido generado es f : l/t2hercios. Con este sistema se pueden producir diferentes tipos de sonido de una misma frecuencia, variando el tiempo tr en que está activo el altavoz. Vamos a ver, como ejemplo, cómo se calcula el número de veces que hay que ejecutar un ciclo de demora para obtener una frecuencia y una duración determinadas, suponiendo que tz:2'tt, es decir, que las duraciones de las señales 0 y 1 sean idénticas. Las instrucciones a ejecutar para un ciclo de señal 0 ó de señal I son: MOV CX.N DEMORA: LOOP DEMORA Se trata de calcular N. Si la frecuencia del reloj es V KHzs. (4770 para el 8088): I ciclo de reloj : ¡,.-f: sees. El número de ciclos consumidos por el bucle es 17 ' N + 5. Despreciando el valor 5, el tiempo consumido por el bucle es: tr : l7.N ¡,. a;- seBS. La frecuencia de la onda será: r:*:t#:i#k:+lF Y puesto que queremos calcular N a partir de la frecuencia, 591 Y el tiempo consumido, tr, de un ciclo completo es: ,, : + SegS. : l+L mifisegs. Si queremos que el sonido dure T milisegs., entonces el número de veces que hay que ejecutar el ciclo completo es: M:I:-'j' "'- t. - lomPara producir sonido de una cierta frecuencia durante un tiempo determinado son necesarios los pasos siguientes: l. Desactivar las interrupciones. 2. Desactivar el temporizador. Esto se realiza leyendo el byte del puerto B del ppl (puert* 97), poniendo el bit 0 con el valor 0 y volviéndolo a escribir iobre el mismo puerto. 3. Para cada ciclo completo de sonido: 3.1. Activar altavoz (señal : l). Esto se realiza leyendo el byte del puerto B del ppl (puerto 97), poniendo el bit I con el valor I y volviéndolo a escribir sobre el mismo puerto. 3.2. Una vez generada la señal l, se mantiene mediante un bucle de retardo (instrucción LOOP). 3.3. Desactivar altavoz (señal :0). Esto se realiza leyendo el byte del puerto B del ppl (puerto97), poniendo el bit I con el valor 0 y volviéndolo a escribir sobre el mismo puerto. 3.4. Unavez generada la señal 0, se mantiene mediante un bucle de retardo (instrucción LOOP). La subrutina SoSSONM2 es el resultado de la implementación de este sistema. El aspecto positivo, pues, de este sistema es su completa flexibilidad para producir diferentes efectos de sonido. Es posible incluso generar señales asimétricas, usando diferentes demoras en los dos bucles. Pero las desventajas son: o El programa requiere la dedicación constante de la cpu. Incluso deben desactivarse las interrupciones, pues las interrupciones del reloj afectan a la suavidad del sonido. o La frecuencia generada depende de la velocidad del microprocesador. 592 Es decir, el mismo programa produciría mayor frecuencia cuanto más rápido fuera la CPU. o La programación es tediosa. Música Ahora que ya tenemos un procedimiento general para producir so- nido, es posible generar las notas musicales, al existir una relación entre frecuencias y notas. Esta relación es la siguiente para la octavaT:. Frecuencia Nota 2093 doi = c7 do#1 = c#7 re7 : d7 re#1 : d#7 mi7 : e7 fa7 - f7 fa#1 : f #7 sol7 : gj sol#1 : g#7 : al lAl la#1 : a#7 si7 : bj 221'7 2349 2489 2637 2794 2960 3 136 3322 3520 3729 3951 Para la octava 6, las frecuencias correspondientes son la mitad de las de la octava 7; las de la octava 5, la mitad de las de la octava 6, y así hasta llegar a la octava 0. Es decir, respecto a la octava 0, las frecuencias de cada octava son: Octqva Frecuencias respecto a ls octavs 0 5 128 64 32 4 l6 7 6 J 8 2 4 I 2 0 I Respecto a la duración asociada a cada nota, la terminología que se utiliza y la duración relativa a la mitad de la más corta (semifusa) es: 593 Duración Símbolo Duración relutiva a la mitad de unq semifusa redonda blanca redo r28 blan 64 negra corchea semicorchea fusa semifusa negr l6 corc semc 8 fusa 4 2 semf Para producir música, bastaría con confeccionar una lista secuencial de notas y duraciones. La subrutina general SOSMUSIC está orientada en este sentido, que tiene dos parámetros. El primero es la dirección de la lista de notas y duraciones. El segundo es la duración asociada a una redonda (en milisegundos), que nos marca la velocidad de ejecución. Para cada nota, se calcula su frecuencia y su duración, que se transmiten a la subrutina SOSSONMI para producir el sonido correspondiente a esa frecuencia y de esa duración, mediante el método I (sonido mediante el temporizador). El programa SOPMUSIC es un ejemplo de utilización de la subrutina general SOSMUSIC. La lista de notas y duraciones se especifica mediante nombres simbólicos, para facilitar al usuario la labor de codificación: . Notas: Hay que incluir la octava a la que pertenecen (de 0 a 7) tras el nombre habitual (do#5,re6,mi2, etc.) o el alternativo (c#5d6,e2, etcétera). ¡ Duraciones: Nombres simbólicos de cuatro letras. tal y como se indican en la tabla anterior. A estos símbolos hay que añadir otros especiales (el usuario puede añadir otros, si lo desea): Símbolo Descripción redo2 redonda con pun llo (duración relativa :144) blan2 negr2 corc2 semc2 fusa2 semf2 silen final blanca con pun llo (duración relativa : 72) negra con pun llo (duración relativa: 36) corchea con pun llo (duración relativa: 18) semicorchea con pun llo (duración relativa: 9) fusa con pun llo (duración relativa: 6) semifusa con pun llo (duración relativa: 3) silencio final de la lista La definición de los nombres simbólicos se hace en el módulo fuente SOMNOTAS. 594 La lista hay que incluirla dentro del segmento de datos. Para ello, es preferible aislar en fichero aparte la codificación correspondiente a cada música. La codificación de la lista de notas de Para Elisa, de Beethoven, se encuentra en el módulo SOMELISA. Aplicaciones Macros/módulos: SOMELISA - Tablas de notas de Para Elisa, de Beethoven. SOMNOTAS - Definición de los símbolos de las notas musicales. SOMRETAR - Consume una cantidad de unidades de tiempo (milisegundos) para mantener un sonido. Programas: SOPMUSIC - Prueba subrutina SOSMUSIC con el módulo SOMELISA. SOPSONMI - Prueba subrutina SOSSONMI. SOPSONM2 - Prueba subrutina SOSSONM2. SOPTECLA - Convierte el teclado en un instrumento musical. Subrutinos: SOSMUSIC - Subrutina genera para producir música por el altavoz a partir de una tabla de notas musicales. Se utiliza el método I para producir sonido (acceso al altavoz mediante el temporizador). SOSNOTA - Convierte número de nota absoluta en frecuencia. SOSSONMI - Produce un sonido de una frecuencia determinada durante un cierto número de milésimas de segundo. Utiliza el método I para producir sonido (acceso al altavoz mediante el temporizador). SOSSONM2 - Produce un sonido de una frecuencia determinada durante un cierto número de milésimas de segundo. Utiliza el método 2 para producir sonido (acceso directo al altavoz). 595 SOMELISA.ASM Módu1o: SoMELISA. nacnr i n¡ i Án . Tabla de notas de rrPara Elisarr, de Beetfloven. compas de 3 x 4. Sirnbolos: Los definidos en SoMNOTAS.ASM. db e5 Áh ó6 db b5 ^( dcq ,corc,d5 ,corc , corc tcorc ci l a¡ ^h db e4 ,corc,a5 ¡nr¡ tcorc ,c4 db b5 gsc ,negr ,silen,corc Ltr ,e4 JL qu Ah Ah ^6 6( ci I o¡ ¡nr¡ ácq , corc ,e4 Áh Áh ó6 h^ ^h db e4 ,corc ,as db b5 Áh uu LJ ^Á ,negr,silen,corc h< db a5 ^h ^F db db db db rR Ah db 596 ,corc,ds5 ,coLc ,p) AeE ^q I tteYL , ,corc , corc , corc cit^^ ,vaLu,DJ ^^F^ ,corc , corc , corc ,c4 ,e4 ,corc sil-en / corc ,negr I AR , corc e5 e5 ,neqr2,g4 ,corc ,corc ,corc d5 d5 tnegr2tf4 ,corc ,corc,e5 , corc ^R á^^va ,tLÉYL-ter c5 ^^ ^R ,corc db b5,negr,sifen,negr,e4 db e5 dh a6 db e5 ,corc,ds5 db db e5 b5 rcorc ,ds5 ,corc ,e5 ,corc ,d5 ,corc ,c5 db db db db a5 e4 b5 qs+ db c5 ,negr ,silen,corc ,c4 ,corc ,a5 ,corc ,negr ,silenrcorc 'e4 ,corc ,b5 'corc ,negr ,si1en'col.c ,e4 ,negr tsilen,negr ,e5 <i l an d<5 ¡nr¡ , negr ,corc , corc db e5 ,corc rds5 ,corc db e5 ,corc ,ds5 ,corc ,e5 d< ,corc negr , silen, corc ,c4 ,corc,a5 ,corc ,corc ^h h< db db a5 e4 áL Ltr Áh db db ^R , , ttetjL a5 f Ínal- I 4ir^h hR ^tr ^^v^ , corc , bl-an 597 SOMNOTAS.ASM Módulo: SOMNOTAS. Descripción: Definición de 1os sírnbolos de 1as notas rnusicales. Símbolos: se hace una asignación de l-os sÍrnbolos de cada nota a los números enteros sicruientes: 0a 11. octava: 0. Números: 1. Números: 2. Números: Octava: 7. Números: 84 a 95. octava: Octava 3 23. j-rpc octava,O]-234567 ; bucle octavas 0 a 7 do&octava equ l-2*octava + O dos&octava equ 12*octava + 1 re&octava equ 12*octava + 2 res&octava equ 12*octava + 3 mi&octava equ 12*octava + 4 fa&octava equ 12*octava + 5 fas&octava equ 12*octava + 6 sol&octava equ 12*octava + 7 sols&octava equ 12*octava + 8 l-a&octava equ 12*octava + 9 Las&octa¡/a equ 12*octava + 10 si&octava equ l-2*octava + l-1 c&octava cs&octava d&octava ds&octava e&octava f&octava fs&octava g&octava gs&octava a&octava as&octava b&octava equ l-2*octava + 0 equ l-2*octava + 1 equ L2*ocicava + 2 1?*^^f^\r^ + ? 1r*^^+rrr¡ + 11 equ 12*octava + 4 equ L2*octava + 5 equ L2*octava + 6 equ 12*octava + 7 equ 12*octava + I 1 2*^^+^tr^ + q equ 12*octava + 10 eYe vYs ,' fin bucle duración de cada nota respecto a Ia rnitad de una sernifusa endm equ Lza ; redonda equ 64 ; blanca equ 32 negr ; negra . equ 16 ^^r^hó^ 8 s cor equ ; semicorchea 4 equ ; fusa équ 2 ; senifusa notas con puntillo (duración: 1.5 veces) redo blan redo2 bfan2 negr2 corc2 scor2 fus12 598 equ 1-92 equ 96 equ 48 equ 24 equ 12 6 equ 3 equ í otros sÍrnbolos silen final- equ 254 equ 255 ; indica sifencio ; indica final de fa tabla de nocas 599 SOMRETAR.ASM ; Macro: . i i SOMRETAR. nóc^Éih^iÁh. Consume una cantidad de unidades de tiernpo (rnilisegundos) para mantener un sonido. ; Parámetros: ; tiempo = número de milisegundos a consumj-r. ; símbolos: v equ 4770 n eq\l v/I7 ; ; velocidad de Ia cPU en KHzs. (8088) i vafor del contador para producir un milisegundo de ; demora ---------- sonretar macro tiempo Iocal- bucle1,bucle2 push cx ; etiquetas loca]es ; salvar reqistro afectado ; bucl-e de los rnilisegundos mov cx,tiernpo ; cx = tiernpo bucl-e1: i denorar un milisegundo push cx nov cxrn buc1e2: Joop buc1e2 pop cx loop bucle1 pop cx endm 600 ; salvar cx ; cx = n ; bucle de retardo i récuperar cx ; bucle unidades ; recuperar registro afectado SOPMUSIC.ASM i i Programa: SOPMUSIC. ; Descripción: ; Prueba subrutina SOSMUSIC. i SÍmbolos: t egu I92o t duración de una nota redonda (nilisequndos) ; Procedirnientos externoss extrn sosmusic: far ; Módulos: include sonnotas.asm nila secmcnt 5!¿gj¡ db pila 12a ends datos segment tiernpo dw t dup (rpiLat) ; duración de una nota redonda (rnilisegundos) ; ; tabla de notas tabl-a label byte incfude some]isa.asm i rrPara Elisarl datos ends ; ---------- codigo segment sopmusic proc far assume cs:codigords:datos,ss:pila i poner dirección de retorno a1 DOS en 1a pila Push ds sub ax,ax push ax ; direccionar segnento de datos con ds mov axrdatos nov ds,ax push ds l-ea ax, tiempo ; duración de una nota redonda push. ax push ds lea ax,tabla t tabla de notas push ax cal-L sosmusi-c 601 sopmusic endp codigo ends end 602 sopmusic SOPSONMl.ASM Programa: SOPSONMI-. nae¡ri n¡i Án. Prueba subrutina SOSSONM1. SÍrnbolos: (ci.c1oslseg.) fre_ini equ 1oO i frecuencia inicial (ciclos/seg.) equ 2ooo ; frecuencia fj-nal fre-fin fre inc equ 1oo ; incremento de frecuencias (ciclos/seg.) durácion equ looo ; duración de cada frecuencia (nilisegundos) n equ (fre_fin - fre ini) /fYe lnc + l- ; nro. de veces r Procedimientos externos: extrn sossonmlr far i pila >e\jtrrErrL db pila ends rl^l-ñ< <ódmóhl- fre d\ t datos ends codigo segment dur r Lau^ 128 dup (rpilar ) ? dr4t duracion ; frecuencia ( ciclos/seg ) (nilisegundos ; duración ) sopsonml proc far assume cs: codigo, ds:datos, ss:pila i poner dirección de retorno aI DOS en 1a pila push ds sub ax, ax push ax i direccionar segmento de datos con ds móv mov ^v.láfos ds,ax mov cx,n i número de iteraciones del- bucle mov fre,fre_ini ; frecuencia inicial ; producir sonido de frecuencia = fre y duración = dur bucl,e 3 push ds 1ea ax, fre ; frecuencia push ax push ds l-ea ax, dur ; duración 603 push ax call sos sonml add fra fra loop bucle raf i sopsonmL endp codigo ends end 604 sopsonm]- i n¡ ; sumar incremento de frecuencias SOPSONM2.ASM Programa: SOPSONM2. nac¡r'i n¡ i Án . Prueba subrutina SOSSONM2. SÍmbolos: (cicl-os/seg.) fre_ini equ L00 i frecuencia inicial (ciclos/seg.) fre*fin equ 2000 ; frecuencia final fre*j.nc equ L00 i incremento de frecuencias (cicLos/seg.) duracion equ 1000 i duración de cada frecuencia (niliségs.) n equ (fre_fin - fre_ini)/fre_inc + l, ; nro. de veces ; Procedimientos éxternos: extrn sossonm2 far 3 pila pifa segment stack db ends datos fre dr^t ? datos ends dur 'L2A dup ( rpil-ar ) segment dw dur:acion ; frecuencia i duración (ciclos/seg) (milisegundos) ---------codiqo segment sopsonn2 proc far assume cs: codigo,ds: datos, ss:pila i poner dirección de retorno aI DOS en 1a pila t ñrr eh qrrh ¿l e push ax i direccionar segmento de datos con ds mov ax,datos mov ds,ax mov cxrn i número de iteraciones def bucle mov frerfre ini i frecuencia inicial ; producir sonido de frecuencia = fre y duración = dur úuc1e: push ds . fra¡rron¡i ¡ rsa push ax l-ea ax, dur i duración 605 push ax cal-l- sossonm2 add fra fro loop bucle ret sopsonm2 endp codigo ends end 606 sopsonm2 i ¡¡ ; sunar incremento de frecuencias SOPTECLA.ASM i i Programa3 SoPTECLA. i Descr j-pción: r convierte el- tecfado en un instrumento ¡nusical. ; Para tocar las notas A, B, c, D, E, F, G, pulsar La tecla de Ia Letra minúscula correspondiente (a, b, c, d' e, f, 9). i t Inicial-mente, supone octava 5. Para canbiar a otra octava (0 a 7) ' ; pulsar 1a tecla numérica correspondiente. Para tocar una nota bernol, pulsar Ia tecla mayúscula (A, B, C, D, E/ i G). r F, : pará terminár- nulsar fa tecl-a Enter. t ; se util-j-za el- nétodo 1 para producir sonido (nediante e1 i ternporizador). , símboLos: duracion equ l,5o ,' duración asociada a cada nota (ni1J-segundos) ; Procedi,mientos externos: extrn sossonm].:far extrn sosnota:far ; ---------- pila segment stack db pila datos ends t2A dup ( 'pil-a' ) segment octava db 5 nota db O,2,3,5 17 ,8,!O notab db Ir99,4,6,99,9,).'). num db ? numabs db ? fre dw ? dur d!¡ duracion datos 5 i octava (o a 7), inicialnente es a rrgrl i notas asociadas a Las teclas rrarr rrArr a rrcrl ; notas asociadas a Las teclas i e1 valor 99 indica que no existe bemol ¡ nro. de la nota en 1a octava (0 a 11) ¡ nro. de Ia nota absoluta (0 a 95) ¡ frecuencia (cicl-os/seg) ; duración (mil-isegundos) ends ---------codigo segnent soptecla proc far assume cs : cod j-go, ds : datos , ss : pil-a i poner dirección de retorno al Dos en Ia pila t push ds sub axrax push ax i direccionar segmento de datos con ds mov ax,datos Inov ds, ax 607 bucle: ; l-eer tecla mov ax,O i función: esperar para l-eer tecta int l-6h ; 1lamar al BIOS ; ver si tecla Enter (fin de1 prograna) cmp ah,1ch jne a9 cmp aL,odh jne ag reE i ¿teclas narr a ilgrt? ag: cnp a1 ,rrarr jb agb cmp af ,tt9tt ja agb sub aI ,rrarr mov ah,o mov bxrax mov al,nota[bx] mov nun,al jnp absofuta i comparar con Ían ; si inferior, bifurcar ; conparar con rtgrl ; si superior, bifurcar ; af = 00h a O6h ,' ah = 0 i bx = índice de nota t af : nú¡nero de 1a nota en La octava ; num = nú¡nero de la nota en 1a octava t ¿tecl-as rrAr a rtcr? agb: cmp al-, rrArr ; comparar con trAr¡ jb no7 t si inferior, bifurcar cmp al,rrcrr i comparar con ncr j a n07 ,. si superior, bifurcar sub aL,rrArr ; a1 = 00h a O6h mov ah,o i ah : 0 mov bx,ax i bx = índice de nota mov al-,notablbx] t aI : número de Ia nota en 1a octava cmp aI,99 t ¿existe bemol para 1a nota? je bucle ; no, ignorarla mov num,al ; num = número de Ia nota en la octava jmp absofuta t ¿teclas rr0n a rrTn? no7: cmp a1 , rrorr jb bucle cmp af , rrTrr ja bucle sub al,rtorr mov octavaral jnp bucle ; comparar con rr0r ; si inferior, bifurcar ; comparar con rrTrl i si superior, bifurcar ; aI = ooh a 07h ; octava = 00h a 07h ; calcular 1a nota abso.Luta (0 a 95) absoluta 608 3 mov al",octava rnov sir12 mu1 si add a1,num ; al = octava ; si = 12 (notas por octava) ; al = octava*12 t aL = octava*l-2 + nota ¡nov numabs,al ; nurnabs = nro. de l-a nota absoluta ; ca]cuIar 1a frecuencia asociada a una nota absoLuta push ds lea axrnumabs ; nota absoluta push ax push ds 1ea ax, fre ; frecuencia push ax calf sosnota ; producir sonido de frecuencia = fre y duracj.ón = dur push ds 1ea ax, fre ; frecuencia push ax push ds l-ea ax, dur ; duración push ax call- sossonml jmp bucl_e soptecla endp codigo ends end soptecl-a 609 SOSMUSIC.ASM t ; subrutina: sosMusIc. ; Descripción: ; subrutina general para producir rnúsica por eI al-tavoz a partir de ; una tabla de notas musicales. ; S" utiliza el- método l- para producir sonido (acceso af altavoz ; rnediante eI ternporizador). ; cada entrada de l-a tabl-a se compone de: i - Número de la nota (o a 95). 0 a LL corrésponden a Ia octava 0. ; L2 a 23 corrésponden a Ia octava L. t i. 84 a 95 corresponden a La octava 7. t Las l-2 notas de una octava son: i do,do#,re,re#,mi,fa,fa$,sol,soIf;,la,1af,,si: t c, c#, d, d#, e, f, f#,9 , g{,a , a#, b i i - Duración de l-a nota respecto a la mitad de una semifusa (2 a ).28) 64 - bl-anca, 32 - negra, l-6 - corchea L28 - redonda, , 4-fusa, 2-semifusa 8-senicorchea, ; ; un sil-encio se indica con el- valor 254. ; E1 final de Ia tabla de notas se indica con el val-or 255. ; Parámetros: params sEruc dr¡ ? ; bp salvado por Ia subrutina retorno dd ? ; dirección de retorno p2 dd ? ; dirección parámetro 2 (ent) (bytes) ; tabla de notas musicales p1 dd ? ; dirección paránetro 1 (ent) (1 palabra) t duración de una nota redonda (nilisegundos) params ends i r Simbolos: final equ 255 ; final de la tabla de notas silen equ 254 ; sil-encj.o nret equ offset pL - offset retorno i argumento de ret ; Procedimientos externos: extrn sossonmL: far extrn sosnota:far ; ---------- datos tiernpo nota notad dw db db frec frecd datos d\^t ? dh¡ ? codigo 610 segment ends ? ? ? ¡ duración de una nota redonda (rnilisegundos) , número de La nota (o a 95) , duración de Ia nota respecto a 1a nitad de una ; semifusa (2 a L28) , frecuencia (ciclos/seg.) , duración asociada a 1a frecuencia (rnilisegundos) segrnent Para rcodigol assume cs: codigo,ds : datos public sosmusic c^chlrc'i^ . hr^^ frr push bp mov bp,sp i --i salvar reqistros afectados push ds push es push si push ax i direccionar segmento de datos con ds mov ax,datos mov ds,ax ; recoger parárnetros de entrada les si, tbpl.pl ; es : segrnento, si = desplazaniento mov ax,es:[si] i ax : duración de una nota redonda ; (rnilisegundos) mov tiernporax ; tienpo = duración de una nota redonda t (nifisegundos) les si, [bp].p2 , es: [si] es l-a primera nota i bucle para recorrido de Ia tabla de notas bucl-e: mov al,es3 [si] mov notaral cnp nota,fj-na] je fin inc si mov al,es: [si] mov notad,al i a1 = nro. de Ia nota ; nota = nro. de la nota t ¿fin de Ia tabla de notas? ; si, bj-furcar isi=si+li ax : duración de 1a nota i notad = duración de l-a nota ; convertir número de la nota en frecuencia push ds ; nota (entrada) push ds i frecuencia (salida) lea ax,nota push ax lea ax, frec push ax call sosnota i convertir duración de 1a nota en mifisegundos ; entrada: notad, salida: frecd call not_dur ; generar sonido asociado a la nota push ds l-ea ax, f rec ; frecuencia (ciclos/seg.) push ax push ds ; duración (nilisegundos) 611 lea ax, frécd push ax ; generar sonido ; apuntar aL siguiente elenento de 1a tabla de notas call sossonml inc sj;si:si+1 l¡np bucle ; restaurar registros afectados fin: pop ax pop s]. pop es pop ds ; --mov sp,bp pop bp ret nret sosrnusic endp not_dur proc near i convierte duración de la nota en rnilisegundos. ; entrada: notad = duración de l-a nota respecto a l-a mitad de una semifusa (2 a I28) ; ; salida: frecd = duración en milisegundos. push ax ; salvar registros afectados push cx push dx ; calcul,ar tienpo*notad/128 mov ax,tiernpo mov ch,O rnov clrnotad mul cx mov cx,l28 div cx mov frecd,ax pop dx pop cx pop ax ñ^+ Árlr óh^h t codigo 612 énds end i ax = tiempo de una redonda (rnilisegs.) ; ch : 0 ; cx = duración de la nota ; cafcular tiempo*notad ; (dx,ax) = tiempo*notad i cx = 128 i ax = tiempo*notad/128 ; duración reaf de l-a nota ; restaurar registros afectados SOSNOTA.ASM ; i Subrutina: SOSNOTA. ; Descripción: ; ConvÍerte número de nota absotuta (0 a 95) en frecuencia. ; ; ; Los números de las notas absofutas son: 0 a 11 corresponden a Ia octava O. 12 a 23 corresponden a fa octava l-. i 84 a 95 corresponden a la octava 7. ;. ; Las 12 notas de una octava son: ; do,do#,re,re#,mi,fa,faS,soI,soI#,Ia,1afi,si = i c t c#, d, d#, e, f, f#, g, g#,a, a#, b ; Parámetros: params struc dr¡/ ? ; bp salvado por Ia subrutina retorno dd ? ; dirección de retorno p2 dd ? ; dirección paránetro 2 (saf) (1 palabra) ; frecuencia p]dd ? ; direcci-ón parárnetro 1 (ent) (1 byte) ; número de l-a nota (0 a 95) params ends ; Sírnbolos: nret equ offset p1 - offset retorno ; arqumento de ret áatos segment ; frecuencias de 1as notas rnusicales de La octava 7 notas dr¡/ 2093 ; do dr4¡ 22L7 t do# dr^¡ 2349 ; re dw 2489 ; re# drr 2637 t ni dw 2794 t fa dw 2960 ; fa# dw 3l-36 ; sof d\^¡ 3322 ; sol# d$/ 3520 t 1a dhr 3729 t la# dw 3951 t si datos ends i ---------- codigo segrnent para rcodigol assume cs: codigo, ds: datos pubLic sosnota sosnota proc far push bp mov bp,sp i salvar registros afectados 613 Push ds push es push si push ax push bx push cx push dx ; direccionar segmento de datos con ds mov axrdatos mov ds,ax i recoger parámetro de entrada les si, tbpl.pl ; es = segnento, si = desplazarniento mov al,es: [si] ; al : núnero dé la nota ; obtener 1a octava y e1 núrnero de l-a nota dentro de l-a octava mov ah,o mov c]-,L2 div cI ; ax = núnero de l-a nota ; cI = 12 notas/octava ; dividir entre 12 ; aI : cociente (octava) (nro. nota en la octava) ; at¡ = resto i obtener la frecuencia dentro de l-a octava 7 mov dh,o ; dh = 0 mov dl,al i dx = octava mov al,ah i aL = nro. de la nota en Ia octava mov ah,o ; ax = nro. de 1a nota en Ia octava sal- ax,1 t ¡nultipl-icar por 2 (Ia tabla de frecs. t (tiene dos bytes por elemento) r ax = 2*nro. de 1a nota en la octava mov bx,ax i bx = 2*nro. de l-a nota en Ia octava mov cxrnotas[bx] t cx = frecuencia de ]a nota en octava 7 ; cal-cular la frecuencia real xchg cxrdx neg c1 add cl-,7 sar dx,cI ; pon". parárnetro de salida 1es si, [bp].p2 mov es: Isi],dx i cx = octava, dx = frecuencia en octava 7 t cl- = -octava ;c1=7-octava ; dividir frecuencia entre 2**(7-octava) i dx = frecuencia ; es : segmento, si = desplazamiento ; frecuencia ; restaurar registros afectados pop ox pop cx pop bx pop ax pop si pop es pop ds 614 mov sp,bp pop bp ret nret sosnota endp codigo ends end 615 SOSSONMl.ASM Subrutina: SOSSoNMI.. Descripción: Produce un sonido de una frecuencia deterninada durante un cierto número de ¡nilési¡nas de segundo. se utiliza el ¡nétodo 1 para producir sonido (acceso a1 altavoz rnediante el tenporizador) . Parámetros 3 params struc dw ? ; bp salvado por Ia subrutina retorno dd ? ; dirección de retorno p2 dd ? ; dirección parámetro 2 (ent) (1 pal-abra ) ; duración (rniJ-isegundos) p1 dd ? ; dirección parámetro l- (ent) (1 palabra) ,' frecuencia (ciclos Por segundo) params ends i símbolos: nret equ offset p1 - offset retorno ; arsumento de ret i Macros: incl-ude somretar.asm ; ---------- codigo segnent para rcodigot assume cs:codigo pubLic sossonml sossonml- proc far push bp mov bp,sp salvar registros afectados push es push si push cx push dx recoger parámetros de entrada Les si, tbpl,pL i es : segmento, si = desplazamiento mov cx,es:[si] i cx = frecuencia l-es si, [bp].p2 ; es = segmento, si = desplazamiento mov dxres: [si] ; dx = duración proceso para generacón de1 sonido retardo: 616 crnp cxro je retardo call fre_per call tem ini call tem per call son ini ; ¿frecuencia cero? ; si, bifurcar ; convertir frecuencia a perÍodo i preparar al tenporizador i cargar al tenporizador con eI período ; activar temporizador y altavoz somretar dx call son_fin r retardo i desactivar ternporizador y altavoz i restaurar registros afectados pop dx pop cx pop si pop es t --mov sp,bp pop bp ret nret sossonml endp fre_per proc near ; Convertir frecuencia (ciclos/seg) en período del temporizador. t Se utiliza La fór¡nu1a LL93I82/frecuencia. ; entrada: cx = frecuencia. t salida: 6y = período. push ax ; salvar registros afectados push dx mov dx,12h mov ax,34Dch div cx fra ' nov cxrax pop dx pop ax nar 6ñ.1ñ ; 11931,82 : 1234DCh t preparar dividendo ; dividir entre Ia frecuencia i ax = cociente (período) i cx = período i restaurar registros afectados t ten_ini proc near temporizador. ; f.ri"ialirar t (Preparar al temporizador para recibir eI período). push ax ; sal-var registro afectado rnov al,L82 out 67,aI pop ax ret ; aI = 182 i preparar al temporizador para recibir ; ef PerÍodo i restaurar registro afectado te¡n_ini endp ; ---------- tem_per proc near i cargar el periodo en el" tenporizador. ; entrada: s¡ = periodo 617 É $ +óñ hó¡ push ax ; salvar registro afectado mov a1, cl, out 66, a1 mov al-, ch out 66, aI pop ax ret . : . h\rf ó én\/iar h\,+ó i nfari ^l <rrnarinr ¡¡ témhórizadol. ; enviar a1 temporizador i restaurar regj-stro afectado ÁñAh son_ini proc near ; Activar ternporizador y altavoz. push ax i salvar régistro afectado q? ih a] ; leer contenido de 1a puerta B de1 PPI or al-, 03h ; poner bits 0 y 1 con valor lout 97 rali activar temporizador y altavoz pop ax i restaurar registro afectado <nn i ; ini óñ^h ---------- son_fin proc near ; Desactivar temporizador y altavoz. push ax i <nn i fin codigo in a]-t97 and aI,oFCh ñrrl- O? i salvar registro afectado i leer contenido de 1a puerta B def PPI ; poner bits 0 y 1 con valor 0 ; desactj.var temporizador y altavoz pop ax i restaurar registro afectado an^n ends end 618 a l SOSSONM2.ASM t t Subrutina: SOSSONM2. ; ; Descripción: ; Produce un sonido de una frecuencia deterrninada durante un cierto ; núnero de miLésirnas de segundo. ; Se utiliza el- ¡létodo 2 para producir sonido (acceso directo al t altavoz). ,' Paránetros: para¡ns struc dw ? ; bp salvado por la subrutina retorno dd ? ; dirección de retorno p2 dd ? i dirección parárnetro 2 (ent) (l- palabra) i duracj-ón (rnilisegundos) pldd ? i dirección parárnetro 1 (ent) (1 palabra) ; frecuencia (ciclos por segundo) óñ.1c i t Simbolos: v equ 4770 ; frecuencia del reloj del- microprocesador, en KHzs. nret equ offset p1 - offset retorno ; argumento de ret ; ---------- codigo segment para rcodigo' assune cs:codic¡o public sossonm2 sossonn2 proc far push bp mov bprsp ; --i salvar registros afectados push es push si push ax push bx push cx push dx ; recoger parámetro frecuencia 1es si, [bp].p1 mov bxres:[si] i es = segnento, si = desplaza¡niento i bx = frecuencia i cál"cul-o de n = 29*v/f ; (n = contador ciclo de demora) ; (f = frecuencj-a) mov axrv ; ax = v mov si,29 i si = 29 nul si ; (dx, ax) = 29*v div bx i ax = 29*v/f t¡ov cx,ax i cx : contador ciclo de denora push cx i sa]var contador cicl-o dé de¡nora ; ; recoger paránetro duración i 1es si, [bp].p2 ; es : segmento, si = desplazamiento 619 mov ax,es: [si] ; ax = duración cá]culodem=t*f/1OOO (m = número de veces a ejecutar e1 cicl-o compl_eto de sonido) (t = duración de1 soni-do, en rnilisegs.) (f = frecuencia) mu1 bx mov si, i-000 div si mov cx,ax pop bx ; (dx,ax) = t*f ; sj = 1000 ; (dx'ax) = t*f/IOOO ; cx = contador ciclos compfetos de sonido i bx = contador ciclo de demora ; proceso para generación del sonido c1i call ten_off ; bucfe principal ; desactivar interrupciones ; desactivar tenporizador bucle: ; bucle dé demora para señal = 1 push cx bucl-el-: call son ini mov cx,6x ; salvar cx i actívar altavoz ; cx = contador bucl-e de demora loop buc]el i retardo señal = 1 ; bucle de demora para seña1 = O bucl-e0: call son fin mov cx,bx ; desactivar altavoz i cx : contador bucl-e de de¡nora ; retardo señal = 0 i recuperar cx loop bucleo pop cx loop bucle i restaurar registros afectados pop dx pop cx pop bx pop ax pop sl pop es nov sprbp pop bp ret nret sossonÍI2 endp ; ---------- tem_off proc near i Desactivar ternporizador push ax 620 ; salvar registro afectado in al-,9'7 and aI ,oFEh out 97,aI pop ax ret ; feer contenido de la puerta B del PPI i poner bj.t o con va]or 0 ; (desactivar temPorizador) ; escribir sobre la puerta B del PPI ; restaurar registro afectado tem_off endp i ---------- son_].n1 proc near i Activar altavoz. push ax in or a!,g7 a1,02h out 97,aI pop ax rét i sa]var registro afectado i feer contenido de 1a puerta B del PPI ; poner bit L con valor L i (activar altavoz) i escribir sobre 1a puerta B del PPI ; restaurar registro afectado son_ini endp ; ---------- son*fin proc near ; Desactj-var aLtavoz. push ax in ál q7 and al,oFDh ^^Dvrr i ai! ¡¡r codigo out 97,aI pop ax ret ; salvar regi-stro afectado i leer contenido de 1a puerta B de1 PPI i poner bit 1 con valor o t (desactivar altavoz) ; escribir sobre la puerta B del- PPI i restaurar registro afectado ^-¡* e¡¡qy ends end 621 ?s Conversión de datos La conversión de la información se plantea entre los diferentes tipos de datos: o números binarios con y sin signo; . cadenas de caracteres; o números decimales empaquetados y desempaquetados; . cadenas de caracteres; o cadenas de caracteres hexadecimales. En las aplicaciones que se presentan en este capítulo se han considerado, por una parte, las siguientes: a de Binsrio Binsrio Cadens de sin signo con signo caracteres Binario sin signo COMBOAS Binario con COMBIAS signo Cadena de caracteres 62 COMASBO Y, por otra, las siguientes: a Csrácter de Cadena Cadena de hexadecimal caracteres COMCRHX Carácter Cadena hexadecimal Cadena de caracteres COMASHX Conversión de una cadena de caracteres ASCII a binario Teniendo en cuenta que, por ejemplo, el número 5417 =5 x 103 + 4x 102+ I x 10' +7 es equivalente a: 5417 :541 x 10 + 7: (54x10+1)xl0+7: ((5 x10+4)xl0+1)x10+7 es decir: ( 0xl0)+5: 5 ( 5x10)+4: 54 ( 54x10)+1: 541 (54lxl0)+7:5417 el procedimiento de conversión consiste en, empezando por el valor cero, multiplicarlo por 10 y sumarle el primer dígito de la cadena, al resultado volver a multiplicarlo por l0 y sumarle el segundo dígito, y así sucesivamente con todos los caracteres de la cadena. Para convertir cada carácter a su número binario equivalente, hay que restarle '0' : 30h. Algoritmo: Entrada: car(i), i: 1,...,n (cadena de caracteres) n : número de caracteres de la cadena Salida: m : resultado (número binario) 623 m=0 Hacer i : I a n ; recorrer los caracteres de la cadena d : car(i)-'O' ; número binario asociado acadacarácter m:m'10+d Fin-Hacer Conversión de un número binario sin s¡gno en una cadena de caracteres Para extraer los dígitos de un número binario, se divide este número entre 10, el cociente se vuelve a dividir entre 10, y asi sucesivamente hasta que el cociente sea cero. Los restos de las divisiones (en orden inverso) forman los dígitos del número. Por ejemplo: s4r7 I to 541 I Ito tI Ito ;t'o 0 El procedimiento de conversión consiste entonces en hacer esas divisiones sucesivas y en colocar los restos obtenidos en orden inverso sobre la cadena de salida. La longitud de la cadena de salida es de 5 bytes como máximo, pues el número máximo de entrada es de 65535. Algoritmo: Entrada: m = número binario. Salida: car(i), i = 1,...,5 (cadena de caracteres) n = número de caracteres de la cadena n=0 ;valoresiniciales Hacer i : I a 5 c(i) : " ; inicializar la cadena de salida con blancos t:IIl Fin-Hacer Hacer i : 5 a I con incremento -l d : resto de (t/10) t = cociente de (t/10) 624 sit:0 fin car(i) : d +'0' Il=fl*l Fin_Hacer almacenarlo convertido en carácter incrementar longitud de la cadena Aplicaciones Macros COMASBO COMASHX COMBOAS COMBIAS COMCRHX Convierte una cadena de caracteres ASCII en un número binario sin signo. Convierte una cadena de caracteres ASCII a hexadecimal. Convierte un número binario sin signo de una palabra en una cadena ASCII de cinco caracteres. Convierte un número binario con signo de una palabra en una cadena ASCII de seis caracteres (cinco caracteres más el signo). Convierte carácter a hexadecimal. Programas: COP Prueba macros de conversión. 625 COMASBO.ASM Macro: coMASBo. Descripción: convierte una cadena de caracteres ASCII en un número binario sin signo. Parámetros: cadena = cadena de caracteres ASCII (ent) (variable). l"on = Iongitud cadena Ascrr (ent) (l- palabra) (variable, registro o vafor innediato). numero = número binario sin signo (saI) (1 pal-abra) (variable). t comasbo macro cadena,Ion,numero focal bucle i salvar reqistros afectados push ax push bx push cx push dx push si i bucle caracteres de ]a cadena mov cx,l-on ; cx = longitud de La cadena ASCII mov axr0 iax=0(resultado) mov di, 1-0 t di = 10 (constante) ;bh=0 mov bhr0 mov sir 0 i despl-azamiento inicial sobre cadena bucl-e: mul di ; rnultiplicar resul-tado por Ia constante ; ax = nuevo resultado mov bl,byte ptr cadenalsi] t bI = carácter de l-a cadena sub b1, r0l ; bl- = dígito en binario add axrbx ; sunar a resultado inc si ; apuntar a carácter siguiente de fa cadena loop bucle ; siguiente carácter ; i poner parárnetro de salida mov numerorax ; restaurar registros afectados pop si pop dx pop cx PoP bx pop ax endm 626 COMASHX.ASM ; ; MacTo: i COMASHX. ; Descripción: Convj-erte cadena de caracteres ASCII a hexadecimal. ; Cada carácter ASCII de entrada se convierte en dos caracteres ; hexadecinales. ; i ; Paránetros: cadéna : cadena de caracteres ASCII (ent) (variable). ; : longitud de la cadena (ent) (1 pafabra) (variable, lon ; ; o valor inmediato). campo = canpo de sal-ida (sal) (variable). ; : ; registro ---------- comashx nacro cadena,lon,carnpo l-ocal- bucle ; safvar registros afectados push cx push si push di ; valores iniciales mov cx,lon >r ¡ U mov di,0 i cx = lonqitud de La cadena i desplazamiento inj-cial- sobre cadena t desplazamiento inicial sobre campo i bucle caracteres de l-a cadena bucfe: corncrhx cadena I si ], carnpo Idj, ] inc si ; siguiente carácter de entrada add di,2 ; posición en área de salida Loop buc]e ; restaurar registros afectados pop di pop si pop cx endm 627 COMBOAS.ASM ,' Macro: COMBoAS. i ; Descripción: ; convierte un número bj-nario sin signo de una palabra en una i cadena ASCII dé 5 caracteres. ; ; Parámetros: i numero = nú¡nero binario con signo (ent) (L pal-abra) (variable). ; cadena = cadena de caracteres ASCfI (sal-) (5 bytes) (variable). ; Ion = fongitud cadena ASCII (sal-) (l- byte) (variable). conboas nacro numerorcadena, Ion local re11eno,bucle ; salvar registros afectados push ax pu6h bx push cx push dx push si ; recoger número de entrada sobre ax mov axrnumero i rellenar cadena de salida (5 caracteres) con blancos ; aI final del loop, cx = O y bx - S mov cxr5 t contador = 5 mov bx,0 ; bx = desplazamiento inicial relleno: mov byte ptr cadena[bx], I I i mover b]anco inc bx ;bx=bx+L loop relleno mov si,1-0 sobre cadena t si = l-0 (constante) ; bucl-e de obtención de los dígitos decirnal-es . bucle: sub dx,dx borrar rnitad superior de1 dividendo dividendo: dx, ax dividir entre l-0 div si ax = cociente, dx = resto rot conversión del- resto a carácter ASCII add dl-, bx=bx-ldec bx mov byte ptr cadenalbx],dl ; al-macena ef carácter en 1a cadena ; (de der. a ízq.) inc cx ; contador de caracteres convertidos or axrax isiax=Q,zf=I jnz buc]e i bifurcar si no cero rnov lon,cl i nover cl = longitud de la cadena i restaurar registros afectados ; 628 pop si pop dx pop cx pop bx pop ax endm 629 COMBlAS.ASM ; Macro: COMB1AS. ; Descripción: ; Convierte un núrnero binario con signo de una palabra en una ; cadena ASCII de 6 caracteres (5 digj.tos ¡nás el signo). ; Parámetros: ; numero: nú¡nero binario con si-gno (ent) (1 palabra) (variable, registro o val-or inmediato). i ; cadena = cadena de caracteres ASCII (sa1) (6 bytes) (variable). ; fon = fongitud cadena ASCII (sal) (1 byte) (variable). ? ; ---------- comblas rnacro numero, cadena, l-on l-ocaf reIleno,bucIe, fin ; sal-var regj-stros afectados push ax push bx push cx push dx push si ; recoger núrnero de entrada sobre ax mov ax,numero ; rell,enar cadena de sal-ida (6 caracteres) con blancos ; af final del loop, cx = O y bx = e mov cx,6 i contador = 6 mov bxrO i bx : desplazarniento inicial, sobre cadena relleno: mov byte ptr cadenalbx], | | ; mover blanco inc bx ibx=bx+1 loop rel-leno ; si el- número de entrada es negatj-vo, hacerLo positivo mov sirl-O ; si = 10 (constante) oraxrax;siax<0rsf=1 push ax ; salvar ax jns bucl-e t bifurca si no signo neg ax i hacerfo positivo ; bucte de obtención de los dígitos decirnales bucle: sub dx,dx ; borrar mitad superior del dividendo ; dividendo: dx, ax div si ; dividir entre 10 i ax = cociente, dx = resto add dl,'0' ; conversión de1 resto a carácter ASCII dec bx ;bx=bx-lmov byte ptr cadena[bx],d1 ; almacena el carácter en 1a cadena ; (de der. a izq.) inc cx ,' contador de caracteres convertidos or ax,ax ;siax=o,zf=1 ; bifurcar si no cero )nz bucle : 630 COMCRHX.ASM I tu".o, coMcRHX. t Descripción: ; Convierte carácter a hexadecimal. i ,' Parámetros: ; car = carácter a convertir (ent) (1 byte) (variable). ; campo = canpo (sal-) (2 bytes) (variable). corncrhx macro car, carnpo l-ocal, sum1, seg1, sum2, seg2 ; safvar registros afectados push ax push cx push si i recoger carácter sobre aI mov al,byte ptr car ; conversión carácter mov ah,al and ah,ofoh and a1,0fh mov cl-,4 shr ahrcl r nibble inferior (at) cmp aI,9 j1e sumL add al-r55 jnp segl suml: add al, r0r ; af = carácter de entrada -L Y¡r /a {e l-ri+c\ vfur/ i ah = abcd0000 (4 bits superiores) i al = 0000efgh (4 bits inferiores) ; 4 bits de desplazamiento t ah = 0000abcd i compara con 9 ; si nenor o igual, bifurcar i convertir en A, B, C, D, E o F i convertir e1 dígrito en carácter t nibble superior (ah) cmp ah,9 l1^ J TE add ahr55 jnp seg2 i conpara con 9 ; si menor o igual, bifurcar ; convertir en A, B, c, D, E o F sun2: add ah,rOr ; convertir el dígito en carácter ; poner parámetro de salida seg2 3 mov byte ptr campo,ah mov byte ptr canpo+l-,aI ; restaurar registros afectados pop sJ- 631 pop cx pop ax endn 632 COP.ASM i . , Dr^dF^ñ.. ¡ rvY!q¡"s. a^D vvr. ; . nacnrin¡iÁ¡. Prueba nacros de conversión. ; ; SÍmbolos: 1 n . ró+^rno de Carro lf édrr 1? . áli-entaCión de 1Ínea i i Macros: AI-L incLude comasbo.as¡n include conboas.asm include comblas.asn include conashx.asn Ínclude comcrhx.asm include pamesct.asm include pamescc.asm endif pila segment stack hi 6hd< i I ^ datos nsal nento nentlcent csal5 csa16 hsal2 hsal-4 1sal titboas titblas titasbo titlong datos db L28 dup (rpilar) segment stack ? ; núnero binario de salida 1-234 i núnero binario de entrada positivo número binario de entrada negativo -L234 r0123r ir cadena de caracteres ASCII de entrada 5 dup(?) i cadena de 5 caracteres AScfI de salida crrlf, ' $l 6 dup(?) ; cadena de 6 caracteres AscII de salÍda cr,l-f , '9' 2 dup(?) i 2 caracteres hexadecirnales de sal-ida lCl ¡r l€ 4 dup(?) ; 4 caracteres hexadecimales de salida cr,l-f , r$r r?r ; longitud cadena de salida rConversión de 1234 (binario sin signo) a ASCII: dw dw dr^¡ db db db db db db ^h db db db db ¡r vl ^h ¡lf l , lClY I 'Conversión de -1234 (binario con signo) a ASCII: cr,If, t$t rconversión de La cadena 0l-23 a binario sin signo: I cr,lf, r$l tlongitud = t rsl db db db db db db ' I ends codigo seglnent vvY n¡n¡ yrvv €r¡ !q! assume cs : codigo, ds : datos , ss : pila i poner dirección de retorno al DOS en 1a pila push ds sub ax,ax 633 push ax ; direccionar segrnento de datos con ds hñ\t r{^tOS ^Y mov dsrax i ; prueba de comboas pamesct titbOas i escribir título comboas nénto, csal5, lsalpamesct csa15 ; escribir cadena pamesct titlong r escribir tÍtuLo comashx lsal-,1,hsaL2 panesct hsaf2 ; escribir cars. hexadecimales ; ; prueba de combl-as pamesct titbLas r escribir título t escribir cadena conbl-as nent1, csal-6, Lsal_ pamesct csal-6 pamesct titlong ; escribir títul-o ; escribir cars. hexadecimal-es comashx l-sa1,1,hsa12 pamesct hsal2 ; prueba de comasbo parnesct titasbo ; escribir título comasbo cent,4,nsal comashx nsal,2,hsal4 pamesct hsa14 i escribir cars. hexadecirnal-es ret ; volver a1 DOS cop endp vvqrYU ^^a i -^ end 634 cop 30 Aritmét¡ca mult¡ precisión Hemos visto que las instrucciones aritméticas del microprocesador están limitadas en cuanto a precisión (número de bits): Operando I Operando 2 Resultado suma resta 8/t6 bi S 8/t6 bi S 8/16 bits 8/16 bits multiplicación división t6/32 bi S 8/16 bits 8/16 bits 8/16 bits 8/16 bits Operación 8/16 bi S 16/32 bits 8/16 bits El número máximo que puede obtenerse como resultado (multiplicación) es: 232 - | : 168- I : FFFFFFFFh : 4 294 967 295 : 4,2 x lOe (aproxi- madamente). Se plantea ahora el tema de la posibilidad de realizar cálculos aritméticos sin limitar el número de bits o dígitos. Por ejemplo, se podría plantear el problema del cálculo de 100! (factorial de 100), que como se sabe es 100 x 99 x 98 x 97 ... x2x Vamos a ver a continuación cómo se resuelve este problema para cada tipo de operación. Existen tres alternativas: trabajar con números binarios, con números decimales empaquetados o con números decimales desempaquetados. x l. 635 De estas tres formas de representación numérica, la más córnoda a efec- tos de calculos aritméticos multiprecisión es la de los números desempaquetados, por dos razones: o La programación es más sencilla. . El resultado de la operación está prácticamente preparado para ser escrito sobre la pantalla. Para ello basta sumar el carácter '0' : 30h : :48 a cada dígito antes de escribirlo. Por ejemplo, el dígito 04h se convierte en el carácter 34h:'4' . Los números binarios multiprecisión se construyen encadenando juntos varios números de 8 ó 16 bits, que a todos los efectos pueden considerarse cada uno como un dígito (con valores decimales 0 a255 ó 0 a 65535, respectivamente). Existiría una cuarta alternativa, que sería trabajar directamente con los caracteres ASCII '0' a'9', pero es menos cómodo que trabajar con el formato desempaquetado, al tener que convertir cada dígito a binario (restando '0') antes de realizar las operaciones. Suma y resta Hemos visto también que no es difícil hacer sumas o restas de cualquier número de bytes o palabras. Basta para ello con tener en cuenta el valor del acarreo (bandera CF), arrastrándolo a la posición siguiente. Multiplicación Para lograr la multiplicación de dos números multidígitos, se opera como con la multiplicación manual. Por ejemplo: 257 x4 3 6 6x2 6x5 6x7 4x2 3x2 3x5 3x7 4x5 4x7 Es decir, hay que multiplicar cada dígito de un operando por todos los dígitos del otro operando. Numerando los dígitos de derecha a izquierda a partir de cero, el valor de posición del dígito i es 10i. El valor de posición del producto de los dígitos i y j es 10i* j. Por tanto, hay que sumar a la posición k : i + j del producto el dígito inferior y sumar el dígito superior (acarreo) a la posición siguiente (k + l). Si se trabaja con números binarios, el sistema es similar. Por ejemplo, Gt6 en la multiplicación de dos números binarios sin signo de 32 bits (dos palabras): Operando 1: (AX, BX), AX : palabra superior, 3¡ : palabra inferior Operando 2: (CX, DX), CX: palabra superior, DX = palabra inferior AX BX XCXDX DXxAX DXXBX DXxBX DXxAX CXxAX CXx BX ll CXx BX CXxAX I Como en el caso anterior, con el resultado de cada producto parcial (dos palabras) hay que sumar al resultado la palabra inferior a la posición k y sumar la palabra superior a la posición k + 1. El resultado final en este caso es de cuatro palabras (64 bits). Si se quiere multiplicar dos números binarios con signo de 32 bits (dos palabras), la solución más sencilla consistiría en convertir en positivos los operandos negativos, realizar la multiplicación sin signo y luego cambiar el signo del producto sólo en el caso de que uno sólo de los dos operandos sea negativo. División Para o$éner'éi cociente y el resto de dos números multidígitos se opera también como en lb,división manual. Por ejemplo: Obtención primer dígito: 5 4 68 _23 9 12 3 e I 307>23 9 ... continuar restando 3078 l? z g -239 2 0 6 8 <2 3 9 ... fin primer dígito Obtención segundo dígito: 0 6 8 8 _23 9 lz s g 2l 0 4 4 9 > 2 3 9 ... continuar restando 637 o44e I23e Cociente :22, resto :210. -239 22 0 2 | 0 <2 3 9... fin segundo dígito - Si m es el número de dígitos del dividendo y n los del divisor, el número de dígitos del cociente es m-n + 1. En el caso del ejemplo, 4-3-r l:2. Numerando, como siempre, los dígitos de derecha a izquierda, el primer dígito a calcular del cociente es el m-n. El algoritmo sería: ¡ Hacer L: n hasta m (n es la longitud inicial del segmento del dividendo a considerar, de izquierda a derecha, es decir, se cogen tantos dígitos del dividendo como dígitos tenga el divisor). . Dígito cociente (k) :0. . Mientras segmento del dividendo sea mayor o igual que el divisor, . Sumar I a dígito cociente (k). . Restar divisor del segmento del cociente. . Coger dígito siguiente de dividendo (L: L + l). e Fin-Hacer. Aplicaciones Mocros: MPMMULTI - Cálculo del producto de dos números decimales desempaquetados. MPMRESTA - Cálculo de la diferencia de dos números decimales desempaquetados. MPMSUMAR - Cálculo de la suma de dos números decimales desempaquetados. Progromas: MPPDIVID - Prueba subrutina MPSDIVID. MPPMULTI - Cálculo de factoriales. Prueba macro MPMMULTI. MPPRESTA - Prueba macro MPMRESTA. MPPSUMAR - Prueba macro MPMSUMAR. Subrutinas: MPSDIVID - Calcula el cociente y el resto de la división de dos números decimales desempaquetados. 638 MPMMULTI.ASM , MacTo: MPMMULTI. ; Descripción: ; cálcuIo del producto de dos números decimal-es desempaquetados. ; Parámetros: ; numerol = multipficando (ent) (variabl-e). i n1 = nro. de bytes de1 nultipli-cando (ent) (valor inrnediato). ; numero2 = multipLicador (ent) (variable). i n2 = nro. de bytes de1 rnultiplicador (ent) (valor inmediato). ; resultado = producto (sal) (variable). ; n = nro. de bytes de1 resuLtado (ent) (valor innediato). ; ---------- nprnmulti macro numerol , n1 , numero2 , n2 , resultado , n 1ocal bucle1, buc1e2 , sumpro, noaca, fbucleL, fbucle2 t si = desplazamiento sobre numerol ; di = despfazamiento sobre numero2 i bx : desplazamiento sobre resultado ; sa]var registros afectados push ax push bx push cx push dx push si push di ; desplazamiento inicial mov st,n1-1 sobre numerol, (dÍqito rnenos significativo) i bucle digitos de numerol mov cx,nli cx = nro. de dígitos de numerol buclel-: mov al-,byte ptr numerol[si] ; extraer dígito de numerol crnp aI ,0 t ¿es o? je bifurcar fbucl-elt si... ; buc]e dígitos de numeroz push cx mov c.x,n2 mov di,n2-1 bucl-e2: ; salvar cx i cx = nro. de dígitos de numero2 i desplazamiento inicial sobre numeroz ; (dígito menos significativo) mov bl,byte ptr nunero2tdil ; extraer díqito de numero2 cmp b1,0 t ¿es 0? je fbucle2 ; si ... bifurcar ; nultipl-icar los dos dígitos desempaquetados mul bl ; ax = aL*b1 aam ; ajustar: ah = dígito sup., al = dÍgito inf' ; ; calcul-ar posición correspondiente en resultado r - (nl-- 1 - s1+ n2-r -di) = n-n1 -n2+ 1+si+di i bx=n? 639 mov bXrn-nl--n2+1 add bx, si add bx,di i sumar a resul-tado sumpro: mov F1 dh, byte ptr F add jnc add al, dh noaca ah, L resultadoIbx] ; extraer dígito de resul-tado . ^€ - ^ i sunar ; bifurcar si no acarreo ; ajustar byte ptr resul-tadolbxl ,aI ,' rnover digito inferior cnp ah, 0 ; ¿dÍgito superÍor es 0? io fbucle2 t si ... bifurcar mov a1, ah ; pasar1o a dígito inferior nov ah, 0 dec bx ; apuntar a dígito anterior -inn mov sumpro i fbucle2: fbuclel: dec di loop buc1e2 pop cx dec si loop bucl-el- ; apuntar a digito anterior de numero2 ; recuperar registro t apuntar a dígito anterior de nurnerol- i restaurar registros afectados pop di pop si pop dx pop cx pop bx pop ax endm 640 MPMRESTA.ASM ; MacTo: MPMRESTA. i ; Descripción: cáLculo de Ia diferencia ; i de dos números decimales desernpaquetados. ; Parámetros: ? ; ; ; ; ñrlmór^l ñri hr = y-.,,er operando (ent) (variable) . nunero2 = segundo operando (ent) (variable). resultado = diferencia (nurnerol- - nunero2) (saf) (variabl-e). n = nro. de bytes de los operandos y del resultado (ent) (valor inmediato). mpmresta macro numerol,nunero2,resultado, n local- buclernoaca ; safvar registros afectados push ax push bx push cx push dx push si i desplazamiento inicial- (dÍgito menos significativo) mov sr,n-1 ; acarreo inicial¡nov dl , 0 t bucle dígitos mov cx'n ; cx = nro. de dígitos mov al,byte ptr nunerol,[si] i extraer dígito de numerolmov bl,byte ptr nunero2[si] ,. extraer dígito de numero2 add bI,d1 ; sumar acarreo anterj-or mov d1,0 ; nuevo acarreo restar los dos dÍgitos decirnafes desempaquetados ; mov ahro ;. ah = 0 ^s - ^ ^l^ sub al'bl i aI : al - bI aas aI i = dígito, cf = 1 indica que hubo acarreo jnc noaca i bifurcar si no acarreo mov dlrl i nuevo acarreo bucl-e: i ; mover a resultado mov byte ptr resultadoIsi],aI dec si loop bucle ; nover díqito a resultado i apuntar a digito anterior ; restaurar registros afectados pop si 641 pop dx pop cx pop bx pop ax endm 642 MPMSUMAR.ASM Macro: MPMSUMAR. Descr j-pción: Cálculo de la suma de dos núrneros decirnales desempacfuetados. Paránetros: nunerol = primer sumando (ent) (variable). nunero2 = segundo sumando (ent) (variable). resuftado : suma (sal) (variable). : nro. de bytes de 1os sumandos y del resultado (ent) n (vaIor Ín¡nediato). ; ---------- mpmsumar macro numerol-,numero2,resul-tado,n Local bucl-e ; salvar registros afectados push ax push bx push cx push dx i push si i desplazamiento inicial mov si, n-l- (dÍgito rnenos significativo) i acarreo inicial mov dL,0 ; bucl-e dígitos mov cx,n ; cx = nro. de dígitos mov al,byte ptr numeroLlsi] ,. extraer dígito de nunerol mov bl,byte ptr nunero2[si] i extraer dígito de numero2 ; sumar l-os dos dígitos deci¡nales desempaquetados mov ahro ; ah = 0 add al , blta1=a1+bl aaa i ajustar: ah = dígrito sup., al- = dígito inf. add al,dI ; sumar acarreo anterior mov dlrah ; nuevo acarreo ; i mover a resul-tado mov byte ptr resuftado[si],af ; rnover dígito a resul-tado bucl-e: dec si 'I nnn i ; restaurar hrr¡l a registros ; apuntar a digito anterior afectados pop sr pop dx 643 pop cx pop bx pop ax endn 644 MPPDIVID.ASM ; ; Programa: MPPDIVfD. . ; nac¡rin¡iÁ-. ¿Pvrv¡r. Prueba subrutina MPSDIVID. ; Sinbolos: n1 equ 10 ; nro. de bytes del- dividendo y del cociente n2 equ 4 ; nro. de bytes del- divisor y del resto cr equ l-3 ; retorno de car¡o lf equ 10 t alinentación de lÍnea ,' Procedimientos externos: extrn mpsdivid: far ; Macros: if include pamescn.asm include pamescc.asm include pamesct.asm endif r_ iir. pila ; segment stack db ends r28 dup (,pilar) ---------- datos segment stack dividendo db O,Lt2,3,4,5,6,7,Bt9 ,$, db divisor db O t9,8,z ,$, db cociente db n1 dup (O) ,$, db resto db n2 dup (0) ,$, db rDividendo = $' titul-ol db tDivisor titulo2 db $' rCociente = tituloc db = $' rResto : $' titulor db datos ends ; ---------- codigo segment mppdivid proc far assume cs: codigo,ds: datós, ss:pila ; poner dirección dé retorno al DoS en la pila push ds sub ax,ax push ax ; dj-reccionar segnento de datos con ds nov axrdatos mov dsrax 645 ; parámetros push ds l-ea ax, dividendo ; dividendo push ax push ds fea ax,divisor ; divisor push ax push ds l-ea axrcociente ; cocj-ente push ax push ds l-ea ax, resto ; resto push ax call mpsdivid ; dividir i escribir números beméset titulol ; escribir títul-o pamescn dividendo ; escribir dividendo pamescc cr ; saltar 1Ínea ¡¡na<¡¡ ; I f pamesct titufo2 pamescn divisor pamescc cr i -^*^-^^ Pan'E-uu rt a ! pamesct titul-oc pamescn cociente pamescc cr *^*^^^^ Pqn'c>vv i 1 r t6 pamesct titulor pamescn resto pamescc cr h^ñÁ<^^ i nnnAirliA ¡nyyg¿ Y i ¡nA i ¡n 646 I f i escribir título i escribir cociente i sal-tar 1ínea i escribir títu1o i escribir resto i saltar línea ; volver ret andn on¡l c ; escribir título ; escribir divisor ; saltar linea *--, v ¡uPPs¿ i "id aI DoS MPPMULTI.ASM , . "rog.u.., MPPMULTI. née^rih^iÁñ. ; ; cálcu]o de factoriafes. PTueba macro MPMMULTI. ; Simbolos: nun equ 50 dig equ 2 i nro. máximo del que se va a calcular e1 factorial , nro. de digitos de num n equ nun*dig ; nro. de bytes del producto (factorial) nl- equ dig ; nro. de bytes del multiplicando n2 equ n i nro. de bytes def muftiplicador cr equ 13 ; retorno de carro ff equ l-0 ; alimentación de l-Ínea ; Macros: A I.L i nc l rrrip nnmmrrl.!i. ¡5¡ include nAmé<en.asm include pamescc.asm endif ; ---------- pila pila segment stack db ends L28 dup ('pila,) t ---------datos segment stack numerol db n1 dup (0) ,$, db numero2 db n2 dup (0) ,$, db resuftado db n dup (O) ,9, db contador dr^r Q datos ends ; ; multiplicando (varía de l- a num) r muttiplicador (factorial- anterior) i producto (nuevo factorial) ; contador bucle principal ---------- codigo segment npprnulti proc far assume cs : codigo, ds : datos , es : datos , ss : pila ; poner dirección de retorno af DOS en l-a pj-l-a push ds sub axrax push ax i direccionar segmento de datos con ds y es mov axroaEos mov ds,ax mov es,ax i vafores iniciales 647 i mov nunerol-+n1-L,1 nov nunero2+n2-1,r 1 t bucLe faetoriaLes bucle: ; resul-tado = nuneroL * numeroz nprnnulti numeroL , nl- , nuneroz , n2 ' resul-tado, n ; escribir nú¡neros pamescn numerol pamescc r!l parnescc pamescn resultado palnescc cr parnescc 1f isumarlanumerol mov si,nL-L sunarL: nueve: escribir nunerol escribir carácter escribir carácter escribir resultado escri-bir carácter escribi-r carácter apuntar al último dígito de numerol- cnp nunerolIsi],9 Je nueve add numerolIsi],1 jmp seguir si ... bifurcar mov numerolIsi],0 dec si mover O 'inn ¿es 9? sumar L apuntar a dígito anterior arrmarl segu].r: ; mover resultado a numeroz push cx mov cx,n 1ea si,resultado 1éa di,numeroz rep movsb ; poner a cero e1 resultado mov cxrn lea di, resultado mov a],0 <+ ¡vr pop cx ^cLr inc contador cmp contador,num )ge fin j¡np bucle fin: ra* i rrPy¡(s¿ -hññrrl+i i e+ codigo 6/t8 an¡in v.¡er ends end nppnulti salvar registro cx = número de dÍgitos de resultado si = desplazamiento de resultado di = despLazamiento de numero2 es: [di] = ds: lsi], si = si+t, di = di+1 cx = número de dÍgitos de resultado di = desplazaniento de resultado es: [di] = 0' di = di + 1 restaurar registro contador=contador+1 ¿contador = num? si ... bifurcar ; volver af DOS MPPRESTA.ASM ; Programa: MPPRESTA. ; Descripción: ; PTUEbA NACTO MPMRESTA. ; Símbolos! n equ L9 ; nro. de bytés de los operandos y déL resultado i i Macros: if linclude mpnresta.asm include pamescn.asn incl-ude pamescc.asm endif ; ---------- pila pila ; segment stack db ends 128 dup ( rpila' ) ---------- datos segrnent stack numerol db 1,2,3,4,5,6,7 ,8,9,O,I,2,3,4 t5,6 t7 ,8,9 rsl db numero2 db 0r0r1r2,3,4r5,6,7,8r9rOrf.,2t3r4,5,6,7 tc I resultado ^h db n dup (0) i diferencia (nunerol - nurnero2) Ah datos l(r ends ;---------codigo segmént mppresta proc far assume cs: codigo, ds: datos, es:datos, ss:pila i poner dirección de retorno al DOS en Ia pila push ds sub ax,ax push ax ; direccionar ségmento de datos con ds mov ax,datos mov ds,ax t- - i resultado = nunerol, - numero2 mpmresta numeroL, nuneroz , resultado, n ; escribir nrineros panescn numeroL pa¡nescc t-t pamescn nunero2 pamescc r=r parnescn resultado t escribir numerolt escribir carácter ; escribir numero2 i escribir carácter t escribir résultado 649 ret nppresta endp codigo 650 ends end mpprésta ; volver al DOS MPPSUMAR.ASM Programa: MPPSUMAR. nae¡ri n¡ i Á¡ . Prueba macro MPMSUMAR. SÍnbolos: n equ L9 ; nro. de bytes de 1os sunandos y de1 resultado Macros: if1 include mpmsumar.asm include pamescn.asn j-nclude pamescc.asm endi-f ; : i ---------- pila segment stack db ends Tza dup (rpilar) ; nunerol db nurnero2 db db resultado db Ah datos IQI ends codigo segment mppsumar proc far assume cs: codigords: datos, es:datos, ss:pil-a ; poner dirección de retorno al DOS en l-a pila push ds sub axrax push ax ; direccionar segrnento de datos con ds mov ax,datos nov ds, ax resultado = numerol + numero2 mprnsumar numerol , nunero2 , resuftado, n escribir números nr1ñarOl pamescc r+t pamescn numero2 Pamescc r=l náhéscn resul tado ; escribir ; escribir ; escribir ; escribir t escribir numerol carácter numero2 carácter resultado 651 ret ñhhcrrñá ; codigo 652 r óñ.lh ends end mppsumar ; vofver aL Dos MPSDIVID.ASM ; ; SubrutJ,NA: IIPSDIVID. r Descripciónl ; calcül-a el- cociente y el, resto de la división de dos números ; decirnales desernpaquetados. ; Pará¡netros: parar¡s struc dr4/ ? ? retorno dd p4 dd ? p3 dd ? p2 dd p1 dd params ends , bp salvado por la subrutina ; dirección de retorno ; dirección parámetro 4 (saf) ; resco ; dirección Paránetro 3 (sal) ; coclenEe ? ; dirección Paránetro 2 (ent) t cl]'vLsor ? ; dirección parámetro 1 (ent) ; dividendo ; símbolos: equ 10 ; nro. de. bytes def dividendo y del- cociente nl y del resfo n2 equ 4 ; nro. de bytes deL divisor nret equ offset pl - offset retorno ; argumento de ret ; datos segnent para divÍdendo db nl dup(o) db r$l cociente db n1 dup(o) Áh l<t divisor txtmayor txtmenor txtrestar db n2 dup(o) datos ends ; i db'mayor$' db rmenor$' db trestar$l ------------- codigo segment para assume cs:codigo public npsdivid rnpsdivid proc far push bp mov bp,sp ; safvar bp t bp : sp i sal-var registros afectados push ds push es push ax push bx push cx push dx push si Push di 653 ; dj-reccionar segmento de datos con es assune es:datos mov ax,datos mov esrax ; recoger parámetro l- (dividendo) l-ds si, [bp].p1 mov cx,n1 cld lea di,dividendo rep movsb i ds = segnento, si = despl-azamiento ; cx = nro. de bytes del dividendo ; dirección hacia adelante ; di = desplazamiento dividendo i nover i recoger parárnetro 2 (divisor) lds si, ¡bp1.pz mov c.xtn2 cl-d 1ea di,divisor rep movsb i ds = segmento, si = desplazamj-ento ; cx = nro. de bytes del- divj-sor ; dirección hacia adelante t di = desplazamiento divj-sor ; mover ; direccionar segmento de datos ta¡nbién con ds assume ds:datos mov axres mov ds,ax i operaciones iniciales mov bx,n2-1 mov dxrn2 mov cx,nl--n2+1 principal r bucl-e bucfe: conpa: mov cociente[bx]r0 ---- I ^^ññ^r --^.---dr cmp al,o je esmenor call restar inc cocientefbxl j¡np compa ^ál estnenor: inc dx inc bx loop bucle i mover cociente a p3 i desplazamiento prirner dígtito en cociente ; nro. de dígitos a considerar en dividendo ; dígitos a calcular de cociente ; movér 0 a cociente i conparar dx dígitos dividendo con n2 ; digitos del- divisor t ¿dividendo menor que divisor? t si ... bifurcar ; sumar l- a cociente ; considerar otro digito en dividendo i apuntar a siguiente dígito de cocÍente cl-d ; dirección hacia adel-ante mov cxrnl i cx = nro. ile bytes del cociente l-es di, tbpl.p3 ; es = segmento' di = despfazamlento 1ea si,cociente t si = desplazaniento cociente rep movsb i lnover ; nover dividendo a p4 (resto) ; dirección hacia atrás std 654 cx = nro. de bytes del resto es = segmento, dí : desplazarniento apuntar a último digito di = desplazamiento dividendo apuntar a úItimo dígito mov cx , ft2 l-es di, Ibp].p4 add di,n2-1 Iea si,dividendo add si,n1-1 rep movsb mover ; restaurar registros afectados pop di pop srpop dx pop cx pop bx pop ax pop es pop ds i --- mov sp,bp ret mpsdivid endp nret ;sp=bp ; restaurar bp comparar proc near i comparar dx dígitos del dividendo con n2 dígitos de1 divisor ; salida: a1 = 0, dividendo rnenor que divisor aI : 1, dividendo mayor o igual que divisor ; push bx ,' salvar regÍstros afectados push cx push si push di buclec: mi: SE: mov cxrdx mov si,dx sub si, cx mov al,dividendoIsi] mov dirn2 sub di,cx cnp di,o jSe ni mov bI,0 jnp se nro. de dígitos a comparar si=dx si=dx-cx a1 = dÍgito de1 dividendo di=n2 di=n2-cx ¿di apunta a dígito de divisor? si ... bifurcar mov bl,divisorIdi] bl = dÍgito def divisor cmp al- , bljb menor ja mayigu bifurcar si a1 < bl bifurcar si al- > bl- I rnayigu: menor: ^^ñ hil^l ^ídi+^ ¡nnnrr¡r'l = n nc óñ mov alr 1 jnp finc mov aI,0 finc: 655 pop di pop si pop cx pop bx ; restaurar registros afectados ret cornparar endp ; ---------- restar proc near i restar n2 digitos de1 divisor de los dx dÍgitos del dividendo push ax ; sal-var registros afectados push bx push cx push si push di ; desplazarniento inicial (digito rnenos significativo) mov si,dx ; si = dx dec si tsi=dx-1" mov di,n2-1 i bucle digitos ¡nov cx,dx i acarréo inicial bucl-er: i cx = nro. de digitos mov ah,0 ¡nov al,dividendoIsi] i extraer digito de dividendo ; dígito de divisor may: sum: cald: segu: cnp di,O lge may mov bL,o j:np sun ; ¿di apunta a dÍgito de divisor? i si ,.. bifurcar i no .. dígito = O mov bl,divisor[di] i extraer dÍgito de divisor i sumar acarréo anterior ,. compara dígitos i bifurcar si al >= bl add blrah cmp a1 , bljae cald add al, l-0 sub al-, bl mov ah,L jnp segu sub al,bl mov ah,0 mov dividendoIsi],aldec si dec di loop bucler i restaurar registros afectados 656 ,. restar dígitos i nuevo acarreo i nuevo acarreo ; mover dígito i apuntar a dígito anterior de dividendo ; apuntar a digito anterior de divisor pop pop pop pop pop rócfar ret di ^i cx bx ax óhdñ i codigo ends end 657 31 Matemát¡cas En este capítulo se han incluido algunas aplicaciones de tipo matemático, concretamente el cálculo delaraiz cuadrada y de los números primos. Raíz cuadrada Se utiliza el método de Newton de aproximaciones sucesivas. El seudocódigo para el cálculo de la raiz cuadrada de n es el que se describe a continuación. Las divisiones son enteras o Primera aproximación: al : n/2 Si al :0 al:1 ¡ Bucle para aproximaciones sucesivas: s2: (n/al + al)/2 Si valor absoluto de (a2-al): I resultado : a2 fin al:a2 ¡ Fin bucle 658 Por ejemplo, si n:27, aproximación I : 27 /2 : 13 aproximación 2 : (27 / 13 + l3)/2 : 7 aproximación3 : (27/7 +'7)/2 : 5 aproximación 4 : (27 /5 + 5)/2: 5 Luego la raíz cuadrada de 27 es 5. Si se quiere obtener otro decimal, habría que calcular la raiz cuadrada de 2700. La subrutina que implementa este algoritmo (MASRAIZ2) está limitada a números de 16 bits, pero es fácil desarrollar una subrutina que se aplique a números multidígitos, apoyándose en los desarrollos del capítulo anterior. Otro método para calcular Ia raiz cuadrada se basa en la propiedad de que la ra\z cuadrada de un número es igual al número de enteros impares que pueden restarse sucesivamente de dicho número. Por ejemplo, si n:27 , Contador Número Número impar Dferencia Número impar/2 I 27 26 I 26 0 2 a J a J ¿J 5 l8 l8 7 ll 2 9 2 4 -9 J+ 4 +5 ll 6 2 ll I J Como en el paso 6 la resta ya es negativa, la raiz cuadrada es 5. También es igual a la mitad del primer número impar que hace que la diferencia sea negativa. La rutina que implementa este sistema es: RATZZ PROC Entrada: AX Salida: BX: raiz cuadrada, redondeada al entero más próximo MOV BX,-l ; BX: SIG: ADD BXp ; obtener-1siguiente valor impar SUB AX,BX ; diferencia JG SIG ; si positiva, bifurcar SHR BX,l ; BX: BX/z (número impar/2) ADD AX,BX ; sumárselo a la diferencia JNC FIN ; bifurcar si no acarreo INC BX : entero sieuiente FIN: RET R-AIZZ ENDP 659 Números primos Un número primo es el que no es divisible más que por sí mismo y por la unidad. Los números pares no son primos (son divisibles entre 2). Para ver si un número impar es primo, hay que dividirlo entre los números impares inferiores a él y que sean menores o iguales que su rau cuadrada. En el programa MAPPRIMO este límite superior es la mitad del propio número. Aplicaciones Programas: MAPPRIMO - Listado números primos. MAPRAIZ2 - Prueba subrutina MASRAIZ2. Subrutinus: MASRAIZ2 - Calcula la raiz cuadrada de un número binario de 16 bits sin signo (método de Newton). 660 MAPPRIMO.ASM ; ; Programa: MAPPRIMO, ,. ñ^^^-l*^l:-. ue>errPUrv¡r. Listado números prinos. ; t SimboLos: nl- equ l; número inicial n2 equ 1000 ,' núrnero fj-naI cr equ 13 ; retorno de carro l-f equ 10 ; alimentación de l-inea ; Procedimientos externos: extrn pasbor: far ; Macros: if1 i nc l rrdp h^mcrrr. asln include pamesct.asm include pamescc.asm incl-ude comboas.asm endÍf pila pil-a ; segrnent para stack 'pila' db ends I2A dup ('pi1a') ---------- datos segment nensaje db 25 dup(r r),rTabLa de Números Primos',cr,If db 25 dup(' '),'==:== =======t,crtJ-ftLf db rsr n dw 0 r núnero binario m dw 0 ;divisor nitad dr¡i O ;n/2 nulnero db 8 dup (r t) ; número en caracteres ASCII db rsl long db 0 ; longitud cadena de caracteres AscII datos ends ¡nrl <ódmahl- i an ; nrnnrin¡ n¡¡¡ f^¡ assurne cs : codigo, ds : datos , ss : pil-a i poner en la pil-a la dirección de retorno al Dos Push ds sub axrax push ax ; direccionar segrnento de datos con ds mov ax,datos mov dsrax 661 ; borrar pantalla cal-l- pasbor ; posicionar cursor en (0,0) pamcur 0,0 i escribir mensaje inicialpamesct mensale , mov n,n1 ; bucle principal ; n : n1 (valor i-ni-cial) ciclo_ini: ; chequea si n <= 3 cmp n,3 jfe prino i conpara con 3 ; bifurca si menor o igual ;calcular¡nitad=n/2 mov ax'n sub dx,dx mov sír2 div si cmp dx,o je cicLo_fin mov rnj.tad,ax ; aX = n i borrar rnitad superior del dividendo ; dividendo: dx, ax ; si = z ; dividir entre 2 i ax = cociente, dx = resto i ¿resto : 0? (núnero par) ; si, bifurcar ,' nitad = cociente de n/z i bucle prueba de divisores 3,5r --.,n/zi mov ilr3 ; primer divisor ciclod_ini: mO\/ ax'n ; aX = n sub dx,dx ; borrar mj.tad superlor del dividendo ; dividendo: dx, ax mov si,n tsi=n(divisor) div si ,' dividir entre m ; ax = cociente, dx : resto cmp dx,O ; ¿resto = 0? (núrnero no primo) ie ciclo fin r si hifrrrq¿¡ i ; chequeo fin bucfe prueba de divisores ciclod_fin: mov ax,m i ax = m cnp ax,nitad i conpara con valor final i bifurca si maYor o igual lge primo add m,2 .'m=m+2 jnp cicl-od ini ; bj-furcar ; chequeo fin bucle principal ciclo_fin: 662 mov ax,n i ax = n i cmp ax,n2 jse fin incnin=n+lihh ^i^r^ ini ; compara con vafor final ; bifurca si rnayor o igual ; bifurcar ; convertir núrnero binario a cadena ASCII prirno: ^^hL^^- l¡, -trhór^ ¡rq¡'LE!v, l^ñ^ rvr¡Y ; ; escribir cadena ASCII del- nú¡nero prirno por pantalla n^néq.t i ; retorno fin: mrnnrina nlrmefo 'imn ciclo fin al- DoS ret onÁn ; i -^ v ^^l r9 uvu énd nannri¡g 663 MAPRAI22.ASM .¡ i Programa: MAPRAIZ2. ; Descripción: ; Prueba subrutina MASRAIZ2. t Procedimientos externos: extrn masraiz2zfar ; Macros: if1 include pamésct.asm include pamescc.asm include comboas.asm endif pila pila ; i segment para stack tpilal db ends r2A dup (rpila') -------------- datos segment db tLa raiz cuadrada de 16386 es t db ,$, n dw l-6386 i numero binario de entrada m dl4r ? ; número binario de salida numero db 5 dup(?) ; cadena ASCII db ,$, long db ? ,; lonqitud cadena datos ends titulo ; ---------- codigo segment rnap¡aiz2 proc far assune cs 3 codigo , ds : datos , ss : pila ; i poner en La pila 1a direccj-ón de retorno a1 DOS push ds sub axrax push ax ; direccionar segmento de datos con ds nov ax,datos nov ds,ax ; --i calcular Ia raíz cuadrada push ds ; n lea axrn push ax nnsh ds 664 ; m l-ea ax, m push ax caL] masraiz2 ; convertir resultado (n) a ASCII (numero) comboas ln, numero, long ; ; escribir ef resultado namesct titulo pamescc numero ; retorno al DOS fin: ret maprai22 endp ^^A i d^ óhAe end napraiz2 665 MASRAI22.ASM ; Subrutina: MASRAIZ2. t Descripción: ; calcul-a Ia raíz cuadrada de un núrnero binario de 16 bits sin siqno. ; Parámetros: params struc dh¡ ? ; bp salvado por l-a subrutina retorno dd ? ; dirección de retorno p2 dd ? ; dirección parárnetro 2 (sal) (1, palabra) i raiz cuadrada p1 dd ? ; dirección parárnetro l- (ent) (1 pal-abra) ; numero parans ends ; SímboLos: nret equ offset p1 - offsét retorno i argumento de ret ; ---------- coclrgo segment para assume cs: codicro publ-ic masraizá masraiz2 proc far push bp mov bp,sp ,. sal-var bp; bp = "O ; --i sal-var registros afectados push es push ax push bx push cx push dx push si ; recoger parámetro de entrada Les si, lbpj.p]; es = segmento, si = desplazarniento nov si,es: [si] t si = núnero ; cafcular primera aproxirnación = núnero/2 mov cx,2 mov ax,si mov dx,o div cx icx=2(constante) i ax = número t dx = 0 ; dividir entre 2 ; cociente en ax, resto en dx i ax = primera aproxj-mación ; ¿es cero? ; no, bifurcar ; ax = primera aproxirnación = 1 crnp ax, 0 jne siguiente mov ax,1 i obtener siguiente aproxirnación = ax = (nú¡nero/ax + ax)/2 ; siguiente: mov bx,ax i bx = aproximación anterior mov dx,o i dx = 0 ¡nov ax,sj; ax : número 666 div bx add ax,bx mov dx,o div cx ; dividir entre aProxinación i ax = núnero/bx, dx = resto ; ax = (número/bx + bx) ; dx = 0 ; dividir entre 2 i cociente en ax' resto en dx i comparar aproxirnación anterior (bx) con nueva (ax) sub bx,ax i bx = diferencia entre l-as dos cmp bx,1 ; ¿mayor que l-? ja siguiente t si ... bifurcar ; poner parárnetro de salida fin: 1es si,[bp].p2 i es = segmento, si = despfazamiento mov es: Isi],ax ; restaurar registros afectados pop si pop dx pop cx pop bx pop ax pop es mov sprbp pop bP ret nret ; sp = bp ; restaurar bP masraiz2 endp nnd i an énrl< end 667 32 Estructuras de datos El diseño de un programa implica dos tareas de diseño: o El algoritmo, es decir, el seudocódigo. r Las estructuras de datos, es decir, la forma de organización de los datos en memoria. Los programas sencillos no puede decirse que contengan realmente estructuras de datos. Pero el diseño de un programa complejo hace totalmente necesario el conocer las diferentes estructuras para seleccionar las más adecuadas. Existen muchas formas de organizar la información en la memoria. Las formas más comunes de estructuras de datos son: o Listas. Una lista es una colección de elementos de datos organizados de forma secuencial. Cada elemento de la lista puede ser de uno o más bytes de longitud y estar compuesto por uno o más campos. La secuencia puede ser física (los elementos ocupan posiciones adyacentes en memoria) o lógica (cada elemento incluye un puntero al siguiente elemento de la lista). Los elementos de una lista pueden estar desordenados u ordenados. En este último caso, la ordenación puede ser ascendente o descendente. 568 Tipos de listas son: . Colas'o listas FIFO (first in, first out). La inserción de elementos es por un extremo y la recuperación por el otro. . Pilas o listas LIFO (last in, first out). La inserción y la recuperación de elementos es por el mismo extremo. r Tablas. Una tabla son dos o más listas relacionadas entre sí. e Matrices. Colección de elementos que se acceden mediante uno o varios índices. El número de índices determina la dimensión de la matriz. o Arboles. Colección de elementos organizados por niveles. o Cadenas (strings). Vamos a centrarnos en la estructura más utilizada: la lista. Clasificación de una lista. Método de la burbuja Es el método más conocido para clasificar una lista en'q.lemoria. Consiste en recorrer la lista desde el primer elemento hasta el penú'himo, compa- rando cada elemento con el siguiente. Si están ya clasificados, se dejan como están. Si están desclasificados, se intercambian sus posiciones. Como resultado de este proceso, el último lugar de la lista contiene el mayor de los elementos (si clasificación ascendente), es decir, está ya clasificado. A la lista pendiente de clasificar (elementos I a n-1) se vuelve a aplicar el procedimiénto anterior, y asi sucesivamente. En total, el número de recorridos a realizar es de n-1. En el recorrido i hay que explorar los elementos I a n-i. Por ejemplo, para la lista (217, 12, 14, 5) de n : 5 elementos: Recorrido 1: exploración elementos I a n-l:4 2 2l-777 7 2l12 12 14 14 5555 3 4 estado final 1 12 2l* 14 12 14 2t* t2 t4 5 2l (elemento ordenado) 669 Recorrido 2: exploración elementos I a n-2 = 3 | J+ 12 14 5 21 2 7 12* 14 5 21 3 7 12 14* 5 21 estado final 7 t2 5 14 (elemento ordenado) 2l (elemento ordenado) Recorrido 3: exploración elementos I a n-3 :2 | J+77 l2 5 14 21 estado 2 final 125 14 21 5 12 (elemento ordenado) 14 (elemento ordenado) 2l (elemento ordenado) Recorrido 4: exploración elementos I a n-4: I I J+ 5 12 14 21 estado final 5 (elemento ordenado) 7 (elemento ordenado) 12 (elemento ordenado) 14 (elemento ordenado) 2l (elemento ordenado) Puesto que en cada recorrido el valor máximo de los elementos explorados se arrastra o eleva hasta la posición superior de la lista, este método se le denomina método de la burbuja. En total, el número de comparaciones que se realizan mediante este método es: (n-l)+(n-2)+...+ l:+ Si la clasificación hubiera sido descendente en lugar de ascendente, los valores mínimos irían apareciendo al final de la lista. En el ejemplo anterior. 670 Recorridos 1234 2t 21 21 7141414 t2 12 12 14777 5555 2l L2 ALGORITMO DE CLASIFICACION ASCENDENTE Hacerr: I an-l ; buclerecorridos Hacer i = I a n-r ; bucle elementos a explorar Si elemento(i) )elemento(i + 1) temporal : elemento(i) ; intercambiar elementos elemento(i) : elemento(i + l) elemento(i + l) : temPoral Fin-Hacer Fin-Hacer Listas ordenadas. Búsqueda binaria o dicotómica En una lista desordenada, para buscar un determinado elemento es necesario explorar la lista de forma secuencial desde el primero hasta el último elemento. Por término medio, el número de comparaciones será n/2, siendo n el número de elementos de la lista. Si la lista ya está ordenada, la técnica de búsqueda más efectiva es la llamada búsqueda dicotómica o binaria. Consiste en partir el intervalo inicial (l a n) por la mitad (n/2) y seleccionar este elemento. Si este elemento es el buscado, se termina el proceso. Si no lo es, se determina en cuál de los dos intervalos a n/2, n/2 + a n) se encuentra el elemento buscado. Sobre el intervalo seleccionado se vuelve a repetir otravez el proceso, y así sucesivamente hasta encontrarlo. Mediante este método, el número de comparaciones es logrn. (l I ALGORITMO DE BUSQUEDA BINARIA EN LISTA ORDENADA DE FORMA ASCBNDENTE Entrada: n : número de elementos de la lista v:valorabuscar Salida: m: número del elemento en la lista (si m : 0, v no se encuentra en la lista) 671 Si v ( elemento(l) m:0 fin Si v : elemento(l) m:l fin Si v ) elemento(n) Íf:0 fin Si v : elemento(n) m:n fin nr : I ; extremo inferior del intervalo ilz : n ; extremo superior del intervalo Hacer mientras nl ( n, m : (nr + n )/2 ; punto medio del intervalo Si v : elemento(m) fin Si v( elemento(m) flz : tn En caso _contraiio lr : rn Fin-Hacer ; seleccionar intervalo inferior ; seleccionar intervalo superior m:0 fin Aplicaciones Mocros: LIMCLAB - Clasificar lista de bytes en orden creciente. LIMCLAC - clasificar, en orden creciente, una lista cuyos elementos son cadenas de caracteres. LIMGESB - Gestión de una lista de bytes. Progromas: LIPCLAB - Prueba macro LIMCLAB. LIPCLAC - Prueba macro LIMCLAC. LIPGESB - Prueba macro LIMGESB. 672 LIMCLAB.ASM i ,' Macro: LIMCLAB. i Descripcj-ón: ; cLasificar lista de bytes en orden creciente. i Parámetros3 ; lista : lista de bytes a ordenar (ent) (variable). : número de bytes (ent) (número). ; n lirnclab macro lista,n 1ocal buclel,bucfe2 rvf ,salirl-r salir2 ; salvar registros afectados push ax push si push di mov si,1 ; valor inicial bucle externo: si ; = 1 a n-1 buc1e1: índice bucle externo mov di,l- ; valor inici-al- índice bucle interno i bucle interno: di = 1 a n-si bucle2: mov al,byte ptr listaldi-Ll i extraer elemento di de l-a lista mov ah,byte ptr listaIdi] i extraer elemento siguiente cmp al,ah i compararlos jb vf ; bifurcar si están en orden i intercarnbiar los elementos mov byte ptr listaldi.-l-l , ah m^\r h\rfa hf r 'l i<l- áf Ai I ál ; ; ver si fin de bucl-e interno vf: mov ax,n sub axrsi ax = n-si cmp di,ax comparar di con n-si jae sa1ir2 bifurcar si di es superior o igual inc di di=di+1 jnp bucl,e2 . rrar ci €in Aa ; safir2: ----{ue externo hln¡ cmD si,n-1 i¡o <al inn hrt¡la1 j-nc si : cómnár^r si con n-1 i11 tsi=si+1 ; ,' recuperar regj-stros sa1ir1: pop di 673 pop sr pop ax endm 674 LIMCLAC.ASM i Macro: LIMCIAC. ; Descripción: ; Clasificar, en orden creciente, una lista cuyos elementos son ; cadenas de caracteres. ; Paránetros: ; Lista = lista de cadena de caracteres a ordenar (ent) (variable) . ; m = l-ongitud (bytes) de cada etemento de lista (ent) (número). ; n = número de elementos de l_a lista (ent) (número). ---------1i¡nc1ac rnacro 1ista,m,n locaf bucf e1, buc1e2, conpar, inf er, interc, inter, vf , sal ir1, saf i12 t : ; salvar registros afectados push ax push si push di mov si,1 ; valor inicial Índice bucle externo ; bucle externo: si = 1 a n-lbucfel: mov di,1 ; valor iniciaL índice bucl-e interno ; buc]e interno: di = 1 a n-si buc1e2: ; comparar e1 elemento di con eI di+1 push di i salvar índice i cx = nro. de bytes de cada el-e¡nento i aX = m ; ax = di*m t di = despl. primer byte siguiente eLemento mov al,byte ptr lista[di-¡n] ; extraer byte efemento en curso mov ah,byte ptr lista[di] ; extraer byte siguiente elemento crnp al,ah ; comparar bytes ja i.nterc ; bifurcar si superior jb infer ; bifurcar si inferior inc di ;di=di+1 loop cornpar mov cx,m mOV ax,m mul di mov di,ax PoP di jmp vf ; recuperar índice ; i-ntercanbiar 1os el-ementos inter: PoP di push di mov cxrm mov ax,m nul di mov di,ax ; recuperar índice i safvar índice i cx : nro. de bytes de cada eLemento ; ax : n ; ax = di*m t di = despl. primer byte siquiente elemento 675 mov al,byte ptr lista[di-n] mov ah,byte ptr lista[di] mov byte ptr lista[di-n],ah mov byte ptr listaldil,al inc ¿ti lnan i¡#ar pop di. ; extraer byte elemento en curso i extraer byte siguiente elemento t intercambiar bytes tdi=di+1 ; recuperar Índice i ver si fin de bucle interno namesct I i sta mov ax,n sub axrsi cmp dirax jae salj-r2 add di,L jnp bucl-e2 ; ax = n i ax = n-si i comparar di con n-si i bifurcar si dj- es superior o igual ;di=di+1 ; ver si fin de blogue externo sa1ir2: cnp sj-,n-L ; comparar si con n-ljae salir1 inc si ;si=si+ljnp buclel i recuperar registros sal irl- : pop di pop si pop ax endrn 676 LIMGESB.ASM i MACTO3 LIMGESB. l ; Descripción: ; cestión de una lista de bvtes. ; ; Parámetros: ; lista = lista de bytes (ent) (variable). : número de bytes (ent/sal) (registro o variable). ; n ; ope = tipo de operación (ent) (valor inmediato) ; A - añadir elenento aI final" de fa lista ; M - nodificar el"emento de Ia l"ista ; E - eliminar efemento de ta lista ; elem = ele¡nento a añadir/rnodificar/elirninar (ent) (valor inmediato i o registro) ; nuevo : nuevo elemento, caso modifj-cación (ent) (valor inmediato o i registro) ; error = indicador error (O : no, 1 = si) (casos M y E) (sa1) (variabLe o regÍstro). i ; i ---------- lingesb rnacro lista,n,ope,elern,nuevo,error Local buscar, salir,mover, fin buscar: saI ir: nover: if ope eq 'At ; ¿añadir? pusn sa ; sal-var registro mov sÍ,n ; apuntar al final de Ia lista mov byte ptr lista[si],e1ern ; nover elemento incn;n=n+l PoP si ; restaurar resistro endif if ope eq tM, or ope eq ,E' push ax i salvar registros push cx push si rnov si,O ; apuntar a primer elemento de lista mov cx,n i buscar en Los n el-enentos mov al,byte ptr lista[si] ; extraer elemento cmp alrelern ; ¿es el elemento buscado? je salir ; si ... bifurcar inc si .'si=si+l l_oop buscar mov error,I ; error (elernento no encontrado) j¡np f in mov error¿o ; no error if ope eq 'Et ; ¿elininar? mO¡/ CX'n ; CX = n dec cx ; cx = n-1 sub cx,si i cx = n-1 - si (nro. de movirnientos) cmp cxrO ; ¿es e1 último el-emento? jfe fin ; si ... bifurcar mov al,byte ptr listaIsi+1] ,' mover elemento siguiente mov lista[si]ral" i a elemento en curso inc si ,si=si+1 loop mover t mov byte ptr lista[si],t ; mover blanco a1 final decnrn=n-1 else 677 mov al,nuevo ; modificar eI eLenento nov byte ptr lista[si],aI fin: énd11r pop si pop cx pop ax endlr endm 678 ; restaurar registros LIPCLAB.ASM t ; Programa: LIPCIAB. i Descripción: Prueba macro LIMCIAB. i ; SímboLos: n equ 64 ; nro. de elenentos de la lista cr equ 13 i retorno de carro 1f equ 1-0 ; alimentación de línea ; Macros: .lr-L include lirnclab.asm incl-ude pamesct.asm include pamescc.asm endif pila pila segment stack db ends I2A datos titulo1 titulo2 fista segrnent stack datos ends ; db db db db db db dup (rpila') c.r,If ,rLista: ' , cr,If, I gl cr,If,tLista clasificada?|,cr,lf,,$, tqwertyuiopasdfghjklñzxcvbnm, IQWERTYUIOPASDFGHJKLÑZXCVBNMi | 1,2345678901 cr,lf, t$t ---------- codigo Iipclab segment proc far assume cs: codigo, ds: datos, ss:pila ; poner dirección de retorno al Dos en la pila push ds sub axrax push ax i direccionar segnento de datos con ds mov axroacos mov ds,ax parnesct titulol- ; escribir lista fimcfab lista,n pamesct tituto2 ; clasificar lista t escribir lista clasificada ret ; vo]ver aI DoS n¡nac¡f nrnae¡+ I i cl-: I i c+¡ 679 i nal =h rI rPvrev anÁn ¡nA éñA< i n¡ end liPclab 680 LIPCLAC.ASM i Programa: LIPCI,AC. . , i ñ^^^-i us>ut¡Pvru¡¡. -^i :-. Prueba macro LIMCLAC. ; sÍmbolos: m equ 1-0 ; longitud de cada elenento de l-a lista n equ 5 i nro. de elenentos de Ia lista cr equ l-3 i retorno de carro 1f equ l-0 ; alimentación de LÍnea ; Macros: if r, incl-ude linclac.asrn include pamesct.asm include pamescc.asm endi f ; ---------- pil-a pila ; segnent stack db I2a dup ( ,pifa' ) ends ---------- datos titul-oltitulo2 lista datos codigo lipclac segment stack db cr,lf,tLista:r,cr,1f,'$, db cr,1f, rLista cl-asificadazt t db 'Pepe rJuan I db rAntonio I db I db 'Miguel rl,uis | db db cr, lf, | $l ,cr,If,,$, ends segrnent proc far assume cs: codigords: datos, ss: p.iIa i poner dirección de retorno aI DOs en la pila push ds sub ax,ax push ax ; direccionar segmento de datos con ds mov axrdatos mov dsrax panesct titulol pamesct lista limctac ; escribir lista 1ista,m,n t clasificar panesct titul-o2 lista t escribir lipta clasificada 681 pamesct Iista ret 682 Iipclac endp codigo ends enri l inclac ; volver al DoS LIPGESB.ASM Programa: LIPGESB. n6e^ri ñ^i Áñ. Prueba macro LIMGESB. Simbofos: cr equ l-3 ; retorno de carro l-f équ l-0 i alimentación de Iínea Macros: if l_ include lingesb.asm include pamesct.asm include pamescc.asm endif pila pil-a i datos n titulo tituloa ti-tuf oe titulon 1 I ^+^ error datos ; segment stack db L28 ends dup ('pita') segnent stack dr4¡ db db db db db db db db db fLista - fista i nro. de elementos de 1a lista cr,7ft'Lista:',cr,If,'$' cr,J-f, tAñadir efernento Xi | ,cr t ff, t $' cr,l-f ,'ELirninar el-emento ezt ,cr,ff , t$t cr,If, tModificar elernento p por p:r,cr,1f,r$l I abcdefghi j kfmnopqrstuv\,rxyz I cr,1f,'9r |tr*,! elemento nO eXiste ***r cr,lf,t$t ? ; indicador error (O = no, f: si) ends ---------- codigo 'linnacl-. segment hF^^ f.F assune cs: codigo, ds: datos, ss: pila ; poner direccj-ón de retorno al Dos en Ia pi-]a push ds sub ax,ax push ax i direccionar segmento de datos con ds mov axrdatos mov ds,ax namFsct t i tufo nameset I i sta , t añadir el-emento rrXrl nAméq.f fifuloa ; escribir tj-tulo ; escribir l-ista ; escribir tituloa 683 Iingesb lista,n, nama<cf I i sl¿ i ; elininar rAr, rXl el-emento rretl +r+rr'lña L Pa¡"e-e : eqerihir cmp error,L t ¿error? tituloe limgesb 1ista,ñ,'E','e',,error -'i no l-r i ana pamescc mensa bi-ene: nameset I i sta i ; modifÍcar elemento nptt por rtPrr Pu¡"uJv Damesct u tit..'^* . ^---;-{, cmp error,l ; ¿error? lirngesb Lj-sta,D,'M','p',' ina hi onn hanéscf ménSa bienm: ; nameset I i sta ret r l--^^L ! ryYe-! E¡ ^ñah¡uP i ¡nA i ¡n onÁc end lipgesb 684 *ituLorn P',error ; volver al DOS 33 Programas res¡dentes La interrupción DOS 27h Una de las rutinas de servicio más interesantes del DOS es la que corresponde a la interrupción 27h. Como la interrupción 20h, sirve para parar la ejecución del programa en curso y devolver el control al DOS. Pero además permite que una porción del programa permanezca en memoria (se dice que se queda "residente"). El DOS registra la primera posición libre (en frontera de párrafo) siguiente al programa residente para la carga de los programas sucesivos. La información que se queda en la memoria se convierte, de esta forma, en una extensión del DOS. Esta información puede ser código ejecutable y/o datos. Por ejemplo, rutinas de manejo de interrupciones, rutinas de intercepción del teclado, datos de comunicación entre programas, etcétera. La información que se deja residente permanece en memoria mientras el DOS esté funcionando. Antes de que se ejecute la interrupción 27h, el registro DX debe contener el desplazamiento respecto al segmento de la posición siguiente a la última que se quiere dejar residente. El tamaño máximo de la información que se puede dejar residente es de 64 Kb. Un programa que utiliza esta técnica tiene normalmente dos partes: o La parte de instalación de la información a dejar residente. o La información que se va a dejar residente. 685 Vamos a ver a continuación dos ejemplos. En el primero, se instala una rutina y su dirección se almacena en el área de comunicaciones entre aplicaciones. En el segundo, se instala una rutina de servicio de una interrupción. Instalación de una rutina ; ; Esquema de instalación de una rutina cuya dirección se sitúa en el ; área de comunicaciones entre aplicaciones (dirección 0:4F0h). t :- - - - i segmento para acceso al áreade comunicaciones entre aplicaciones ; ------------ SECCPNO SEGMENT AT OH ORG DES-RUT DW SEG-RUT DW SEGCERO ENDS 4F0H : área de comunicaciones entre ; aplicaciones ? ; dirección rutina: desplazamiento ? ; dirección rutina: segmento ;- - - - ; parámetros: PARAMS STRUC DW ? ; BP salvado por la subrutina ? : dirección de retorno DD ? ; dirección parámetro N DD ? ; dirección parámetro I RETORNO DD PN Pl PARAMS ENDS CODIGO SEGMENT ASSUME CS:CODIGO EMPEZAR: , 686 ORG 100H ; por ser tipo COM JMP INSTALAR : bifurca a la rutina de ; instalación : definición de variables rutina a instalar UTINA PROC NEAR PUSH BP MOV BP,SP ; comienzo procedimiento ; salvar BP ; BP : SP (apuntar al área de ; parámetros) salvar registros afectados PUSH... instrucciones de la rutina restaurar registros afectados POP MOV SP,BP POP BP ; SP: BP : restaurar BP RET NRET RUTINA ENDP ;---: instalación ; -------------- ; almacena la dirección de la rutina en el área de comunicaciones entre ; aplicaciones. ; deja residente la rutina. INSTALAR PROC 687 i direccionar segmento SEGCERO con el registro ES ASSUME ES:SEGCERO ; MOV AX,O ; AX:0 MOV ES,AX I ES :0 ; poner dirección de la subrutina en el área de comunicaciones entre ; aplicaciones MOV DES-IUT,OFFSET RUTINA ;desplazamiento MOV SEG-RUT,CS ;segmento ; terminar rutina de instalación, pero dejar residente la rutina MOV DX.OFFSET INSTALAR I DX: última dirección+lrespectoal segmento de la rutina a instalar INT 27}l ; terminar, pero dejar residente INSTALAR ENDP , CODIGO ENDS END EMPEZAR lnstalación de una rutina de servicio de una interrupción Esquema de instalación de una rutina de servicio de una interrupción (de número NRO_INT) segmento correspondiente a los vectores de interrupción INTERRS SEGMENT AT OH ORG NRO_INT x 4 DIREC LABEL DWORD INTERRS ENDS 688 ; dirección rutina de servicio , ; segmento principa. ; -----------CODIGO SEGMENT ASSUME CS:CODIGO,DS:CODIGO EMPEZAR: ORG l00H JMP INSTALAR ; bifurca a la rutina de ; origen por ser fichero tipo ; COM : instalación , , ; definición de variables , ; ; rutina de servicio , RUTINA PROC CLI ; inhibir interrupciones t ; salvar registros afectados ; PUSH... , ; instrucciones de la rutina , ; restaurar registros afectados ; POP... STI IRET RUTINA ENDP ; permitir interrupciones ; una interrupción debe terminar con IRET : 689 : instalación : -------------; almacena la dirección de la rutina en el vector de interrupción y ; deja residente la rutina. INSTALAR PROC ; direccionar segmento de vectores de interrupciones con ES ASSUME ES:INTERRS MOV AX,O MOV ES.AX ; AX: 0 : ES :0 ; poner en el vector de interrupción la dirección de la rutina CLI ; inhibir interrupciones MOV DIREC,OFFSET RUTINA ; desplazamiento MOV DIREC + 2.CS ; segmento ; ; terminar rutina de instalación, pero dejar residente la rutina MOV DX.OFFSET INSTALAR ; DX : última ; dirección + I ; respecto de la ; rutina de STI INT 27F{ I NST ALAR ENDP ; interrupción permitir interrupciones ; ; terminar, pero dejar residente ; CODIGO ENDS END EMPEZAR La función DOS 31h (interrupción 21hl Es una función avanzada que sirve también para terminar y dejar residente un programa. Pero además: o Permite reportar un código de retorno en AL. o Supera la limitación de las 64 Kb de la interrupción 27h. En DX se especifica la cantidad de memoria (en párrafos) que debe permanecer. El resto se libera. 690 Aplicaciones Programas: Instalación de rutina residente para captura de pantallas de texto. Cada vez que se pulsa Alt-P (símbolo "tecla-acción"), se salva en disco los 80 x25:2000 caracteres de Ia pantalla sobre el fichero de nombre "PANTALLA". Si el fichero no existe, lo crea. Si existe, añade la información capturada a continuación. REPRELOJ . Instalación de rutina residente para escribir la hora en la esquina superior derecha de la pantalla. Hace uso de la interrupción lCh (tic del temporizadot), que se produce 18,2 veces por segundo. La hora se calcula a partir del contador del temporizador, que se encuentra en las palabras 40h:6Ch (inferior) y 40h:6Eh (superior). REPCAP 691 REPCAP.ASM , P.og.u.., REPCAP. ; Descripción: ; Instal-ación de rutina residente para captura de pantaflas ; de texto. ; Debe convertirse en fichero tipo COM a través de EXE2BIN. t Sí*boIo", pantaffa f¿nrr r¡nia¡ xpan ypan nbytes equ 0b800h ^^u 190Oh equ BO equ 25 equ xpan*ypan ; segmento rnenoria de pantalla t Alt-P ; nro. de columnas ; nro. de fil-as ; nro. de bytes a grabar ; Macros: rr-L include fimabrir.asm inc]ude fimcrea.asm incl-ude fimcerr.asm inc]ude f irngrab. asm include f irnpunt. asrn incl-ude pamcur. as¡n j-ncl-ude pamcurl- . asm incl-ude vimest.. asm endif ; ; segmento correspondiente a 1os vectores de interrupción del BIOS ; j.nterrupcs segment at 0h org th*4 tec]ado_int label- dword interrupcs ; ends ; dirección de 1a rutina de ; i-nterrupción de teclado ---------- ; segmento correspondiente al área de datos del- BIOS: teclado datos_bios segment at 40h head org dw ? tail dI4/ ? buffer buffer end datos_Fios ; dr¡¡ labe1 l-ah 1a cabeza deL buffer de teclado ¡ puntero a rr rr COl"a rr rt tr il rl : L6 dup (?) t buffer de tecLado ü/ord ends ---------- i segnento principal- ; --------- codigo segrment assume cs:codiqo org jmp empezar: t 692 ---------- 100h instafar ; origen por ser fichero tj-po coM ; bifurca a la rutina de inicial-ización ; . \ra7iAFIó< ant_teclado_int dd xdb? ydb? xant v antpag modo db db db db registro handl-e effor fichero nbytes2 db ? ? ? ? nbytes dup (' t) d\^¡ o 0 db lh-h+állrl d1¡ ? n dr^t direc. interrup. teclado anterior desplazamiento y segmento nro. co1. pantalla (0 a 79) nro. fiLa pantal-la (0 a 24) nro. coI. anterior nro. fifa anterior página activa rnodo vÍdeo 0 - al-fanunérico (4ox25) L,2,3 - alfanurnérico (8ox25) 4,5,6 - gráfico reqistro a grabar fil,e handle indicador error cadena asciiz nombre fichero a crear nro. de bytes grabados i nueva rutina de intérrupción de teclado nue teclado int proc near assume cs: codi-qo push ax push bx push cx push dx push di push si push ds push es pushf ; salvar registros ; salvar banderas t llanada a l-a rutina de ; interrupción anterÍor ; direccionar segrnento datos_bios con ds call ant_teclado_int assume ds3datos bÍos mov axrdatos bios mov ds,ax ; expl-oración buffer de teclado mov bxrtail cmp bx,head je fin_nue ; bx apunta a la col-a . r t^^h62^ ¿vq!ves = ¡a1a? ; si ... blfurcar ; (no existe carácter en el buffer) proceso carácter de1 buffer de teclado bx apunta al- carácter introducido sub bxr2 cmp bx, offset buffer ¿fin del buffer ? j ae no_r{rap no, bifurcar a no-l¡rap si ... ini-cio de buffer mov bx,offset buffer_end carácter en dx no_$/rap: mov dx, [bx] cmp dx tecl-a accl,on ¿es tecl"a de acci-ón? ' no ... bifurcar j"é fin-nue 693 ; carácter = tecl_a de acción ; si ... borrarl-o del buffer +r'i I h -*--, -x cafl- proceso : Iaor ñáñ+^lIr ; salida de la rutina de interrupción de teclado fin_nue: ; restaurar regi-stros Pop es pop ds pop si pop djpop dx pop cx pop bx pop ax iret ; una interrupción necesita iret nue_tecfado_int endp ; proceso ; ------yr ve ; i hacer ds = cs push cs pop ds ; chequeo modo def vídeo y obtener página activa vimest modorpag cmp modo,3 ; ¿nodo alfanumérico? jS fin_pro i no ... bifurcar t ; Ieer posición actual de1 cursor pamcurl x_ant,y_ant . I ^^- i Ldrrd Pqrt cál I I éérh^n i i qrabar fichero call- accion ; restaurar fin_pro: proceso posición de1 cursor pamcur x antry ant ró+ endp l-ectura de 1a ¡nernoria de pantaffa salida: registro : caracteres de 1a nemoria de pantalla 694 i Leerpan proc i direccionar segmento memoria de pantalla con es mov axrpantalla mov es,ax mov si,o ; despl-azamiento sobre fa memoria pantalla mov di,o t desplazamiento sobre registro mov y,0 t fila 0 t bucle fifas mov x,0 ; coL. 0 ; bucle cols. bucle_x: ; posicionar cursor en (xry) i car = carácter de1 buffer t añadir carácter a1 registro pamcur x,y mov af,es:[si] mov registro[di],aI inc di add sí,2 ,' insertar carácter en registro tdi=di+1 ; si = si + 2 (siguiente carácter) ; chequeo fin bucle columnas i-nc x ;x=x+1 cmp x,xpan t ¿fin col-s.? ih hrrclé x t i chequeo fin bucle filas inc y cmp YrYPan ih i 'I Á6rñ^h ; ; l-¡r¡1 a - ----_v , y=y+1 ; ¿fin filas? ret óñ.1ñ ---------- i acci.ón sobre e1 fichero i --------accion proc ; abrir fichero con acceso 1" (grabar) abrir: firnabrir fichero, 1, handle, error ; abrir eI fichero cnp er].ol-, O ; ¿existe ef fichero? jne crear ; no ... crearlo i posicionar puntero a1 final" del fichero finpunt handle,error cmp errorr0 t ¿error? je grabar ; no ... bifurcar 695 ; ; crear ef fichero con atributo O (Iectura/escrítura) ; crear : fimcrea fichero, o,handle, error cmp error,0 ; ¿error? jne fin_acc ; si ... bifurcar i ; grabar registro grabar: fingrab handle, nbytes, registro, nbytes2, error cmp error,0 ; ¿error? jne fin_acc ; si ... bifurcar ; cerrar e1 fichero cerrar : fi¡ncerr handle,error fin_acc: accron endp ; t ---------- ---------; instalación ; ----------j-nstalar proc near ; direccionar segnento interrupcs con es assune es:interruocs nov ax, interrupc-s mov es,ax i salvar dirección de la rutina de interrupción de tecladó actual mov ax,teclado_int i ax = despl. rutina teclado actual rnov ant tecfado_intrax ; salvar desplazamiento mov ax,Eeclado_fnt[2] i ax = segn. rutina teclado actual mov ant_teclado_int[2],ax ; salvar segrnento ; poner dirección de la nueva rutina de interrupción de teclado mov teclado_introffset nue_teclado_int ; desplazamiento rnov tecl-ado_int 12) , cs ; segrnento ; terminar rutina de inicialización, pero dejar residente la rutina ; de interrupción de tecl"ado mov dx,offsét instalar ; dx = últirna dirección + l- respecto ; a1 segmento de la rutina de ; interrupción int 27}j i terminar, pero quedar residente instalar endp ; ---------- codigo 696 ends end emDezar REPRELOJ.ASM ; Programa: REPRELoJ. ; Descripción: ; rnstá1ación de rutina residente para escribir la hora en la esquina superior derecha de ]a pantalla. i , E1 ternporizador (tirner) emite una interrupción tipo l-Ch con la frecuencia f = fI9318o/65536 = 18.20648). veces/segi r Por rninuto: f x 60 = IO92 ; Por hora : Lo92 x 60 = 65543 : 32760 x 2 r Símbo1os3 pantalla equ obSooh ; segrnento ¡nemorj-a de pantalla ---------- t ; segrnento correspondiente a los vectores de interrupción del BIOS ; --------- interrs segment at 0h org l-ch*4 direc label- dword i-nterrs ends ; ; dirección rutina reloj ---------- ; segmento principal ¡ --------- codigo segment empezar: org jmp assume cs:codigo,ds:codigo looh instalar ; origen por ser fichero tipo coM ; bifurca a l-a rutina de inicialización i variables h^r^ dh I ¡lrrn lr2r\ i hora en formato hh:mm:ss ; . r,r+in¡ reloj ral¡i proc ; inhibir interrupciones c1i ; restaurar registros push ax hrrch nrrch n,r<h nrrch hv ¡v ¿lv qi push di nrrch dq push es ; i obtener hora d.e las pa]abras 4oh:6ch (inferior) y 4oh:6eh (superior) 697 mov ax,40h mov esrax mov si,6ch mov axres: [si] mov dx,es: Isi+2] nov bx,32771_ div bx shr ax,1 nov ch,al i dx = resto, ax = horas*2 i ax = horas (dividir entre 2) ; ch = horas mov axrdx mov dxr 0 mov bx,L092 div bx mov c1,al i dx = resto, ax = minutos i c] = minutos ; segmento ; despl-azaniento ; parte inferior contador ; parte superior contador mov ax,dx mov dx,0 mov bx,l-8 dj-v bx i dx = resto, ax : segundos mov dh,al ; dh = segundos poner l-a hora en formato decirnal- sobre campo hora ; nov bh,1o , bh : 10 (constante) mov ah,O i ah = 0 mov al,ch ; ax = horas div bh ; ax = horas en decinal add ax,3030h nov \^¡ord ptr horarax ; ¡nover mov hora+2, r: I mov ah,o mov alrcldiv hh add axr 3030h mov v/ord ptr hora+3,ax mov hora+s, r: I ; ah = O ; ax = ¡ninutos ; ax = minutos en deci¡naL mov ah,o mov al,dh div bh add ax,3030h mov word ptr hora+6,ax ¡nov hora+8,r:l ; ah = O ; dh = segundos ; ax = segundos en decirnal nov ahro nov al-,dl div bh add ax,3030h mov h/ord ptr hora+g,ax ; nover ; mover ; ah = 0 t dl = centésinas ; ax = segund.os en decimaL ; mover i direccionar zona némoria de pantaffa con es: [di] nov ax,pantafla mov esrax mov di,2*(80 - length hora) i mover la hora mov cx,length hora mov si,o 698 i desplazamiento inicial mover: nov al,horalsi] mov es:[di],at inc di mov byte ptr es:[di],07h inc si inc di ; carácter canpo hora i moverlo a memoria de pantal-]a ; mover atributo norrnal 1-oop rnover ; restaurar registros f i-n: pop es pop ds pop di pop s j. pop dx pop cx pop bx pop ax sti iret reloj ; endp ; permitir interrupciones i una interrupción debe terminar con iret ---------- i instalación ; ----------'i ne+r'l i ; direccionar segmento de vectores de interrupciones con es assume es:interrs mov axro i ax = 0 mOV es,ax i eS = 0 ; poner en el vector Lch = 28 Ia dirección de 1a rutina reloj cLi mov direc,offset nov direc+2rcs ; inhibir interrupciones ; desplazarniento ; segmento t terminar rutina de instalación, pero dejar residente l-a rutina nov dx,offset instalar i dx = últina dirección + 1 respecto ; al segmento de la rutina de ; interrupción sti ; pernitir interruPciones int 27h, ; terminar, pero dejar residente 'i net¡ l ¡r reloj on¡ln ; i ---------¡n^ i ¡a óhA< pnd émnaz^¡. 699 Varios En este capítulo se incluyen otros temas no recogidos en los capítulos anteriores, principalmente las funciones DOS no asociadas a dispositivos de entrada/salida. Otras funciones DOS (interrupción 21hl FECHA Y HORA AI{ Función Obtener fecha. Salida: CX : Año (1980-2099). DH : Mes (1-12). DL : Dia (l-31). zBh Poner fecha. Entrada: CX : Año (1980-2099). DH : Mes (1-12). DL : Día (l-31). Salida: AL :0 si no error. AL : FFh si error. 700 2Ch Obtener hora. Salida: CH : Hora (0-23). CL : Minutos (0-59). DH = Segundos (0-59). DL : Centésimas de segundo (0-99). zDh Poner hora. Entrada: CH : Hora (0-23). CL : Minutos (0-59). DH: Segundos (0-59). DL : Centésimas de segundo (0-99). :0 si no error. AL Salida: AL : FFh si error. GESTION DE MEMORIA AH Función 48h Ubicar bloque de memoria. Entrada: BX : tamaño del bloque, en párrafos. Salida: si CF: 1, AX : número del error. AX:0: dirección del bloque de memoria. BX : máximo tamaño posible del bloque de memoria (en párrafos), si error. 49h Liberar bloque de memoria. Entrada: ES : segmento del bloque de memoria. Salida: si CF: l, AX : número del error. 4Ah Modificar los bloques de memoria ubicados. Entrada: ES : segmento del bloque de memoria. BX : nuevo tamaño del bloque, en párrafos. Salida: si CF: l. AX: número del error. BX : máximo tamaño posible del bloque de memoria (en párrafos), si error. 701 CARGA Y EJECUCION DE PROGRAMAS AH Función 4Bh Cargar o ejecutar un programa. Entrada: AL : modo: 0 - cargaryejecutar. 3 - cargar sólo sin crear PSP (prefijo de segmento de programa). DS:DX : dirección cadena ASCIIZ con la unidad, sendero y nombre del fichero a car9ar. ES:BX : dirección bloque de parámetros. Es necesario liberar memoria antes de cargar el programa (mediante la función 4Ah), pues al programa llamador (padre) le fue asignada toda la memoria disponible por el DOS. Las funciones de carga y ejecución de programas destruyen la mayoría de los registros, incluyendo el SS y el SP. Deben, pues, preservarse antes de invocar a la función y restaurarse después. obviamente, no puede utilizarse la pila. Normalmente, un programa es invocado por el intérprete de comandos del DOS (COMMAND.COM) y a él retorna cuando acaba el programa. Sin embargo, un programa (digamos PROGI) puede hacer que se ejecute otro programa (digamos PROG2) y eue, cuando termine, devuelva el control al programa llamador PROGI (o programa padre), que continúa su ejecución. El programa VAPEXE es un ejemplo de llamada a otro programa. Para ello, hay que hacer los pasos siguientes: o El programa a ejecutar hay que definirlo como cadena ASCIZ. Ejemplos de programas a ejecutar son: A:/COMMAND.COM FIPLISTA.EXE o Es necesario salvar los registros BP, SP y SS en el segmento de datos (y no en la pila) y recuperarlos después. Para poderlos recuperar del segmento de datos hay que volver a direccionar el segmento de datos con DS (pues este registro se destruye). . Hay que liberar parte de la memoria para que el programa llamado pueda cargarse. Cuando el DOS carga un programa en memoria, le asigna toda la memoria disponible. Hay que utilizar la función 4Ah para modificar el bloque de memoria asignado al programa padre. En el ejemplo, la nueva longitud es de 4.000 párrafos :64.000 bytes. r Los parámetros a pasar al programa deben contener en el primer byte el número de caracteres y deben ser seguidos por un retorno de carro (13 :0Dh). 702 Ejemplos de parámetros son: /C DIR/W VAPEXE.ASM o Hay que construir el bloque de parámetros siguiente: Pl P2 P3 P4 DW 0 DD 0 DD 0 DD 0 ; indica que el retorno es el del proceso padre ; dirección parámetro 2 ; dirección parámetro 3 ; dirección parámetro 4 En P2 hay que guardar la dirección completa del área de parámetros. Este bloque de parámetros se apunta con ES:BX. ¡ Para cargar y ejecutar le programa se invoca a la función 4Bh con AL:0. Aplicaciones Programas: VAPALMA - Ilustra el modo de almacenamiento de números binarios. VAPBOOT - Carga del sistema (boot). VAPEXE - Carga y ejecución de un programa. 703 VAPALMA.ASM ; ; Prograna: VAPALMA. ; Descripción: ; Ilustra e]- modo de alnacenam.iento de núrneros binarios. ,' sÍmbol-os: cr equ 1"3 ; retorno de carro l-f equ l-0 ; alimentación de Linea ; Procedi¡nientos externos: extrn pastexto: far ; Macros: if rinclude co¡nashx.asn include comcrhx.asm endif ; ---------- pila pila i segment stack db ends l2a dup ('pila' ) datos segment nrol nro2 nro4 nroS db ol-h i nro. binario dhr 0123h i nro. binario dd 0]-234567}] i nro. binario dq OI234567A9ABCDEFh i nro. binario Ah hexlhex2 hex4 hexS datos ^r l€ roi --> ' 2 dup(?) i caracteres hexadecimales de nrol cr,lf,crrl-f 10123 --> | dup(?) i caracteres hexadecimales de nro2 cr r]-f rcr,If I 0].234567 --> | 8 dup(?) i caracteres hexadecirnales de nro4 cr,l-f,cr,1f t0!23456789A8CDEF --> , l-6 dup(?) i caracteres hexadecinal-es de nroS lf lf ^r ^r ^h db ,$, db db db db db db db db db db db ends codigo segment vapalma proc far assume cs: codigo, ds:datos, ss:Pila ; poner dirección de retorno al, DOS en 1a pifa Push ds sub axrax push ax 704 en byte en palabra en dobl-e palabra en cuádruple palabra t direccionar segrnento de datos con ds mov axrdatos mov dsrax ; convertir a hexadecimaL comashx nrol-, 1, hexl- comashx nt.o2r2,})ex2 comashx nro4r4rhex4 conashx nro8r8,hex8 ; escribir nros. binarios y sus correspondientes hexadecimales push ds fea ax,mensa push ax cal-L pastexto ; volver al DOS f in: ret r¡¡na 1n¡ áñdñ ; codigo ends end vapaLma 7É VAPBOOT.ASM Programa: VAPBooT. Descripción: carga del- sistena (boot). Parámetros: /T - Lo nismo que la operación de teclado ALt-ctrL-Del. /B - Mediante interrupción BIoS 19h. ; ---------- i segmento rrpowér onrl prrron segment at offffh reset labe1 far p\^/ron ends ; segmento área de datos del- BIoS datosb segnent at 40h db 72h dup(?) ireset di r ? ¡ l-234h si reset por teclado datosb ends ; ---------- codigo vapboot segment proc far assume cs:codigo ; poner dirección de retorno al- Dos en Ia piJ.a push ds sub axrax push ax ; ver eI parárnetro mov si,82h cmp byte ptr je teclado cmp byte ptr je teclado crnp byte ptr je bios cnp byte ptr je bios ; apuntar aI área de parámetros del PsP [si],rtl [si],rTl [si],rbl [si],rBl ; retornar al- Dos i direccionar segmento área dé datos de1 BIos con es 16t i teclado: assune es:datosb mov axrdatosb mov esrax mov bx,l234h mov es: iresetrbx jmp reset 706 .' i.ndj-ca reset por teclado ; bifurcar a reset i leer sector 1 de 1a pista O y transferir e1 control bios: int l-9h i l-lamar a1 BIOS vapboot endp codigo ends end vapboot 707 VAPEXE.ASM i Programa: VAPEXE. ; Descripción: i carga y ejecución de un programa. i Símbolos: cr equ l-3 lf equ 1-0 ; i retorno de carro r alimentación de linea ---------- pila pil-a seglnent stack db ends Iza dup (rpilar) i datos segment bpx spx ssx dw d\,¿ dl^r ; bp salvado i sp salvado ; ss sal-vado ; cadena asciiz con eI nombré del- prograna a ejecutar ;programa db ra:\comnand.comr,O ; <=== PRoGRAMA A EJECUTAR programa db rfiplista.exer,0 i <=== PROGRAMA A EJECUTAR ; parárnetros a pasar al programa ; (e1 priner byte contiene el núnero de caracteres) param db paramcr-param-L i núnero de caracteres deI parámetro db | /c dtr/wt r i <=== PARAMETROS DEL PROGRAMA db 'vapexe.asm' i <=== PARAMETROS DEL PROGRAMA paramcr db cr ; mensales mensal db r... mensa2 db r... mensa3 db '... mensa4 db t... mensae db t*** de ¡nodificar Ia memoriat,crrffrt$t }a menoriat,crtlf,t$t antes de ejecutar e1 programar rcr'l-f, r$l después de ejecutar e1 programar,cr,lf,r$r antes después de nodificar error al modificar l-a memoria ***r,cr,Ifr,$' ; bloque de parámetros p1 dv/ o ; dirección deI segrnento de la cadena de1 entorno ; (environment) a Pasar ; (0 indica que es el nismo que el del proceso padre) p2 dd 0 ; dirección par. 2 p3 dd 0 ; direccj-ón par. 3 p4 dd o i dirección par. 4 datos ends codigo ségment Para vapexe proc far assune cs : codigo , ds : datos , es : nothing, ss : pila 708 poner en la pila la dirección de retorno a] DOS push ds sub ax,ax push ax salvar ds = dirección del segrnento donde comienza eL PSP det prograna push ds direccionar segmento datos con ds rnov ax, datos mov ds,ax salvar registros mov bpxrbp mov spx, sp mov ssx, ss mensaje antes de ¡nodificar 1a rnenoria mov axrseg mov dsrax mov dx,offset mensal- mensal t ds:dx apunta al rnensaje t función: escribir texto int 21h i llamada a1 DOS t ¡nodificar J-os bloques de memoria afocad.os pop es i es = dirección del segnento def programa ; (bloque de rnenoria) mov bx,4000 i bx = nuevo tamaño del bloque, en párrafos i un párrafo = l-6 bytes t 4000 párrafos = 4000*16 = 64000 bytes mov ah,4ah t función: setblock mov alr 0 int 21h ; l-fanada aI DOS mov ah.09h i ; chequeo error (errores posibles? 7 | I y 9) cmp axrT je error cmp axrS je error cmp ax,9 jne bien ; mensaje de error error: mov ax, seg mensae nov dsrax nov dxroffset mensae mov ah,09h int 2l-h jnp fin ; dssdx apunta al mensaje ; función: escribir texto r llamada al DOS ; mensaje después de rnodificar la memorj.a : 709 bien: nov axrseg mov ds,ax mov dx,offset mov ah,09h mensa2 mensa2 i ds:dx apunta al rnensaje ; función: escribj-r texto ; llarnada al Dos int 2l-h ; nensaje antes de ejecución móv axrseg mensa3 rnov ds, ax mov dxroffset mensa3 i ds:dx apunta a1 mensaje mov ah,09h i función: escribir texto int 21h ; llamada aI Dos i direccionar nornbre del prograrna a ejecutar con ds:dx mov dx,offset prograna i ; construir bloque de parárnetros *^r, ^aápararn ; p2 = dirección de paran ¡trvv -ay¿,-..set mov p2+2rseg param ; apuntar bloque de parámetros con es:bx mov ax, seg pl; ax = data segment de p1 mov es,ax i es = data segment de plmov bx, offset pL i bx = offset de p]i cargar y ejecutar programa mov ah,4bh i función: cargar o ejecutar un programa nov a1,0 t función: cargar y ejecutar programa int 21h r llanada aI DoS ; rnensaje después de ejecución mov axrseg mensa4 mov dsrax mov dxroffset mov ah,09h int 21h nensa4 i ds:dx apunta a1 rnensaje ; función: escribir texto ; Ilanada a1 DoS ; direccionar segnento datos con ds fin: mov axrdatos mov dsrax ; restaurar registros mov bp,bpx mov sprspx mov ss,ssx i cuando se salvó sp sobre spx, se había puesto sobre la pila i regj-stro ds, por tanto, saltarfo add sP,2 ; retorno al- DOS 710 e1 rói vapexe endp i d^ 6hr¡ < ^^A end vapexe 711 Interf az con lengua¡es de alto nlvel Ya hemos mencionado que, normalmente, la vía más adecuada para el desarrollo de programas es a través de un lenguaje de alto nivel (BASIC, PASCAL, C, FORTRAN, COBOL, etc.). La utilización de ensamblador está justificada: o Cuando se desea realizar cierta función no soportada por el lenguaje de alto nivel e incluirla en el repertorio del lenguaje. o Cuando se desea mejorar la velocidad de ejecución de una función implementada en un lenguaje de alto nivel. La mayoría de los lenguajes de alto nivel soportan la llamada a módulos ensamblador. Por tanto, es posible desarrollar programas hibridos que utilicen los recursos de ambos tipos de lenguajes. En la comunicación lenguaje de alto nivel-ensamblador intervienen tres elementos: o El módulo llamador. o El módulo llamado. r El interfaz de comunicación entre ambos. 712 El interfaz El interfaz es lo que hace posible que un programa escrito en un lenguaje de alto nivel se pueda comunicar con un módulo ensamblador. Existen dos partes o aspectos del interfaz: c El interfaz de control. o El interfaz de datos. l. El interfaz de control. corresponde a la llamada a la subrutina y al retorno desde ésta. a) La llamada. Respecto a la llamada, casi todos los lenguajes de alto nivel disponen de una sentencia CALL, en la que pueden especificarse opcionalmente una serie de parámetros. La llamada puede ser: NEAR (dentro del segmento de código) o FAR (a otro segmento distinto). En el primer caso, sólo se transmite el desplazamiento, y en el segundo, la dirección completa (segniento y desplazamiento). b) El retorno. Se realiza vía instrucción RET. Puesto que normalmente los parámetros se pasan a través de la pila, hay que especificar un argumento en RET que hace que se restaure el puntero de la pila antes de devolver el control. Si se especifica un valor erróneo, el programa se queda ,,colgado". En algunos lenguajes esta restauración del puntero de pila la realiza el propio módulo llamador. 2. El interfoz de datos. Corresponde a los datos que se manejan y conocen a ambos lados del interfaz. Los datos residen en memoria, no se utilizan registros. Existen muchas maneras de pasar información de un módulo a otro, pero la forma más segura y flexible es mediante la colocación de los argumentos sobre la pila. Otros tipos de interfaz de datos son: o Mediante CCMMON, que es un área de memoria accesible por ambos módulos (BASIC, FORTRAN). . Mediante variables declaradas PUBLIC (PASCAL), que permiten al módulo ensamblador acceder al contenido por el nombre, mecanismo idéntico al existente entre módulos ensamblador. o Haciendo "POKE" (BASIC) en direcciones específicas de memoria para su posterior utilización por parte del módulo ensamblador. 713 Los parámetros El paso de los parámetros sobre la pila puede hacerse de dos maneras: o Directa. Se pasa el valor. o Indirecta (o por referencia). Se pasa la dirección' El tipo de método utilizado depende del lenguaje.. Algunos lenguajes permiten pasar valores, casi todos permiten pasar direcciones y otros permiten ambos sistemas' Este último caso nos permite elegir uno u otro método, ¿Cuál debemos utilizar? En el caso de que la subrutina cambie el parámetro, estamos obligados a utilizar la dirección (método indirecto). Si el parámetro no va a ser modificado, podría pasarse el valor (método directo)' Los reg¡stros En general, puede decirse que: CS: apunta al segmento de código del módulo llamador. SS y SP: corresponden a la pila del módulo llamador. DS y/o ES: apuntan al segmento de datos del módulo llamador. Se deben preservar los registros utilizados salvándolos sobre la pila y recuperarlos antes de devolver el control (con RET) al módulo llamador. La pila La subrutina llamada puede usar la pila del módulo llamador, pero no existe manera de saber el espacio disponible. Si lo que se necesita es razo- nable (menos de 32 palabras), normalmente debería ser suficiente. Si se necesita más espacio, la subrutina llamada debe reservar su propio espacio en memoria. 714 Interf az con intérprete de BASIC La comunicación entre el intérprete de BASIC y un módulo ensamblador se realiza vía sentencia CALL del BASIC: CALL nombre_subrutina(argumento I ,argumento2, . . .) Las características de esta comunicación son: ¡ Los parámetros son opcionales. Si existen, deben de corresponder en número y tipo con los del ensamblador. o El control se transfiere a la dirección: segmento: el último especificado en DEF SEC. desplazamiento: el especificado en CALL. o La llamada es de tipo FAR, es decir, se guarda sobre la pila la dirección completa de retorno (segmento y desplazamiento). El procedimiento principal de la subrutina ensamblador debe ser también FAR. o El paso de argumentos en la llamada es mediante los desplazamientos (offsetl de cada variable. o Para las variables tipo cadena de caracteres, el desplazamiento corresponde al descriptor de la cadena. Este descriptor tiene la estructura siguiente: 715 byte I - longitud de la cadena (0 a 255). bytes 2 y 3 - desplazamiento (offset) de la cadena. En el compilador BASIC, la longitud de la cadena es de 2 b¡es. Cuando se recoge un parámetro de este tipo dentro de la subrutina ensamblador, es conveniente prepararla para que se pueda utilizar en ambos entornos de programación. o En el módulo ensamblador la instrucción de retorno debe ser RET n, siendo n:2* número de parámetros. o Los registros ES, CS y DS apuntan inicialmente al comienzo del segmento del BASIC. El registro CS se actualizacadavez que se ejecuta una sentencia DEF SEG del BASIC. o Los datos dentro del segmento del BASIC están direccionados mediante el registro de segmento DS. El intérprete de BASIC utiliza un área máxima de 64K bytes (la longitud máxima de un segmento) en el que residen el programa, los datos y la pila. Este segmento no se ubica siempre en la misma dirección. La dirección de este segmento se encuentra en la palabra 0:510h, es decir, en los bytes 0:510h (inferior) y 0:5llh (superior). Respecto a su tamaño, por defecto es de 64K bytes, pero puede modificarse mediante: ¡ La sentencia CLEAR del BASIC: CLEAR ,longitud-segmento Por ejemplo, CLEAR ,32768. Longitud :32K. o La opción M del comando BASIC: BASlC/M:longitud-segmento Por ejemplo, BASIC/M:32768. Longitud = 32K. Las subrutinas en código de máquina pueden situarse: o Dentro del segmento del BASIC. o Fuera del segmento del BASIC. A su vez, existen diferentes métodos para ubicar las subrutinas en lenguaje de máquina. Los más importantes son: ¡ Método POKE. r Método BLOAD. Otra alternativa es instalar las subrutinas y dejarlas residentes. Código dentro del segmento del BASIC El código se almacena dentro de una matriz entera (2 bytes por elemento). El programa BASIC tendría la siguiente forma: 716 100 OPTION BASE 110 DEFINT A-Z 1 r20 , ' subíndice inicial: I ' todas las variables enteras (2 bytes) 130 ' CODIGO = matriz donde se va a guardar el código objeto 140 ' si la longitud (L) del código es par, la dimensión es L/2 150 ' si la longitud es impar, la dimensión es L/2 + | 160' 170 DrM CODTGO (...) 180 L = ... 400' ' longitud del código 410 ' carga del código objeto sobre la matriz CODIGO 420', 430 ... 440 ... 500 ' 510 ' ejecución de la subrutina 520 ', 530 Pl :... ' parámetro I 540 P2: ... ' parámetro 2 550 ... 560 N : VARPTR(CODIGO(I)) ' desplazamiento del primer elem. 570 CALL N (P1,P2,...) ' llamar a la subrutina 580 END Código fuera del segmento del BASIC Con este sistema es posible superar el límite de las 64K. Para direccionar, por ejemplo, el segmento que se encuentra más allá de las 64K, basta con recoger la dirección de comienzo del segmento del BASIC y sumarle el valor: : 4K párrafos = 4 x 1024 párrafos : 4096 párrafos : :4 x 400h párrafos = 1000h párrafos 64 Kbytes Existe un "truco" para asegurarse de que hay suficiente memoria, y consiste en tratar de acceder a la última posición de carga de la subrutina. El programa fuente BASIC tendría la siguiente forma: I ' subíndice inicial: 1 110 DEFINT A-Z ' todas las variables enteras (2 bytes) r20 ' 130 ' obtención de la dirección del segmento del BASIC 100 OPTION BASE 140' 150 DEF SEG:0 ' segmento :0 717 160 NSEG: PEEK(&HS10) + PEEK(&HS11)'t250 ' dirección del 170' ' segmento ' BASIC 180 ' apuntar a la dirección del nuevo segmento : 190 ' dirección segmento BASIC + longitud (en párrafos) segmento BASIC 200' 210 LSEG: ' longitud(enpárrafos)delsegmento BASIC 220 NSEG: NSEG + LSEG ' dirección nuevo segmento 230 DEF SEG: NSEG ' segmento nuevo 240', 250 ' asegurarse de que hay suficiente memoria para almacenar el código 260', 270 L: ... ' longitud del código 280 X + PEEK(L-I) ' leer el último b¡e donde se va a,situar el código 290 POKE L-1,255 ' tratar de cambiar el byte 300 IF PEEK(L-I) -- 255 THEN POKE L-l,X : GOTO 400 ' .restaurar byte 310 PRINT "ERROR: NO HAY SUFICIENTE MEMORIA" : STOP 400' 410 ' carga del código sobre el nuevo segmento 420', 430 ... 440 ... 500' 510 ' ejecución de la subrutina 520', 530 pl : ... ' parámetro I 540 P2: ... ' parámetro 2 550... 560 N : 0 ' desplazamiento en el nuevo segmento (primer byte) 570 CALL N (P1,P2,...) ' llamar a la subrutina 580 END Método POKE Consiste en colocar el código objeto en la memoria mediante sentencias POKE del BASIC. Es adecuado sólo cuando el código a incluir sea relativamente corto. Para ello, hay que ensamblar el módulo fuente y apuntar los códigos generados (en hexadecimal) para insertarlos posteriormente dentro del fuente de BASIC mediante sentencias DATA. 718 Ejemplo: Subrutina ensamblador para hacer hardcopy de pantalla. En este caso no existen parámetros. Instrucción Códiso (hexadecimal) PUSH BP ) salvar BP )) INT interrupción BIOS CDO5 POP RET BP restaurar BP 5D CB retorno FAR La secuencia de b¡es (en hexadecimal) es: 55, CD, 05, 5D, CB. Método BLOAD Consiste en cargar el código objeto de un fichero imagen de memoria mediante la sentencia BLOAD del BASIC. Es el método más utilizado. Un fichero BSAVE del BASIC contiene un prefijo de 7 b¡es: r Un byte con FDh, que indica que este fichero ha sido creado con la sentencia BSAVE. o Una palabra que indica el segmento por defecto de la dirección de carga. o Una palabra que indica el desplazamiento (offset) por defecto de la dirección de carga. o Una palabra que contiene la longitud del fichero. De lo que se trata es de "engañar" al BASIC, incluyendo un prefijo BSAVE en el módulo fuente ensamblador, que se consigue mediante un segmento de 7 bytes. Este prefijo es utilizado por el intérprete de BASIC para cargar (con la sentencia BLOAD). El código que se almacena en memoria viene a continuación de dicho prefijo. El proceso a seguir es: l. Crear el módulo ensamblador con un prefijo BSAVE. 2. Ensamblar el módulo fuente: MASM módulo; 3. Linkeditar el rnódulo objeto: LINK módulo; 4. Crear el fichero imagen de memoria (por ejemplo, tipo BSV): EXE2BIN módulo.EXE módulo.BSV El esquema del módulo fuente ensamblador es el siguiente: ; estructura parámetros ; -----------719 , PARAMS STRUC PN P2 Pl DW ? DD ? DW ? DW ? DW ? PARAMS ENDS ; BP salvado por la subrutina ; dirección de retorno ; dirección parámetro n ; dirección parámetro 2 ; dirección parámetro I prefijo tipo bsave BSAVE SEGMENT DB OFDh ; identificación fichero tipo bsave DW 0 ; segmento Por defecto DW 0 ; desplazamiento Por defecto DW FINAL-COMIENZO ;tamaño (bytes) del ; módulo ENDS BSAVE segmento de código CODIGO SEGMENT BYTE ; el alineamiento tipo byte : es necesario ASSUME CS:CODIGO ; COMTENZO EQU $ =+ comienzo imagen de memoria SUBRUT PROC FAR comienzo procedimiento salvar BP BP : SP (apuntar al área de parámetros) PUSH BP MOV BP,SP ; salvar registros afectados PUSH ... ; recoger parámetros t ; ; proceso 720 MOV SI,[BP].PN ; si : desplazamiento parámetron ; ... t ; restaurar registros afectados POP , MOV SP,BP POP BP RET NRET ; SP : BP ; restaurar BP SUBRUT ENDP ; fin procedimiento Í.nal i + fin imagen de memoria EQU $ CODIGO ENDS END Método POKE dentro del segmento del BASIC Con VARPTR se obtiene el desplazamiento de la matriz respecto al segmento del BASIC. A partir de esa dirección se almacenan los bytes especificados en DATA. Las sentencias BASIC son: 400' 410 ' carga del código objeto sobre la matriz CODIGO 420' 430 DATA &H..,&H.. ' código objeto (en hexadecimal) 440 L: ... ' longitud del código 450 N: VARPTR(CODIGO(I)) ' desplazamiento (offset) del primer elemento 460 FOR I: I TO L ' bucle bytes 470 READ VALOR ' obtener byte sobre VALOR 480 POKE N + I-I.VALOR ' almacenarlo en CODIGO 490 NEXT I Para el ejemplo de hardcopy de pantalla, las sentencias serían: 430 DATA &H55,&HCD,&H05,&H5D,&HCB ' código objeto 440L:5 'loneituddelcódiso 721 Método POKE fuera del segmento del BASIC Los valores especificados en DATA se almacenah sobre el byte inicial del nuevo segmento. Las sentencias BASIC son: 400 , 4I0 ' carga del código objeto sobre el nuevo segmento 420' 430 DATA &H..,&H.. ' código objeto (en hexadecimal) 440 L: ... 450 FOR I: 1 TO L ' longitud del código ' bucle bytes 460 READ VALOR ' obtener b¡e sobre VALOR 470 POKE I- I.VALOR ' almacenarlo 480 NEXT I Método BLOAD dentro del segmento del BASIC Como en el método POKE, se trata de almacenar el fichero imagen de memoria sobre una matriz entera. Con VARPTR se obtiene el desplazamiento de la matriz respecto al segmento del BASIC. Y con BLOAD se carga el fichero en esa dirección. Las sentencias BASIC son: 400' 410 ' carga del código objeto sobre la matriz CODIGO 420', 430 N : VARPTR(CODIGO(1)) ' desplazamiento del primer 440 BLOAD "nombre-fichero",N ' carga del código elemento Método BLOAD fuera del segmento del BASIC En este caso, el fichero imagen de memoria se carga sobre el byte cero del nuevo segmento. Las sentencias BASIC son: 400' 410 ' carga del código objeto sobre el nuevo segmento 420', 430 N = 0 ' desplazamiento en el nuevo segmento (primer b¡e) 440 BLOAD "nombre_fichero",N ' canga del código Método de las subrutinas residentes Las características de este método son: o Las subrutinas se cargan antes de ejecutar el comando BASIC. . El programa BASIC puede invocar a las subrutinas en cualquier momento. o El área donde reside la subrutina está protegida por el DOS. r Diferentes programas pueden hacer uso de las subrutinas residentes. ¡ Las subrutinaJpermanecen en la memoria hasta que se arranque de nuevo el sistema. o El programa BASIC debe saber dónde se encuentra la subrutina para poáerlá invocar. Para ello la subrutina, en el momento de instalarla, debe almacenar su dirección en un área que puede ser el área de comunicaciones entre aplicaciones: 0:4F0h a 0:4FF (16 bytes) La dirección es tipo doble palabra (4 bytes): desplazamiento (primera palabra) y segmento (segunda palabra). bsta direócióñ la recoge el programa BASIC para bifurcar a ella. Para evitar que Se acumulen en la memoria las subrutinas, por ejecuciones sucesivas, puede definirse un fichero BAT que instale las subrutinas, ejecute el comando BASIC con su aplicación y a continuación que ejegyle un programa que rearranque el sistema, o bien que el propio programa BASIC, al terminar, rearranque el sistema. Supongamos que la dirección de la subrutina residente se encuentra en 0:4F0h y áue se desea rearrancar el sistema después de la ejecución. El programa fuente BASIC tendría la siguiente forma: 100 OPTION BASE ll0 DEFINT A-Z 120' I ' subindice inicial: I ' todas las variables enteras (2 bytes) 130 ' obtención de la dirección de la subrutina residente r40' ' segmento = 0 150 DEF SEG :0 160 INI : &H4F0 ' posición donde se encuentra la dirección 170 DESP =PEEK(INI) +PEEK(INI+t¡*256' desplazamiento 180 SEGM :PEEK(INI+2) +PEEK(INI +3)x)56' segmento 190' 500 ' ejecución de la subrutina 510' 520 DEF SEG: SEGM ' segmento ' parámetro I 530 pl :... ' parámetro 2 540 p2: ... 723 550 ... 560 CALL DESP (Pl,P2,...) ' llamar a la subrutina 600' 600 ' rearrancar el sistema 610 ' 620 DEF SEG: &HFFFO ' segmento rutina BIOS de arranque 630 DESP : &HFFFO ' desplazamienro rutina BIOS de 640 CALL DESP 650 END ' rearrancar el sistema arranque Aplicaciones Programas: BIPD.BAS - Ejemplo de llamada a una subrutina ensamblador desde BASIC. Método: BLOAD. Carga de la subrutina dentro del' segmento del BASIC. BIPF.BAS - Ejemplo de llamada a una subrutina ensamblador desde BASIC. Método: BLOAD. Carga de la subrutina fuera del segmento del BASIC. BIPRES.ASM - Instalación de una subrutina para ser utilizada desde un programa BASIC. BIPRESU.BAS - Ejemplo de utilizacion de una subrutina ensamblador residente desde un programa BASIC. Subrutinas: BIS.ASM - Cambiar minúsculas a mayúsculas en una cadena de caracteres BASIC. 724 BI PD. BAS oo2 004 ¡ Programa: BIPD. 006 o1o I Descripción: O2O I Ejernplo de l,l-amada a una subrutina Assembler desde BASfC. 030 | Método: BLOAD. 040 ' Carga de la subrutina dentro de1 segmento del- BASIC. , r 050 | -----060 | 100 oPTIoN BASE 1 110 DEFINT A-Z 't subÍndice inicial- = ltodas las variabLes enteras (2 bytes) r20 130 t matriz donde se va a guardar el código objeto l-40 ' si la longitud (L) del códigto es par, 1a di¡nensión es L/2 150 t si Ia J-ongitud es irnpar, fa dinensión es L/2 + I 160 ' | 170 DrM CODTGO(r-00) 400 | 410 ' carga de] código objeto sobre l-a matriz coDIGo 420 | 43o N : VARPTR(CoDIGO(1)) 440 BLoAD rrBIS.BsVrr,N 500 51o I ejecución de fa subrutina 520 | | desplazarniento de1 priner el-emento I carga deI código r 530 A$ = I'abcdefghijklmnñopqrstuvwxyz0123456'7 89tl 54O PRINT AS 560 N = VARPTR(CoDIGo(L)) | desplazaniento del prirner elemento 570 CALL N (A$) 580 PRINT A$ 590 END | Llamar a 1a subrutina 725 BIPF. BAS 002 | 004 | Programa:BIPF. 006 r 0lOrDescripción: 02O I Ejemplo de llamada a una subrutina Assernbl-er desde BASIC. 030 | Método: BLOAD. | 040 Carga de la subrutina fuera del segmento del BAsIc. 045 | | 050 -----060 | 1-00 OPTION BASE t- | subindice inicial = 1 I todas las variables enteras (2 bytes) l-1,0 DEFINT A-Z L20 | L30 | obtención de l-a dirección de1 segmento de1 BASTC 1_40 | | segmento = O 150 DEF sEG : 0 L60 NSEG : PEEK(&H5l-0) + PEEK(&H511)*256 ' dj,rección del segnento BASIC l-70 t l-80 | apuntar a la dirección de1 nuevo segmento = 19o ' dirección segmento BAsrc + tongitud (en párrafos) segnento BAsrc 200 t 210 LSEG = &H10oo ' longitud (en párrafos) de1 segmento BASIC 220 NSEG : NSEG + LSEG t dirección nuevo segrnento I 230 DEF SEG = NSEG segnento nuevo 240 | | 250 asegurarse de que hay suficiente memoria para almacenar el código 260 | I longitud de1 código 27O L = 2OO 280 X = PEEK(L-1) | leer eL últi¡no byte donde se va a situar el código | tratar de cambiar el- bvte 290 POKE L-L,255 300 IF PEEK(L-]-) = 255 THEN POKE L-l,X : GOTó 4OO I restaurar byte 3].0 PRINT IIERROR: NO HAY SUFICIENTE MEMoRIA'' : sToP 400 | 4l-o I carga del código objeto sobre eI nuevo segmento 420 | I desplazamiento en e1 nuevo segrnento (primer byte) 43o N = o 440 BLOAD rBfS.BsVtr,N I carga del código 500 | 510 | ejecución de la subrutina 520 | 530 A$ = rtabcdefghijklnnñopqrstuw/xyzo1234567agn 540 PRINT AS 560 N : 0 en el nuevo segmento (priner byte) .r desplazamiento | lla¡nar a 1a subrutina 570 CALL N (A$) 580 PRINT AS 590 END 726 BIPRES.ASM Programa: BIPRES. Descripción: Instálación de una subrutina para ser utilizada desde un programa BASIC. i segmento para acceder al área de cornunicaciones entre apl-icaciones segcero segment at 0h 4F0h org ; área de co¡nunicaciones entre aplicaciones ; dirección subrutina: desplazamiento ? des sub d\^¡ ; dirección subrutina: segmento ? seg-sub dw segcero ends i ; *******************************************tk********************t(***** ; Subrutina: BIS. t Descripción: BASIC. ; ca¡nb-iar mj_núscuLas a mayúsculas en una cadena de caracteres ; La subrutina queda prepárada para ser utilizada desde eI cornpilador t de BASIC, según e1 vaLor del- sÍmbolo "tipo-basicrl i Parámetros: params struc ? t bP salvado Por Ia subrutina dw ret d.es d\.¡ ? ; dirección de retorno (desplazaniento) ? ; dirección de retorno (segnento) ret-seg dw pl dt¡/ ? i dirección Parárnetro t (ent/sal) cadena de caracteres deI BASIC params ends 1- ; símbolos: 1 byte) tipo-basic equ L ; 1 - intérprete (carnpo longitud cadena, 2 bytes) t 2 - conpilador (carnpo longitud cadena, equ offset pr - oifset ret-seg i argumento de ret nret ; ---------- codigo segment assume cs:codigo empézar: bis org l-00h jnp instalar proc far push bP mov bprsp ; por ser tipo coM i cornienzo procedimiento i salvar bp ; lp = sp lapuntar al- área de parárnetros) saLvar registros aféctados push ax push cx push si 7n i recoger parámetro mov si, [bp] .pl, ; si = desplazamiento parámetro 1 ife tipo_basic-1si tipo basic = 1 (intéLprete) -; Sout fntérprete de BASrC .^L-^ mov ch,0 mov cI, Isi] ; cx = longitud de l-a cadena else ; si compilador Sout compil-ador BASTC mov cx, Isi] ; cx = longitud de l-a cadena endif cmp cx,0 ; ¿Longitud cadena = O? j1e fin ; si ... fin bucle caracteres de la cadena c mov si, Isi+tipo _basic¡ lodsb cmp aI, ral jb carsig cmp alrt zl ja carsig sub al-,32 t si = desplazarniento cadena ; al- = ds:[si]r si = si + 1 i ¿carácter inferior a rar? i si ... carácter siguiente i ¿carácter superior a tzt? t si ... carácter siguiente ; convertir a rnayúsculas t Por ejenplo, a = 97, A = 65 i al-macenar carácter convertido mov Isi-1],a1 ; carácter siguiente carsig: loop car i restaurar registros afectados ; fin: pop si pop cx pop ax mov sp,bp bis v-v rét vv ñró+ rsp=bp ; restaurar bp endp ; *****tr**************************************************************** instalar proc near ; - A]macena 1a dirección de l-a subrutina en el área de co¡nunicaciones ; entré aplicaciones. t - Deja residente la subrutina. i direccionar segnento segcero con el registro es assume es:segcero mov axr 0 mov es,ax ; poner dirección de 1a subrutina en e1 área de comunicaci-ones i entre aplicaciones 728 nov des_sub, offset bj.s mov seg_sub, cs ; dejar residente Ia subrutina mov dxroffset instal-ar int 27}j, instalar endp codigo desplazamiento segmento dx = úl-tina dirección + t respecto a1 segmento de la subrutina terrninar, pero quedar residente ends end empezar 729 BI PRESU. BAS 002 004 | Programa: BfPRESU. 006 | r 0l-0tDescripción: 02O I Ejenplo de utilización de una subrutina Assembler residente 030 | desde un programa Basic. 045 | 050 | -----060 | l-00 OPTION BASE 1 | subíndice inicial = ll-l-0 DEFINT A-Z ' todas 1as variables enteras (2 bytes) r20 | 13o I obtención de la di.rección de 1a subrutina residente l-40 | t segmento = 0 150 DEF SEG : 0 160 INI = &H4F0 | posición donde se encuentra 1a dirección 1"70 DESP = PEEK(INI) + PEEK(INf+1)*256 ' desplazarniento 18O SEGM = PEEK(INI+2) + PEEK(fNI+3)*256 ' segnento L90 | 200 t ejecución de l-a subrutina 2lo I 220 DEF SEG = SEGM t seqmento 230 AS ='tabcdefghijkfrnnñofqrstuvr^/xyzOl-2 34567A9n 240 PRINT A$ 250 CALL DESP (AS) | l-lanar a Ia subrutina 260 PRINT A$ 270 END 730 BIS.ASM ; Subrutina: BIS. ; ; Descripción3 ; Canbiar minúscufas a mayúsculas en una cadena de caracteres BASIC. ; La subrutina queda preparada para ser uti-fizada desde eI compilador ; de BASIC, según el val-or def sirnbolo "tipo_basicrl i Parámetros: c+Yrrñ dw ret des dw ret-seg dw d\nr Pl params ends ? ; bp salvado por Ia subrutina ? ; dirección de retorno (desplazaniento) ? ; dirección de retorno (segmento) ? ; dirección Paránetro 1 ; (ent/saf) cadena de caracteres del- BASIc ; Sírnbolos: tipo_basic equ 1 i t 1 - intérprete (campo longitud cadena, 1 byte) ; 2 - compilador (campo longitud cadena, 2 bytes) equ offset p1 - offset ret_seg i argumento de ret nret ---------t prefijo tipo t bsave bsave t codigo BSAVE segment db dw d\^¡ dr^r ends Ofdh ; identificación fichero tipo BSAVE o ; segmento por defecto 0 ; desplazaniento por defecto final - comienzo ; tamaño (bytes) del rnódulo segnent byte assume cs:codiqo comienzo equ $ bis proc far push bp nov bp,sp ; e1 alineamiento tipo byte es necesario i si se va a crear tipo BSAVE ; ==> co¡nienzo irnagen de memoria i cornienzo procedimiento ; salvar bp ; bp = sp (apuntar aI area de parámetros) i ; salvar registros afectados ' push ax push cx push si i recoger parárnetro mov si, [bpi.p]t si = desplazarniento parárnetro 1 ife tipo_basic-L ; si tipo-basic = 1 (intérprete) Sout Intérprete de BASIC nov ch,o i ch = 0 mov cl, [si] i cx = longitud de la cadena el,se ; si co¡npil-ador Sout co¡npilador BAsrc 731 mov cx, [si] endif cmp cx,0 jle fin i cx = longitud de l-a cadena ; ¿longitud cadena = 0? ; si ... fin t bucle caracteres de 1a cadena mov si, Isi+tipo_basic] fodsb cmp al-, rar jb carsigr cmp aI, t zl ja carsig sub a7,32 mov Isi-]-l , aI t si = desplazarniento cadena aI = ds: [si], si = si + 1 ¿carácter inferior a rat? si ... carácter siguiente ¿carácter superior a tzt? si ... carácter siguiente convertir a rnayúsculas por ejenpfo, a = 9'7, A = 65 aL¡nacenar carácter convertido ; carácter siguiente carsig: Ioop car ; restaurar registros afectados rln: pop si pop cx pop ax i --- bis mov sp,bp pop bp ret nret endp f inal eqlu I codigo ends end 732 ; sp = bp i restaurar bp ; fin procedirniento ; ::> fin imagen de ¡ne¡noria 37 lntertaz con BASIC compilado La comunicación entre un módulo BASCOM (IBM PC Basic Compiler) y un módulo ensamblador se realiza, como en el caso del intérprete de BASIC, mediante la sentencia: CALL nombre-subrutina(argumentol,argumento2,...) Pero hay diferencias respecto al modo intérprete: o El objeto del módulo ensamblador se incluye en la fase de montaje (LINK) del programa. Es decir, teóricamente ya no es necesario cargar el código objeto mediante POKE o BLOAD. Realmente se hace el uso normal de la capacidad del montador de crear un módulo ejecutable a partir de varios módulos objetos. ¡ El nombre de la subrutina debe declararse PUBLIC. Por su lado. la sentencia CALL genera un EXTRN idéntica a la que se usa en ensamblador. o La manera en que se transmiten los argumentos es la misma que en modo intérprete, con la única diferencia de que el descriptor de la cadena tiene un campo de longitud de 2 bytes. Descriptor de cadena: bytes I y 2 - longitud de la cadena (0 a32767). bytes 3 y 4 - desplazamiento (offset) de la cadena. 733 Se puede también cargar un objeto ensamblador mediante BLOAD o POKE, pero no se puede utilizar esta forma de la sentencia CALL. Cuando el compilador BASIC inicializa las variables, pone a cero todos los segmentos que no tienen como nombre de clase "CODE". Con este nombre de clase nos aseguramos de que el módulo objeto del ensamblador se agrupará junto con el módulo objeto del BASIC compilado. La sentencia CALL ABSOLUTE Para cargar el código de un módulo ensamblador mediante BLOAD o mediante POKE, hay que usar esta sentencia, que tiene el formato siguiente: CALL ABSOLUTE(argumento 1, argumento2,. . .,ar gumenton, variable-entera) Esta sentencia hace que los desplazamientos de los argumentos se coloquen sobre la pila y haga una llamada ala dirección siguiente: o Segmento: el correspondiente al DEF SEG activo. o Desplazamiento: el de variable-entera. Esta es la única manera de pasar el control a una dirección determinada y es el que se utiliza para transferir el control al código cargado en una matriz (mediante BLOAD o POKE). Método BLOAD Para cargar el código del módulo ensamblador con BLOAD dentro de la matriz entera CODIGO v a continuación bifurcar al mismo. se utilizan las sentencias: I ' subíndice inicial: I ' todas las variables enteras (2 bytes) ' matriz para almacenar el código de la subrutina 430 N : VARPTR(CODIGO(I)) ' desplazamiento del primer elemento 440 BLOAD "nombre-fichero",N ' carga del código 500 ' 510 ' ejecución de la subrutina 520', 530 Pl :... ,' parámetro parámetro 2 540 p2: ... 100 OPTION BASE 110 DEFINT 170 DIM CODIGO(...) A-Z 1 734 550 ... ' parámetro n 560 pN:... 570 CALL ABSOLUTE (Pl,P2,..,PN,N) ' llamar a la subrutina Método POKE En este caso las sentencias son: ' subíndice inicial: I ' todas las variables enteras (2 bytes) I l0 DEFINT A-Z DIM CODIGO(...) ' matriz para almacenar el código de la 170 100 OPTION BASE I subrutina 400' 410 ' carga del código objeto sobre la matriz CODIGO 420', ') código objeto (en hexadecimal) 430 DATA &H..,&H.. : longitud del código 440 L ... 450 N : VARPTR(CODIGO(I)) ' desplazamiento del primer elemento 'buclebytes 460FORI:lrOL ' obtener byte sobre VALOR 470 READ VALOR 480 POKE N + I -1, VALOR ' almacenarlo en CODIGO 490 NEXT I 500 ' 510 ' ejecución de la subrutina 520 ', 530 pl : ... ' parámetro I 540 p2: ... ' parámetro 2 550 ... 560 pN: ... ' parámetro n 570 CALL ABSOLUTE (Pl,P2,..,PN,N) ' llamar a la subrutina La sentencia COMMON Esta sentencia se usa principalmente para pasar datos de un módulo a otro via sentencia CHAIN, pero también puede usarse como mecanismo para pasar datos desde un programa en BASIC compilado a un módulo ensamblador. Se incluye a continuación un ejemplo ilustrativo: I 100 OPTION BASE 110 DEFINT 120 DIM 130 COMMON N,A$,M( A-Z M(5) t40' ' subíndice inicial: I ' todas las variables enteras (2 bytes) ' matriz entera de 5 elementos ) ' definición COMMON 150 ' inicialización de variables 160' N:1 170 180 A$ = "PEPE" 190 M(3) :3 200 CALL SUBR ' llamar a la subrutina t g¡Etttplo DE SUBRUTINA ENSAMBLADOR LLAMADA ; DESDE BASIC COMPILADO (CON COMMON). ; ; segmento común ; ; COMUN SEGMENT COMMON NDW? LON-A$ DW DES-A$ DW M DW ? ? 5 DUP(?) COMUN ENDS definición variable N longitud de la cadena desplazamiento de la cadena definición variable M (5 palabras) segmento de código PUBLIC SUBRUT CODIGO SEGMENT PARA PUBLIC ,CODE' ASSUME CS:CODIGO.DS:COMUN SUBRUT PROC FAR ; comienzo procedimiento ; proceso MOV N,l234h ; cambiar el valor de N MOV BX,OFFSET M ; BX apunta a M(l) MOV CX,LON_A$ ; CX: longitud de la cadena LEA SI,DES-A$ nbr SUBRUT ENDP t CODIGO ENDS END 736 ; SI apunta al primer carácter ; de la cadena ; fin procedimiento Método de las subrutinas residentes Este método es también válido, como en el modo intérprete, para el caso de programas en BASIC compilado. 737 lntertaz con COBOL Nos referimos al compilador COBOL de Microsoft. La comunicación entre un módulo COBOL y un módulo ensamblador se realiza vía sentencia CALL: CALL "subrutina" USING Pl. P2. ... PN. Las características de la comunicación son: o Los argumentos se pasan por referencia. La direcciÓn de cada argu- mento sobre la pila consta sólo del desplazamiento. Ocupa, por tanto, una palabra. El segmento es el apuntado por DS. . El procedimiento invocado debe ser FAR, es decir, se guarda sobre la pila la dirección completa de retorno. . El procedimiento debe declararse PUBLIC. r En el módulo ensamblador la instrucción de retorno debe ser RET n, siendo n:2* número de parámetros. Aplicaciones Progromas: CBP.COB - Ejemplo de llamada COBOl-Ensamblador. Subrutinas: CBS.ASM - Ejemplo de subrutina llamada desde COBOL. 738 CBP.COB * Programa: CBP. * n6<^riñ-iÁñ. * Ejemplo de llamada COBOL - Assembler. Identl-t].caElon dIvIsIon. program-id. co. environment division. configuration section. data division. working-storage section. pic 99 comp-o value 77 plp2 pic 99 comp-o value 77 pic 99 conp-o value 77 p3 parl pic 77 99, 77 par2 pic 99. 77 par3 pic 99. procedure division. comienzo. calf ¡rcbsr¡ using p]-, p2, ñ^\ró h1 f^ l-5. 25. 0. p3. ñ.F1 rnove p2 to par2. h^lté h? +^ ñ-F1 display parl ' + | par2 | = | par3. sEop run. 739 CBS.ASM í ; Subrutina: CBS. ; Descripción: ; Ejenplo de subrutina 1l-anada desde COBOL. ; Parámetros: params struc dr¡/ ? ip_ret d$, ? cs ret dL¡ ? ñ? ÁLr ?. p2 dl^¡ ? p1 dw ? params ends ; bp salvado por l-a subrutina ; desplaz. dirección de retorno ; seq¡nento di-rección de retorno r dirección paránetro 3 (sal) (1 palabra) ; dirección paránetro 2 (ent) (1 palabra) ; dirección paránetro I (ent) (1 palabra) ; SÍ^bolo=, nret equ offset p1 - offset cs_ret ; i argumento de ret ---------- coor_go segmenc assume cs:codigo ñ!rLf yqprrv cbs I ^ ^Leu- push bp mov bprsp sal-var regÍstros afectados push si push ax recoger parámetros de entrada mov si, [bp].pL mov ax, [si] mov si, [bp].p2 mov bx, [si] t si = desplazamiento parámetro 1 i ax = valor parámetro 1 t si = desplazamiento parámetro 1 ; bx = valor parámetro 1 proceso add axrbx i ax = ax + bx poner parámetro de salida mov si, tbpl.p3 mov [si],ax ; si = desplazamiento paránetro 3 ,' mover resultado a parámetro 3 restaurar registros afectados pop ax pop si mov pop 740 sp, bp bp cbs endp codigo ends end 741 Intertaz con FORTRAN La comunicación entre un módulo FORTRAN y un módulo ensamblador se realiza de dos formas: o Mediante sentencia CALL. o Mediante una función. Las características son: Los argumentos se pasan por referencia. La dirección de cada argumento sobre la pila es completa (segmento y desplazamiento). Ocupa, por tanto, dos palabras. El procedimiento invocado debe ser FAR, es decir, se guarda sobre la pila la dirección completa de retorno. : El,?ir?tiliftnffi#::'?ir::,ii.i#ft retorno debe ser REr n, siendo n:4* número de parámetros. En el caso de una función real, hay que añadir 2 a este valor. Llamada mediante CALL En este caso, todas las subrutinas ensamblador desarrolladas en los capítulos anteriores son aprovechables sin cambios. 742 Llamada mediante una función o Si la función es de tipo entero o lógico de 2 bytes, el valor a retornar debe estar en AX. ¡ Si la función es de tipo entero o lógico de 4 bytes, el valor a retornar debe estar en AX (parte inferior) y en DX (parte superior). ¡ Si la función es de tipo real*4 o real*8, se pasa automáticamente en la llamada un argumento adicional que contiene el desplazamiento de una variable temporal que va a contener el resultado. El segmento es el apuntado por DS. Además, AX debe contener el desplazamiento de esta variable temporal. El siguiente módulo ensamblador muestra un ejemplo de función real, que es el caso más complejo. , : EJEMPLO DE FUNCION REAL LLAMADA DESDE FORTRAN : ------------; FUN(X): XxPl. PARAMS STRUC DW ? ; BP salvado por la subrutina ? ; dirección de retorno RESUL DW ? ; desplazamiento variable temporal (respecto a DS) RETORNO DD X ; con el resultado de la función DD ? ; dirección parámetro PARAMS ENDS NRET EQU OFFSET X - OFFSET RETORNO ; argumento de RET CODIGO SEGMENT PARA 'CODE' ASSUME CS:CODIGO PUBLIC FUN t FUN PROC FAR PUSH BP ; salvar BP MOV BP.SP : BP: SP LES BX,[BP].X FLD DWORD PTR ES:[BX] FLDPI FMULP ST(t),ST MOV DI,[BP].RESUL MOV AX.DI FSTP DWORD PTRlDrl ES:BX: dirección de X PUSH. ST: X PUSH, ST: PI ST: ST*ST(I), POP DI : desplazamiento resultado AX : desplazamiento resultado almacenar resultado en variable ; temporal y PoP FWAIT ; esperar a que acabe el 8087 MOV SP,BP ; SP: BP POP BP : Restaurar BP FUN RET NRET ENDP CODIGO ENDS END Aplicaciones Un ejemplo de subrutinas ensamblador llamadas desde FORTRAN se incluye en el capítulo "La irnpresora en modo gráfico". 744 Intertaz con C Nos referimos a los compiladores Microsoft y Lattice u otros compila- dores similares: Desmet, Aztec, etc. Existen entornos distintos de programación. vamos a considerar el caso de longitud máxima de 64 Kb (un segmento) para código y datos. La comunicación entre un módulo en lenguaje C y un módulo ensamblador tiene las características siguientes: . o Los argumentos se pasan por valor o por referencia, es decir, de forma directa o indirecta. El lenguaje C intenta, a menos que se le diga otra cosa, poner el valor sobre la pila, en lugar de su dirección. Para forzar al c a que pase una dirección, se le pone a la variabre el prefijo "&". Por ejemplo: SUBR(&I,J) El primer parámetro contiene la dirección de la variable ',I', y el segundo el valor de la variable "J". o Las direcciones relativas (desplazamientos) están referidas al registro DS. o Al contrario que la mayoría de los lenguajes, el primer parámetro se coloca el último sobre la pila (el más próximo a Bp). o Como todas las funciones C retornan un valor entero en el regis745 tro AX, el módulo ensamblador debe hacer lo mismo. Si la función se calculó correctamente, AX debe ser cero. ¡ Las variables tipo cadena (string) usadas como argumento pasan la dirección siempre. Por ejemplo: suBR(s) Si "S" es una variable tipo cadena, el parámetro que se pasa es la dirección de la variable "S". . El procedimiento debe declararse PUBLIC. . El procedimiento debe ser tipo NEAR. o En el módulo ensamblador la instrucciÓn de retorno debe ser RET n, siendo n igual al número de bytes que ocupan los parámetros sobre la pila. Los tipos de datos soportados por el lenguaje C son: o Enteros. Pueden ser de I byte sin signo, de 2 bytes (con o sin signo) o de 4 bytes con signo. o .Cadenas (strings). Una cadena se almacena como ASCIIZ, es decir, una serie de caracteres seguido de un byte con 00h, que indica el final de la cadena. o Punto flotante. Utilizan los formatos estándar del coprocesador 8087 (de 4 y de 8 bytes). 746 41 Intertaz con PASCAL El PASCAL es el lenguaje que posee más flexibilidad en la comunicación con módulos ensamblador. un programa PASCAL trata a un módulo ensamblador de la misma forma que a los propios procedimientos del lenguaje. Las características del interfaz son: o La llamada es de tipo FAR, es decir, se pasa la dirección completa (dos palabras). o Los parámetros se pasan (como a cualquier procedimiento PASCAL) por valor o por referencia: . Se pasa el valor de los parámetros simples. . Se pasa la referencia (desplazamiento sólo, el segmento es DS) de los parámetros complejos y los de tipo VAR. o El módulo ensamblador puede alterar cualquier registro, excepto Bp, SS y DS. . Se debe restaurar la pila antes de devolver el control al programa llamador. o Al entrar en el procedimiento, la situación de los registros es: . SS apunta al segmento de pila del PASCAL. . CS apunta al segmento en el que reside el procedimiento llamado. . DS apunta al segmento de datos del PASCAL. 747 . BP apunta al marco (frame) del procedimiento llamador. . SP apunta al marco del procedimiento llamado (dirección de retorno más parámetros). Funciones PASCAL La comunicación es análoga a la de los procedimientos, pero las funciones retornan un valor: . si 8 bits, en AL. . si 16 bits, en AX. r si 32 bits, en ES y BX. Variables PU BLIC Las variables PASCAL con atributo PUBLIC se pueden acceder directamente por un módulo ensamblador sin necesidad de pasarlos como parámetros. En el módulo ensamblador: ¡ Las variables se deben declarar EXTRN. ¡ El retorno al módulo llamador es con RET, sin argumentos. o Se debe definir un grupo de segmentos de nombre DGROUP que incluya el segmento de datos, que a su vez contiene las definiciones EXTRN. DGROUP es el nombre del segmento físico donde residen los datos PASCAL. A continuación se incluye un ejemplo: PROGRAM SUMAR(INPUT,OUTPUT) ; (* (x Calcula la suma de dos números mediante la llamada a un *) (* módulo ensamblador *) (x --------------------- x) (r. *) VAR IPUBLICI N1,N2,R :INTEGER; PROCEDURE SUMA; EXTERNAL; BEGIN WRITELN ('Teclear dos números: '); READLN(Nl,N2); 78 SUMA; (* Llamada a un módulo ensamblador *) WRITELN ('La suma es: ',R); END. ; Ejemplo de procedimiento ensamblador llamado desde PASCAL PUBLIC SUMA DGROUP GROUP DATOS DATOS SEGMENTBYTE'DATA, EXTRN N 1 :WORD,N2:WORD,R:WORD DATOS ENDS óoorco sEGMENT PARA PUBLTc 'coDE' SUMA ASSUME CS:CODIGO,DS:DGROUP PROC FAR MOV AX,NI ADD AX,N2 MOV R.AX RET ENDP CODIGO ENDS END SUMA 749 Programación estructurada Def inición La programación estructurada es una filosofía de diseño de software que tiene las características siguientes: . En primer lugar, y principalmente, existen unas estructuras de control de la lógica del programa. Estas estructuras de control son de tal forma que no son necesarias instrucciones de bifurcación. Al no existir instrucciones de bifurcación, tampoco son necesarias las etlquetas. . Un aspecto visual importante en la escritura de cada módulo fuente es que las sentencias comprendidas dentro de una estructura de control se desplazan (normalmente, dos posiciones) a la derecha. o Pueden existir estructuras de control anidadas. es decir. una dentro de otra. El propósito de la programación estructurada es aumentar la calidad de los programas en los aspectos de: claridad de la lógica, documentación y eliminación de errores. Además, es una condición necesaria para realizar programas con la técnica arriba-abajo (top-down), que consiste básicamente en desarrollar el programa de lo global a lo particular, de tal manera que 750 inicialmente se parte de un esquema del programa (estructuras de control de mayor nivel, junto con sus comentarios) y progresivamente Se van añadiendo otras estructuras de control y mayor detalle. Una característica de esta técnica es la posibilidad de poder probar el programa en cada fase del desarrollo. Las estructurab de control básicas son dos: la estructura IF-ELSE-ENDIF y la estructura DOWHILE-ENDDO. Las formas son: IF condición DOWHILE condición A A ELSE B ENDDO ENDIF En donde A y B son bloques o conjuntos de instrucciones, que pueden contener a su vez otras estructuras de control. Obsérvese que A y B se han desplazado dos posiciones a la derecha. La estructura IF-ELSE-ENDIF indica que se ejecute el bloque A si la condición especificada es cierta. Si no es cierta, indica que se ejecute el bloque B. La parte ELSE de la estructura de control es opcional, siendo la forma en este caso: IF condición A ENDIF La estructura DOWHILE indica que se ejecute el bloque A mientras se cumpla la condición especificada, es decir, A se ejecuta de forma cíclica (bucle) hasta que la condición sea falsa, continuando entonces con la instrucción que sigue a ENDDO. Puede demostrarse que mediante estas estructuras de control básicas es posible implementar cualquier lógica de un programa. Muchos lenguajes de alto nivel ya llevan incorporadas estas estructuras de control básicas (por ejemplo, Pascal). Otras estructuras de control que pueden existir son, por ejemplo, la FOR-NEXT del BASIC. En ensamblador es posible realizar programación estructurada mediante la utilización de macros. Un aspecto negativo es que los programas desarrollados con este sistema son más grandes y requieren, por tanto, mayor tiempo de ensamblaje. Pero la calidad lograda compensa en mucho este inconveniente. Vamos a desarrollar a continuación las macros necesarias para implementar estas estructuras de control. Constituyen además un excelente modo de practicar el desarrollo de macros. Una vez entendidas, el lector podrá desarrollar sus propias estructuras de control y, si lo desea, castellanizar los nombres. Se ha incluido en todos los nombres utilizados el prefijo "$" por dos motivos. En primer lugar, para distinguirlos de los del usuario. En segundo 751 lugar, para evitar que la estructura IF se confunda con la directiva del mismo nombre. En Macro Assembler 3.0 existe un programa de utilidad llamado SALUT (Structurol Assembly Language Utility), que realiza la conversión de unas estructuras de control ya definidas a instrucciones estándar del lenguaje. La estructura DOWHILE-ENDDO Vamos a hacerlo progresivamente en varias fases. Esquema general: Se trata de desarrollar dos macros ($DOWHILE y $ENDDO) para con- vertir: $DOWHILE opl,oper,op2 $ENDDO en las instrucciones siguientes: $BUCLE: CMp opl,op2 Joper $BLOQUE JMP $FIN $BLOQUE: $FIN: ]üp Sgucln ; comienzo bucle ; comparar operandos ; bifurcar a $BLOQUE si se cumple ; condición ; bifurcar a $FIN ; comienzo bloque ; bifurcar a $BUCLE ; salida del bucle .. Signdg "opl" y "op2" los operandos de la instrucción de comparación cMP y "oper" el sufijo de una instrucción condicional, como, por ejemplo, L (menor que), AE (superior o igual a), NE (no igual), etc. La estructura de control nos suprime tres instrucciones de bifurcación v tres etiquetas. La condición en este caso está, pues, implementada mediante dos operandos y un operador de comparación. Un ejemplo de utilización de la macro sería: $DOWHILE AX,LE,3 spÑono 752 Primera versión: La implementación inicial correspondiente a este esquema general es la que aparece en PEMDO1.ASM. La macro $DOWHILE tiene tres parámetros y la macro $ENDDO ninguno. La implementación es casi la literal del esquema general. Unicamente se reservan tres bytes mediante la instrucción NOP para ser sustituidos por el código asociado a la instrucción JMP $FIN. El programa PEPDOI.ASM prueba estas macros. Segunda versión: Esta primera versión tiene el inconveniente de utilizar etiquetas, que son esenciales para la comunicación entre ambas macros y no pueden declararse, por tanto, como etiquetas locales (directiva LOCAL). Por consiguiente, las macros sólo pueden utilizarse una vez, es decir, no son reutilizables dentro del mismo módulo fuente. La forma de solucionar este problema es: . Utilizar símbolos con sentencias de asignación " :", con lo que los valores asignados a cada símbolo pueden variar a lo largo del médulo fuente. o Utilizar el símbolo "$" para referirnos al valor del contador de posiciones. La segunda versión, ya reutilizable, es la que aparece en PEMDO2. El programa PEPDO2.ASM prueba estas macros. Tercera versión: La segunda versión no permite la utilización de macros anidadas (una dentro de otra), como por ejemplo: SDOWHILE AX,LE,IOO i'rowurlE BX,cE,so iÉNroo seÑ'óoo 753 Pues la segunda $DOWHILE destruiría los valores de los símbolos "$bucle" y "$hueco" definidos en la primera. La solución a este problema consiste en implementar una pila de símbolos y dos nuevas macros para manejar esta pila, una para almacenar un símbolo sobre la pila y otra para recuperar el último símbolo, tal y como se describen en PEMAUX.ASM. Cada símbolo almacena un valor del contador de posiciones. La tercera versión y última, ya reutilizable y anidable, es la que aparece en PEMDO.ASM. El programa PEPDO.ASM prueba estas macros en su estado definitivo. La estructura lF-ELSE-ENDIF Esquema general: Se trata de desarrollar tres macros (SIF, $ELSE y $ENDIF) para con- vertir: $lF condición $ELSE .:: $ENDIF en las instrucciones siguientes: CMP opl,op2 ; comparar operandos Joper $BLOQUEI ; bifurcar a $BLOQUE si se cumple ; condición JMP SBLOQUE2 ; bifurcar a $BLOQUE2 $BLOQUEI: ; comienzo bloque I JMP $FIN $BLOQUE2: ; comienzo bloque 2 $FlN: ; salida de la estructura de control E,n el caso de que no exista el bloque ELSE, habría que convertir: $lF condición ... $ENDIF 754 en las instrucciones: CMP opl,op2 JMP $FIN . $BLOQUEI: ; comparar operandos $BLoQUE si se cumple I ::Tá,Tra I bifrr..u, a $FIN ; comienzo bloque I $FIN: : salida de la estructura de control Joper $BLOQUEt Los parámetros "opl", "op2" y "oper" tienen el mismo significado que en la estructura anterior. Macros: Las macros $IF, $ELSE y $ENDIF se describen en PEMIF.ASM. Se utilizan las macros auxiliares creadas en la estructura de control anterior. El programa PEPIF.ASM prueba estas macros. La estructura FOR-NEXT Esquema general: Se trata de desarrollar dos macros ($FOR y $NEXT) para convertir: $FO.R indice,inicial, final [,incr] sÑixr en las instrucciones siguientes: MOV indice,inicial ; poner valor inicial en índice JMP SHORT $COMPARAR ; bifurcar a comparar $BUCLE: ; comienzo bucle ADD indice,incr ; sumar incremento a índice $COMPARAR: CMP indice,final ; comparar índice con valor ; final IF incr GT 0 JLE $BLOQUE ; si menor o igual, bifurcar a ; $BLOQUE ELSE 755 JGE $BLOQUE ENDIF JMP $FIN $BLOQUE: JMP $BUCLE $FIN: ; si mayor o igual, bifurcar a ; $BLOQUE ; bifurcar a $FIN ; comienzo bloque : bifurcar a $BUCLE ; salida de la estructura de : control Macros: Los macros $FOR y $NEXT se describen en PEMFOR.ASM. La macro $NEXT es idéntica a la macro $ENDDO. El programa PEPFOR.ASM prueba estas macros. Aplicaciones Macros: PEMAUX - Macros auxiliares de las macros de programación estructurada. PEMDO - Macros $DOWHILE y $ENDDO (versión final: reutilizable y anidable). PEMDOI - Macros SDOWHILE y $ENDDO (versión 1: no reutilizable). PEMDO2 - Macros SDOWHILE y $ENDDO (versión 2: reutilizable, pero no anidable). PEMFOR - Macros $FOR y $NEXT. PEMIF - Macros $IF, SELSE y $ENDIF. Programos: PEPDO - Prueba macros $DOWHILE y $ENDDO (versión final). PEPDOI - Prueba macros $DOWHILE y $ENDDO (versión 1). PEPDO2 - Prueba macros $DOWHILE y $ENDDO (versión 2). PEPFOR - Prueba macros $FOR y $NEXT. PEPIF - Prueba macros $IF, $ELSE y $ENDIF. 7ffi PEMAUX.ASM Macros: $SALVAR, $SALVAR1, $RECUP Y $RECUPI Descripción: Macros auxiliares de fas macros de programación estructurada. Sirven para salvar y recuoerar el valor del- contador de posiciones mediante Ia utilización de una pila de simbolos. Símbolos: $simbol-o = contador de posiciones recuperado. Si = número de orden del últirno símbolo. $si¡n 1, $sin 2 $salvar rnacro i fndaf (i <i = o ENdII $j- = $i+1 $saIvar1 %9i contadores de posiciones sal-vados. si simbolo no definido hacerl,o cero i-ncrenentar nro. de orden de1 sí¡nbolo salvar contador de posiciones endrn $salvar1 macro Si this near $sin_&$i = endm Srecup si macro $recupl ?$i ; sal-var contador de Posiciones i recuperar úl-tirno símbolo r decrementar nro. de orden del sirnbolo endm nacro $i ifndef $sj-¡n_&$i ; si sínbolo no definido .1a11 ; *** error de estructura *** *** error de estructura *** ?out endif $sirn_&$i ; recuperar úItimo sÍmbolo $sinbolo = SrecupL endm 757 PEMDO.ASM Macros: SDOWHILE y $ENDDO. Formato: $o:T:t"" opl-,oper¡op2 $ENDDO Descripción: Ejecutar bloque de instruccj-ones mientras se curnpla una condición. La condición se especifica mediante tres parámetros, que se corresponden con 1os operandos de una instrucción de cornparación y el tipo de bifurcación condicional-. por ejernplo: CMP AX,12 opl- = AX oper = LE JLE FIN Versión reutilizabfe op2 : 12 v anidable. Parámetros: op1 = varj-able de rnernoria, registro op2 = registro, valor inmediato, memoria (si op1 es registro) oper = operador de comparación: E, Lt LE, B, BE, c, cEt A, AE y sus concrart-os: E j ernplos: tu:::tt" <byte ptr Isi]>,Ie,'z' gdowhite ax,re,12 ::: s"iáá" senddo Símbolos: $bucle = contador de posiciones en conienzo bucl_e. $hueco = contador de posiciones en espacio reservado para eI código de jnp gfin. : contador de posiciones en salida del- bucl-e. $fin $si¡nbolo = contador de posiciones recuperado. do$/hiLe macro op1, oper, op2 gsafvar cnp opl_, op2 j&oper $ + 5 gsalvar nop nop noP endm i genddo macro $recup 758 $hueco = gsimbolo $buc1e = gsinbolo $recup imn <l-rrr^ l ó ; safva el- contador de posiciones para poder t bifurcar después de cada iteración ,. comparar operandos ,. bifurcar a bloque si se curnple l-a condición ; sal-va eI contador de posiciones para poder ; referenciar aJ. espacio siguiente ; espacio reservado para eI código ; de La instrucción ; jnp $fin t ef bloque de instrucciones cornienza aquÍ ; recuperar contador de posiciones i correspondiente al- hueco de los NOPS ; salvar este valor ; recuperar contador de posiciones ; correspondiente af comienzo de1 bucfe r sal-var este vafor ; bifurcar a comienzo de1 bucle $fin = org jmp "tó endm this near ; salvar contador de posiciones i poner contador de posiciones en eI hueco thueco i reservado con los NOPS ; incluir el código de jnp $fin $fin ; restaurar eI contador de posiciones $fin 759 PEMDOl.ASM Macros: $DO!íHILE y $ENDDO. Fornato: *o::Tt"u opt-,oper,op2 s"rnioo Descripción: Ejecuta bloque de instrucciones ¡nientras se cu¡npla una condición. La condición se especifica mediante tres parámetros, que se corresponden con l-os operandos de una instrucción de óonparación y el tipo de bifurcación condicional. por ejenplo: CMP AX,l-2 JLE FIN op1 = AX oper = LE op2 = 1,2 Versión no reutiLizable. Parámetros: op1 : operando 1 op2 = operando 2 oper = operador $dowhile macro opl-,oper,op2 $buc1e: ; comienzo bucle cmp op1,op2 i comparar operandos j&oper $bloque ; bifurcar a bloque si se curnpte la condici-ón $hueco: $bloque: nop nop nop i espacio reservado para e1 código i de 1a instrucción i j¡nP $rin el- bloque de instrucciones comienza aguí endn macro jnp $bucle org $hueco j ¡np endm 760 $fin bifurcar a comienzo del bucle etiqueta tras e1 bucle poner contador de posiciones en el hueco reservado con los NOPS incluir el código de jnp gfin restaurar el- contador de posiciones PEMD02.ASM ; Macros: $DOWHILE y $ENDDO. i ; Formato: $DOWHILE op1,oper,op2 ; ; ; ... ... SENDDO ; Descripción: ; Ejecuta bloque de instrucciones mientras se cumpla una condición. La condicj-ón se especifica rnediante tres parárnetros, que se i corresponden con los operandos de una instrucción de comparación y i ; el tipo de bifurcación condicional. Por ejemplo: t CMP AX,12 opl = AX op2 : 12 t JLE FIN opeT = LE ; ; versiónreutifizable. ; Parámetros: ; op1 = operando L op2 = operando 2 i ; oper = operador ; simbofos: ; $bucle = contador de posiciones en co¡nienzo bucle ; $huéco = contador de posiciones en espacio reservado para el código de jnp $fin i ,' $fin = contador de posicj.ones en sa]ida del bucle $dowhile nacro opl,, oper, op2 this near ; salva el contador de posiciones para poder $bucle = ; bifurcar después de cada iteración cmp opL,op2 ; comparar operandos j&oper $ + 5 i bifurcar a bloque si se cumpfe 1a condj-ción this near ; salva el, contador de posiciones para poder $hueco = ; referenciar al- éspacio siguiente nop ; espacio reservado para e1 código nop ; de l"a instrucción nop ; j¡np $fin ; el bloque de instrucciones cornienza aqui endm í ; --Senddo $fin macro jmp = org jnp org endm $bucle ,' bifurcar a comienzo de1 bucle this near ; salvar contador de posiciones t (corresponde a ]a salida del bucle) $hueco ; poner contador de posiciones en el- hueco i reservado con 1os NoPs ; incluir eI código de jnp $fin $fin ; restaurar e1 contador de posiciones $fin 761 PEMFOR.ASM Macros: $FoR y $NEX?. Formato: $FOR. índice, inicial, final[, j-ncr] sú;'i' Descripción: Ejecutar bloque de instrucciones cornprendidas entré gFOR y $NEXT deL Índice igual a Íinicialr con valor inicial e incrementando én cada iteración el- valor deL índice con el valor de rincrr hasta que eI valor de1 índice sea mayor que ilfinal¡r (caso incr > o) o hasta que el- valor de1 Índice sea j-nferior a rrfinalr (caso incr < 0). Todos 1os operandos deben ser de1 rnisrno tipo (byte o palabra). La comparación se realiza antes de J.a primera ejecución del buc1e. Si rrindice" y 'tfinalr se aLteran dentro de1 bloque de instrucciones, entonces deben de restaurarse al vaLor que tenían antes de modificarse. En caso contrario, se al-teraría Ia ejecución del- buc1e. La macro $NEXT es idéntica a SENDDo. Versión reutilizable y anidable. Parámetros: índice inicial final incr = variable de rnernoria, registro. = registro, val-or inrnediato. = registro, valor inmediato, rnemoria (si inicial = valor innediato (positivo o negativo). (supone 1_ si no existe). es registro) Ej enplos : $for contador,l-,20 $for ax,bx,50,2 $for ax,bx,cx,-2 $for <byte ptr [si]>,l-,l-o $for <word ptr es: [bx]>, LO,'1,,-z Símbol-os: $buc1e = contador de posicj.ones en comienzo bucl-e. $fin = contador de posiciones en salida del bucle. $hueco = contador de posiciones en espacio reservado para elcódigfo de jmp gfin. $incr = incremento. $sinboLo = contador de posiciones recuperado. macro indice, inicial, finat, incr locaL $cornparar ,. etiquetas l-ocales <incr> ifb ; si no existe incremenco $incr=1 ;suponelelse ; caso contrari-o ; coger incremento $incr = incr endif mov indice,inicial ; valor inicial- a índice j¡np short $comparar ; bifurcar a $comparar ; salva el contador de posiciones $salvar i+ éiñ^, Y¡¡¡v¿ ^+ v^ Ye add indice,$incr else sub indice, $incr endif $conparar: 762 cmp indice, final if $incr gt o jle $ + 5 else ise $ + 5 endif $salvar nop nop nop endm i comparar ; bifurcar a bloque si menor o igual ; bifurcar a bloque si mayor o igual ; salva eI contador de posiciones ; espacio reservado para e1 código ; de l-a instrucción ; jnp $frn ; el bloque de instrucciones conienza aqu i --- Snext thueco $bucle $fin macro Srecup gsinbolo = $recup : $sirnbolo jnp gbucle this near = org $hueco jmp $fin org $fin endrn ; recuperar contador de posiciones i correspondiente af hueco de los NoPs i sal-var este valor ; recuperar contador de posiciones i correspondiente a1 cornienzo del bucle ; safvar este valor ; bifurcar a cornienzo del bucle ; salvar contador de posiciones ; poner contador de posiciones en el- hueco ; reservado con l-os NOPS ; incluir eI códigro de jmp $fin i restaurar eI contador de posiciones 763 PEMIF.ASM Macros: $IF, $ELSE y $ENDIF. Formato: $IF.op1,oper, op2 tr::: SENDIF Descripc j-ón: Ejecutar bloque de instrucciones cornprendidas entre gIF y $ELSE si l-a condición especificada es cierta. Si l-a condición es fal-sa, ejecutar e1 bloque de instrucciones comprendidas entre $ELSE y $ENDIF. $ELSE es opcional. Si no existe, cuando la condición es cierta, se ejecutan Las instrucciones comprendidas entre $IF y $ENDIF. Versión reutil-izabl-e v anidabLe. Parámetros: op1 = variable de mernoria, regi-stro op2 = registro, valor in¡nediato, menoria (si opl" es registro) oper = operador de comparación: E, L, L!', B, BE, G, GE, A, AE y sus conErart-os: Ej enplos: $if.<byte ptr Isi]>,le, rzl Sif ax, 1e, l-2 . $efse )erse ::. ::: 9endif Símbolos: $sirnbolo : contador de posiciones. macro opL, oper, op2 cnp opl-, op2 co¡nparar operanoos j&oper $ + 5 bifurcar a bl-oque1 si se cumple la condició sal-va el- contador de posiciones para poder referenciar a1 espacio siguiente nop espacio reservado para e1 código nop de 1a instrucción jmP $ti.t nop e] bl-oque l- de instrucciones cornienza aquÍ endm $else $casocon: 764 loca1 $bl-oque2,$casocon i recuperar contador de posiciones $recup org $simbolo ; poner contador de posiciones en e1 hueco de fos tres NoPs de Sif jmp $bloque2 i j-nsertar el código de jnp $bloque2 org Scasocon ; poner contador de posiciones al cornienzo del bloque else t salva e1 contador de posiciones para poder $salvar ; referenciar aI espd,cio siguiente ; espacio reservado para el código ! ; de la instrucción ; jrnp $fin i ef bloque 2 de instrucciones comienza aquÍ nop nop nop $bl-oque2. endm : --; Sendif $fin: macro rocal Srrn $recup org j¡np org endm $sinbolo $fin $fin i recuperar contador de posiciones ; correspondiente a1 hueco de l"os NoPs ,' de $if o de $el-se i poner contador de posiciones en eI hueco t reservado con los NOPS ; incluir el código de jnp $fin ; restaurar el- contador de posiciones 765 PEPDO.ASM . Pr^dr.ñá. DFDnñ ; . nóc^rih^iÁh. Prueba rnacros $DOWHILE y $ENDDO. r ; Sinbolos: cr equ l-3 l-f equ 10 ; retorno de carro ; alimentación de fínea ; Procedirnientos externos: extrn pastexto: far ; Macros: tr,t i nc l udc npm.lñ . asJn include pemaux.asm endi f ; ---------- pila hi i ; ; l ^ segment stack db L28 ah.ic dup ( 'pilar ) ---------- datos segnent para n-L ctD ! db db 20 dup ( rar ) , crr lf, n2db? textol texto2 datos ; ; ends ' ; contador bucl-e externo r contador bucl-e interno ; texto a escribir ' $, t texto a escribir ', 20 dup (rbr),crr1fr'$' ---------- codigo pepdo segment proc far assume cs : codigo , ds : datos , ss : pila ; poner en La pifa la dirección de retorno aL DOS push ds sub ax,ax push ax i direccionar segrnento de datos con ds mov ax,oaEos mov ds,ax i --mov n1r1 $dos/hi1e nl-, l-e, 3 push ds 1ea ax,textol push ax call pastexto inc nL nov n2rl 766 i ds : segmento de textol i ax = desplazarniento de textol ; escribir textol;n1 :n1 +l- $do$¡hile Ir2,l-e,3 push ds l-ea ax, texto2 push ax call pastéxto inc n2 ds = segmento de texto2 ax = desplazamiento de texto2 escribir texto2 n2=n2+I $enddo 9enddo i retorno al- DOS ret pepdo endp ¡n^iaa óhÁe end Pepdo 767 PEPDOl.ASM ; ; Programa: PEPDOI". . n6c^Fiñ^iÁñ. Prueba macros $DObTHILE y SENDDO (versión 1). ; t SÍmbo]os: cr equ 13 ; retorno de carro If equ 10 i alimentación de línea ; Procedimientos externos: extrn pastexto: far ; Macros: .I I.L 'i nal rrdé némdñ1 . asln endif ; ---------- pila hi l i ; ^ segnent stack db f2A dup (rpilar) óñ.le ---------- datos ndb? texto datos codigo pepdol segnent para db ends 20 dup (rar) ,cr,ff, ,9' ; contador bucle ; texto a escribir segment proc far assume cs : codigo, ds : datos , ss : pila i poner en la pila La dirección de retorno al- DOS push ds sub axrax push ax ; direccionar segmento de datos con ds ^w d^fOS mov dsrax mov n,1 $dowhile n,le,L0 push ds lea axrtexto push ax call- pastexto incn $enddo i retorno al DOS ret 768 tn=1 i ds = segnento de texto ; ax = despl-azamiento de texto ; escribir texto ;n=n*1 h^ha^1 yePqe ^^Aid^ r r¡ ^ñ¡ñ¡qP óhdé ^-l ñ^h^^1 yePqv ¡ 769 PEPD02.ASM i ; Programa: PEPDO2. ; Descripción: i Prueba nacros $DovlHILE y $ENDDO (versión 2). ; SÍmbolos: cr equ 13 lf equ 10 i retorno de carro i al-irnentación de 1Ínea ; Procedimientos externos: extrn pastexto:far ; Macros: if r. incl-ude pemdo2, asm endif pila ni l ¡ segment stack 1,2a dup ('pilar) db ah.lc i datos ndb? textoltextoz datos ; segment para db db ends ; contador bucle t texto a escribir t texto a escribir 20 dup (rar),cr,lf,t$t 20 dup (rbr),cr,lf,t$t ---------- codigo segment pepdo2 proc far assume cs : codigo , ds 3 datos , ss : pila i poner en 1a pila la dirección de retorno al DOS push ds sub ax,ax push ax i direccionar segnénto de datos con ds mov ax,datos mov dsrax mov ir1 $dor4¡hil-e n, le , 5 push ds 1ea ax,textolcall- pastexto incn push ax $enddo movn,ltn=1 Sdowhile n, Ie,5 TTO ;n=1 i ds = segmento de textoL i ax = desplazarniento de textol ; escribir textol ;¡=n*1- push ds fea push calf ínc n texto2 genddo i retorno pepdo2 codigo al- DOS reL endp ends end pepdo2 771 PEPFOR.ASM i ; Programa: PEPFOR. i Descripción: i Prueba macros $FoR y $l¡nxr. ; Si¡nbolos: cr equ l-3 i retorno de carro lf equ 10 i alirnentación de l-Ínea ; Procedinj-entos externos: extrn pastexto: far ; Macros: if1 iñ.1rrda hémfñr.asm include pemaux.asm endif ; ---------- pila pila segment stack db ends I2a dup ('pila') t ---------datos segment para idw? jdw? textol db 50 dup(' t),cr,ff,'$' texto2 db 50 dup(rbr),cr,ff,'$' ends datos ; texto a escrj-bir ; texto a escribir t ---------codigo segrnent pepfor proc far assume cs : codigo, ds : datos , ss : PiJ.a i poner en 1a pila la dirección de retorno aI Dos push ds sub axrax push ax ; direccionar segmento de datos con ds mov axrdatos mov ds,ax Sfor 1,1,7 mov si, i dec si mov textolIsi],ra' push ds l-ea axrtextol push ax óa1l pastexto iÍor ftr,¿ 772 i ds : segmento ; ax : despl-azam.iento ; escribir texto push ds lea ax,texto2 push ax call pastexto $next $next u5 - sca¡"E¡ruv ax = desplazamiento escribir texto ; retorno aI DOS hahf^r i i ^^v evq ^^Á rv anÁn ^-r^ a¡A ñóh€^F 773 PEPIF.ASM ; Programa: PEPIF. ; Descripción3 ; Prueba macros $IF, $ELSE y $ENDIF. ; SÍmbolos: cr equ 13 lf equ l-o ; retorno de carro i alimentación de l-ínea i Macros: ara include pemif.asrn include pemaux.asm endif escribir macro texto ; Escribir texto por pantalla. ; Delinitador fin de texto = $. r texto = texto a escribir. i push ax i sal-var registros push dx Iea dx,texto mov ah,9 int 2l-h pop dx pop ax i dx = desplazamiento de texto ; función: escribir texto por pantalla ; llanar aI DoS i restaurar registros endm ; ---------- pila pila ; segment stack db L28 ends dup (rpiLar) ---------- datos ndb? segment para n-L ht q.D Áh cierto falso datos db db ends ( ? rciertorrcr,lf,r$r I falso r rcr,lf,r$t ; texto a escribir ; texto a escribir i -'-------- codigo pepif segment proc far assune cs : codigo, ds : datos , ss : PiJ-a ; poner en 1a pila l-a dirección de retorno aI DoS push ds sub axrax Push ax Tt4 direccj-onar segmento de datos con ds mov ax,datos mov dsrax mov nL,1 nov n2,I ¡: 1I nrrrahr mov n1,1 mov rr2,2 calI prueba mov rrl, r2 mov n2,I call prueba mov n!r2 mov rL2,2 cal-l- prueba retorno al- DOS nani i ; f éñ^h ---------- prueba proc near i entrada: n1, n2 $if n1, e, L escribir cierto gif n2 , e, lescribir cierto gelse escribir falso $endif $e1se escribir fafso $if n2,e,1 escribir cierto gelse escribir falso gendif gendif prueba codigo ret endp ends end pepif 775 Parte lll El coprocesador matemático 8087 El coprocesador matemático flE7 El coprocesador aritmético Intel 8087 es un chip que sirve para realizar operaciones matemáticas complejas. El IBM PC dispone de un zócalo en la placa base para este procesador, con el que se amplía notablemente la capacidad de cálculo del 8088/8086. El 8088/8086 puede hacer cálculos aritméticos limitados a las cuatro operaciones elementales (sumar, restar, multiplicar y dividir) y sobre números enteros almacenados en una palabra (hasta cuatro a cinco dígitos decimales). En cambio, el 8087 puede calcular funciones trigonométricas, logarít.micas, exponenciales, etc., operandos sobre números enteros o reales de hasta 18 dígitos. Al estar implementadas en hardware,la velocidad de eje- cución se mejora considerablemente respecto a las mismas funciones programadas con las instrucciones del 8088/8086 (del orden de l0 a 100 veces más rápido). El coproceso Al 8087 se le llama coprocesador porque comparte la corriente de instrucciones de un programa con el procesador principal (8088/8086) y a veces actúan en paralelo. Cuando se ejecuta un programa híbrido (con instrucciones 8088/8086 y 8087), cada microprocesador ejecuta las instrucciones que reconoce, es decir, intercepta las propias. 779 Para incluir las instrucciones del 8087 en un módulo fuente. existen dos vías: ) Insertando directamente las instrucciones 8087, que generan códigos correspondientes a la instrucción ESC (escape). Mediante la propia instrucción ESC (escape) del 8088/8086. Con la instrucción ESC, el 8088/8086 calcula la dirección de memoria, lee el contenido de esa dirección, pero lo ignora y pasa a la instrucción siguiente. Sin embargo, como el 8087 recorre la misma corriente de instrucciones. cuando detecta ESC. comienza a actuar: ) Coge el código de operación, la dirección calculada y el dato leido por el 8088/8086. Libera el bus y comienza a ejecutar, permitiendo que el 8088/8086 ' continúe ejecutando la instrucción siguiente. El 8087 está conectado al bus de datos y al bus de direcciones del sistema. Además de estas señales, existe la línea TEST, que parte del 8087 y llega al 8088/8086. Cuando se activa, el 8087 le indica al 8088/8086 que está libre, es decir, disponible para rcalizar operaciones. Esta señal TEST es la que permite el sincronismo entre ambos procesadores. Existen dos tipos de instrucciones ESC, que es la única que reconoce el 8087: , ESC sin referencia a memoria. EI 8088/8086 ignora la instrucción y el 8087 la ejecuta. Por ejemplo, FINIT, que corresponde a 0DBh,0E3h. , ESC con referencia a memoria. El 8088/8086 calcula la dirección, la pasa al bus de direcciones y lee el dato de la memoria. El 8087 toma entonces el control y ejecuta la instrucción. Si el 8088/8086 necesita que el 8087 acabe, a la instrucción ESC sigue una instrucción WAIT (el 8088/8086 espera a recibir la señal TEST, que le indica que el 8087 está ya disponible). para asesurarse que er 8087 está üor.'XT,?'rtt.""J:l"Ylfi""lilf:#": Gonstantes En el entorno de programación del 8088/8086 existen cinco tipos de constantes: binaria, octal, hexadecimal, decimal y carácter. En el entorno 8087 existen dos tipos de constantes adicionales: 780 Decimal real. Es un número decimal pero con punto decimal. Ejemplo: 3.141592 Decimal científico. Es un número decimal o decimal real seguido de E y un valor de exponente (de la potencia de l0). Ejemplos: 1.23458-2 (equivale a0.012345) y l7E4 (equivale a 170000). Arquitectura del 8087 Los elementos accesibles por el programador son los siguientes: r La pila (ocho elementos). o Los siete tipos de datos. o El entorno (siete palabras). La pila El funcionamiento de los registros internos del 8087 es diferente al del 8088/8086. No existen aislados ni con nombres distintos. Están estructurados en forma de pila cíclica de ocho elementos. Estos elementos se numeran de0a7. Cada elemento de la pila es de l0 bytes de longitud (80 bits), y el formato de los datos es real temporal, uno de los siete tipos de datos soportados por el 8087. El puntero de la pila indica en todo momento cuál es el elemento que se encuentra en lo alto de la pila, que llamaremos ST (Stock Top). Puede valer entre 0 y 7, es decir, señala el número del elemento. Para mover el puntero hay dos operaciones: Operación Función POP incrementar en I el puntero de pila PUSH decrementar en I el puntero de pila Como valor mnemotécnico, recordemos que, en el 8088/8086, PUSH decrementaba el registro SP y que POP lo incrementaba (en dos unidades). Es decir, si ST es 3, POP lo convierte en 4, y si ST es 3, PUSH lo convierte en 2. En el caso de que el puntero tengo el valor 7 y se haga POP, el nuevo valor es 0. Si tiene el valor 0 y se hace PUSH, el nuevo valor es 7. Es por esto que la pila es ciclica. La mayor parte de las instrucciones del 8087 usan los registros de datos de la pila. Por ejemplo, las instrucciones aritméticas utilizan uno o dos operandos de pila y el resultado se deja también en la pila. 781 ¿Cómo se direccionan los elementos de la pila? El direccionamiento no es absoluto, siempre se realiza mediante el elemento en lo alto de la pila (ST). Si se hace un POP, accedemos al elemento siguiente, ST(l), pues incrementamos en uno el puntero. Por el contrario, si se hace un pUSH. accedemos al elemento anterior, ST(7), pues se decrementa en uno el puntero. En ambos casos el elemento accedido se convierte en el nuevo elemento en lo alto de la pista (ST). El esquema siguiente ilustra este mecanismo: Pila POP + PUSH Pils + Pila sr(5) sr(4) sr(6) sr(5) sr(7) sr(6) ST(0) = 51 ST(7) sr(l) sr(o): sr sr(2) sr(l) sr(3) sr(2) sr(4) sr(3) Pils sr(5) sr(6) sr(6) sr(7) sr(7) sr(O): sr sT(0): sT sT(1) sr(l) sr(2) sr(2) sr(3) sr(3) sr(4) sr(4) sT(5) Ejemplo de instrucciones que acceden a la pila son: o FST ST(2) copia ST sobre ST(2) o FADDP ST(3),ST hace la operación ST(3) : ST(3) + ST y hace POP sobre la pila, es decir, ST(l) se convierte en el nuevo ST' . FADD ; hace la operación ST(1): ST(l) + ST y hace ; POP sobre la pila, es decir, ST(l) se convierte ; en el nuevo ST (donde se encuentra el resultado) Los siete tipos de datos El 8087 puede manejar siete tipos de datos: ¡ Enteros. Los números negativos se almacenan en forma de complemento a dos. Existen tres tipos: . Entero palabra (l palabra ó 16 bits). . Entero corto (2 palabras ó 32 bits). . Entero largo (4 palabras ó 64 bits). o Empaquetados. Ocupan l0 bytes (80 bits). Contienen dos dígitos BCD por byte, alineados ala derecha. Los bits 72a78 no tienen significado. El signo se almacena en el bit 79. 782 o Reales. Corresponden a los números de punto flotante de la notación científica. Existen tres campos: el signo (l bit), el exponente y la mantisa. La mantisa contiene los dígitos significativos. Existen tres tipos de números reales: o Real corto. Ocupa 2 palabras. o Real largo. Ocupa 4 palabras. ¡ Temporal. Ocupa l0 bytes. Este último es el formato que se utiliza en los registros de datos de la pila del 8087. Por su mayor precisión, da un margen suficiente en la práctica para los errores de redondeo acumulativos y de desborda- miento en cálculos intermedios. Cualquier otro tipo de dato que se convierta a este formato no pierde precisión. La tabla siguiente detalla el formato de cada tipo de datos. El número entre paréntesis indica la longitud (en bits). Formoto Signo entero palabra entero corto entero largo empaquetado l5 3l real corto real largo real temporal 3l Exponente Dígitos significativos 0-14 (ls) 0-30 (31) 0-62 (63) 63 o-7r (72) 79 63 79 Referencio del exponente zt -:o (tt) s2-62 64-78 (15) tal o-22 (23) 0-51 (52) 0-63 (64) 7Fh: 127 3FFh = 1023 3FFFh: 16383 La referencia del exponente es el valor del origen utilizado para poder almacenar exponentes positivos y negativos. Por encima de este valor, el exponente es positivo. Por debajo, el exponente es negativo. Por ejemplo, en el caso de real corto, el exponente 0 se almacena como 7Fh; el exponente l, como 80h; el exponente -1, como 7Eh, etc. El rango de los exponentes para los números reales es: Formato Rango exponente real corto real largo real temporal -127 a + 1024 -1023 a + 16384 a + 128 -16383 La tabla siguiente indica los rangos de los valores que se pueden almacenar en cada tipo de datos. 783 Formato Bytes entero palabra 2 4 entero corto entero largo Dígitos significativos Rango (los resles en valor l6 4-5 32 64 80 9 a + 32767 -32768 a +2xl0r8 -2xlOe a -9x1018 a ++9xl0r¡ 99...99 -99...99 a 3.37x1038 8.43x10-37 4.19 x 10-307 a 1.67 x 10308 3.4 x l0ae32 a l.2x 104e32 Bits 8 empaquetado l0 real corto real largo real temporal 4 32 8 64 80 l0 l8 l8 6-7 l9 -16 l5 absoluto) ESQUEMA DE LOS SIETE FORMATOS DE DATOS entero S l5l4 0 entero corto S 31 30 entero largo S 63 62 decimal empaq. S X I DD DD DD DD DD DD DD DD D.D 79 78 72 real corto SI EXP I 31 real largo SI EXP I real S 79 78 7U MANTISA 23 63 O temporal 7l MANTISA 5251 MANTISA EXP 6463 Notqs: S : Bit de signo. D = Dígito decimal codificado en binario (BCD) en un nibble. X : Bits sin significado. EXP : Exponente normalizado. Referencia exponente: 127 = 7Fh. real corto : real largo : 1023:3FFh. real temporal: 16383 = 3FFFh. Delante de la mantisa se supone el dígito binario " 1". DIRECTIVAS DE DEFINICION DE DATOS Para los siete tipos de datos soportados por el 8087 se aplican las directivas de definición de datos sieuientes: Formato Directiva Ejemplo entero palabra DW DD ENT-_PAL DW 12345 ENT-COR DD 12345678 ENT r AR DQ 123456',78901234 entero corto entero largo empaquetado real corto real largo real temporal DQ DT DD DQ DT EMPAQ DT -r234s67890r2 REAL-COR DD 3.14159 REAL r AR DQ 9.88-12 REAL-TEM DT 9.81234 Ya sabemos que, en el caso de números enteros, el almacenamiento es con los bytes invertidos, es decir, con el byte menos significativo primero. En el caso de números reales definidos mediante DD, DQ o DT, también se invierten los bytes. Ejemplo: almacenamiento del número N: 197.625 con DD (real corto). o Se convierte la parte entera (197) a binario: 197 : C5h : 1100 0101b o Se convierte la parte fraccionaria (0.625) a binario. Para ello se multiplica por 2: 0.625x2=1.250-l La parte entera (1) es el primer dígito binario de la parte fraccionaria. A la parte fraccionaria (0.250) se vuelve a aplicar el mismo procedimiento, y así sucesivamente: 785 0.250x2:0.500-0 0.500 x 2: 1.000- I Luego O.625:0.l0lb y N: ll00 0l0l.l0lb : l.l000l0l l0l x21 Se prescinde del I anterior al punto binario, por ser dato conocido. El exponente normalizado será: 7Fh + 7 : 86h : 1000 0l lOb. Los tres campos (signo, exponente y mantisa) serán: Signo Exponente (8 bits) 0 1000 0ll0 Mantisa (23 bits) 1000 l0ll 0100 0000 0000 000 El entorno Se compone de las siete palabras siguientes, y en este orden: Pslabra Contenido I estaoo 2 control tog J 4v5 dirección de la instrucción dirección del operando de memoria 6vj I B IC3 2 a J tagT ST , ICz I lc0 IR E6 E5 E4 E3 E2 EI CI CR I CP I IM M5 M4 M3 vt2 MI tag6 ta95 tag4 ta93 ta92 tagl tag0 ESTADO CONTROL TAG 4 5 Dirección de la instrucción 6 7 Dirección del operando de memoria PALABRA DE ESTADO (T) Refleja el estado en que se encuentra el 8087. Incluye: o Campo B de un bit que indica si el 8087 está ocupado o no. . Código de'condición (refleja el resultado de una comparación). Son cuatro bis (C0 a C3). 786 o Campo ST (indica el registro de la pila que es el alto de la pila). Son tres bits (valores 0 a 7). r Tipo de excepción (desbordamiento, división por cero, etc.). Existe un bit por cada tipo de excepción (bits El a E6). . Campo de petición de interrupción por parte del procesador principal (bit IR). Se puede examinar la palabra de estado transfiriéndola a memoria. Existen seis tipos de excepciones. Si ocurre alguna de ellas, se pone a uno el correspondiente bit de la palabra de estado: . Operación inválida. ¡ No normalizado. Intento de operación con un número no normalizado. r División por cero. o Desbordamiento por arriba (overflow). Exponente demasiado grande. o Desbordamiento por abajo (underflow). Exponente demasiado pequeño. o Precisión. Pérdida de precisión. PALABRA DE CONTROL (2\ Contiene: ¡ Máscaras de excepción (bits Ml a M6). Si el valor es l, se procesa la excepción correspondiente. Si el valor es 0, se invoca a una rutina del usuario. o Máscara (bit IM) para permitir/inhibir interrupciones. Si valor 0, interrupciones permitidas. Si valor 1, interrupciones no permitidas (enmascaradas). o Control de redondeo (campo CR). 00 - hacia el más próximo. 0l - hacia abajo (hacia--). l0 - hacia arriba (hacia + oo). 1l - truncar hacia cero. o Control de precisión (campo CP). 00 - 24 bits. 0l - reservado. 10 - 53 bits. ll - 64 bits. o Control del infinito (campo CI). 787 PALABRA TAG Q') Indica el contenido de cada elemento de la pila: e vacío. . cero, ::3i:x?"Í"ün1l?iffi }"":iJffi i:x'3}'no.*u,i,a¿or PALABRAS DE DIRECCIONES (4 A 7) Son punteros de excepción. Siempre que el 8087 ejecuta una instrucción, salva la dirección de esta instrucción. Si el operando es de memoria, también salva la dirección de este operando. El programador puede escribir un manejador de excepciones que acceda a estas direcciones para obtener información de la instrucción que provocó el error. Tratamiento de excepciones Cuando se produce una excepción, el 8087 realiza varias operaciones: l. Activa una de las banderas de excepción de la palabra de estado, 2. para indicar el tipo de error producido. Accede al campo de máscara de esa excepción (en la palabra de control) para saber si debe o no procesar la excepción. o Si la máscara es l, se ejecuta el procedimiento estándar de proceso de esa excepción. El coprocesador genera un número con todos unos en el exponente y una mantisa con tres valores posibles que representan + oo, -oo e indefinido. Si se sigue operando con este número en las siguientes instrucciones, el resultado sigue siendo del mismo tipo (infinito o indeterminado). Para borrar las banderas, se utiliza la instrucción FCLEX o se inicializa el 8087 mediante FINIT. . Si la máscara es 0, se invoca a una rutina del usuario. Se genera igualmente el número especial como resultado de la operación, pero además se produce una petición de interrupción por la línea INT. 788 El juego de instrucciones del 8087 Todos los nombres simbólicos de las instrucciones 8087 empiezan por F. Si acaban en P (de POP), quiere decir que la pila se cargará con el resultado de la operación. El conjunto de instrucciones del 8087 se puede dividir en los seis grupos siguientes: r Instrucciones de transferencia de datos. o Instrucciones aritméticas. ¡ Instrucciones de comparación. o Instrucciones de cálculo de funciones trascendentes. o Instrucciones relativas a constantes. o Instrucciones de control del microprocesador. INSTRUCCIONES DE TRANSFERENCIA DE DATOS Sirven para mover operandos entre los elementos de la pila o entre el elemento en lo alto de la pila (ST) V la memoria. Se pueden hacer transferencias con los siete tipos de datos que maneja el 8087 (si se mueven a la pila se convierten a formato real temporal). Estas instrucciones actualizan automáticamente la palabra tog para reflejar el contenido de cada elemento de la pila. Las instrucciones de transferencia de datos son: FLD FST FSTP FXCH FILD Cargar real Almacenar real Almacenar real y POP Intercambiar números reales FIST FISTP Cargar entero Almacenar entero Almacenar entero y POP FBLD FBSTP Cargar decimal empaquetado Almacenar decimal empaquetado y POP INSTRUCCIONES ARITMETICAS Permiten hacer las operaciones aritméticas elementales (suma, resta, multiplicación y división) y otras como raiz cuadrada, valor absoluto, etc. Los operandos pueden ser elementos de la pila o de memoria. El resultado se almacena sobre la pila en formato real temporal. Los. operandos de memoria pueden ser tipo real (corto o largo) o entero (palabra o corto). 789 Las instrucciones aritméticas elementales tienen el esquema siguiente: Instrucción Foper Foper ST(i),ST Foper ST,ST(i) Foper MEM Floper MEM Ejemplo FADD FSUB ST(2),ST FSUB ST,ST(2) FMUL MEM FIDIV MEM Destino Fuente sr(l) ST ST ST(D ST(D ST ST ST MEM MEM Operondo de memoria real corto, largo entero palabra, corto Siendo: oper Operoción ADD dest no:destino+fuente dest no : destino -fuente dest no: fuente -destino dest no:destinoxfuente dest no : destino ,/ fuente dest no : fuente ,/ destino SUB SUBR MUL DIV DIVR Además de las formas normales, existen dos en modo inverso (reversed), que realizan la resta y la división considerando los operandos al revés. caso de que no exista ningún operando, supone destino : ST(1), - En el sr y se hace además PoP sobre la pila, de modo que el resultado fuente: se sitúa en lo alto de la pila. Por ejemplo, FADD calcula ST(l) : ST(l) + ST y hace POP sobre la pila (incrementa en uno el puntero de la pila), con lo que el nuevo elemento en lo alto de la pila contiene el resultado. Las instrucciones aritméticas son: Suma FADD FADDP FIADD Sumar real Sumar real y POP Sumar entero Resta FSUB FSUBP FISUB FSUBR FSUBRP FISUBR 790 Restar real Restar real y POP Restar entero Restar real modo inverso Restar real modo inverso y POP Restar entero modo inverso Multiplicación FMUL FMULP FIMUL Multiplicar real Multiplicar real y POP Multiplicar entero División FDIV FDIVP FIDIV FDIVR FDIVRP FTDIVR Dividir real Dividir real y POP Dividir entero Dividir real modo inverso Dividir real modo inverso Y POP Dividir entero modo inverso Otras operaciones FRNDINT FXTRACT Raíz cuadrada Escalar por una potencia de dos Resto parcial Redondear a entero Extraer exponente Y mantisa FABS FCHS Valor absoluto Cambiar signo FSQRT FSCALE FPREM INSTRUCCIONES DE COMPARACION Sirven para comparar dos operandos. El primero (destino) es ST, y el segundo es utt operándo de pilá o de memoria. Para ello resta fuente de deitino y genera un código de condición en la palabra de estado. Para alalizar el contenido del código de condición hay que tranpferir a memoria la palabra de estado (mediante la instrucción FSTSW). Como otras instrucciones podrían cambiar el código de condición' es recomendable hacerlo inmeáiatamente después de la instrucción de comparación. Una vez en memoria, el sistema más utilizado es el de mover el byte de estado (más significativo) al registro de banderas. comparar FCOM ... transferir palabra de estado a ESTADO FSTSW ESTADO esperar a que se termine de almacenar FWAIT MOV AH.BYTE PTR ESTADO + I ; AH : byte de estado (más ; significativo) SAHF ; cargar byte de estado sobre el registro de banderas En este momento se pueden utilizar las instrucciones de bifurcación condicional del 8088/8086: 791 JB ... ; bifurcar si ST ( fuente o ST ? fuente JBE ... ; bifurcar si ST ( fuente o ST ? fuente JA ... ; bifurcar si ST ) fuente o no ST ? fuente JAE ... ; bifurcar si ST ) fuente o no ST ? fuente JE ... ; bifurcar si ST : fuente o ST ? fuente JNE ... ; bifurcar si ST # fuente o no ST ? fuente El sódigo de condición (los cuatro bits C0 a C3) generado por las instrucciones de comparación son: ¡ Instrucciones FCOM, FCOMP, FCOMPP y FICOM: C3 C2 CO Resultado comparoción 0 0 0 0 0 0 I I ST fuente ST fuente ST = fuente ST ? fuente I I ) ( I 0 o Instrucción FTST: Resultado comparación C3 CO 0 0 0 I I 0 ST:0 (positivo o negativo) I I ST no comparable ST positivo ST negativo o Instrucción FXAM: C3 0 0 0 C1 CO Resultado comparación 0 0 0 0 + no normalizado + no es un número I I 0 0 0 0 0 0 I I normalizado -no +no es un número 0 0 0 0 0 I I I I I 0 0 I 0 0 0 -infinito +0 0 0 I vacío 0 0 I I 0 I 0 0 + denormalizado I 0 I vacío I I I 0 I I I I I I I I I 792 C2 I I I I +normalizado + infinito -normalizado -0 vacío -denormalizado vacío Las instrucciones de comparación son las siguientes: FCOM FCOMP FCOMPP FICOM FICOMP FTST FXAM Comparar real Comparar real y POP Comparar real y POP dos veces Comparar entero Comparar entero y POP Comparar alto de la pila con cero Examinar alto de la pila INSTRUCCIONES DE CALCULO DE FUNCIONES TRASCENDENTES Sirven para calcular funciones trigonométricas (directas e inversas), logarítmicas y exponenciales. Operan sobre el elemento que se encuentra en lo alto de la pila (ST) o sobre dos elementos de la pila. El resultado se devuelve sobre la pila. Las instrucciones son: FPTAN FPATAN F2XMI FYL2X FYL2XPI Tangente parcial (X comprendido entre 0 y n/4) Arcotangente parcial (0< Y< X < + infinito) X2- I (X comprendido entre 0 y 0.5) Y'logrX Y'logr(X + 1) INSTRUCCIONES RELATIVAS A CONSTANTES Sirven para cargar una constante en ia pila, que se almacena en formato real temporal (19 digitos decimales). FLDZ FLDI FLDPI FLDL2T FLDL2E FLDLG2 FLDLN2 Cargar 0.0 Cargar 1.0 Cargar pi Cargar logrl0 Cargar logre Cargar log2:logtoZ Cargar ln 2 : log2 (logaritmo neperiano) INSTRUCCIONES DE CONTROL DEL MICROPROCESADOR Corresponden a actividades internas del 8087, como por ejemplo: o Inicializar el microprocesador. o Preservar la información de estado del procesador. 793 o Cambiar el modo de redondeo. o Permitir/inhibir interrupciones. ¡ Manejo de excepciones. r Cambio de tareas. Muchas de estas instrucciones tienen una forma alternativa, que se distinguen por tener una "N" como segundo carácter del nombre. Eito indica al ensamblador que no incluya previamente la instrucción wAIT (en su lugar se incluye la instrucción NoP). Se usa en situaciones en que la instrucción WAIT puede conducir a una espera indefinida. Por ejemplo, cuando las interrupciones de la cPU no están permitidas y el 8087 puede potencialmente generar una interrupción, debe usarse en forma no wait. Si las interrupciones de la cPU están permitidas (que es el caso normal cuando se ejecuta un programa), debe usarse la forma normal (woit). El 8087 puede generar una petición de interrupción del 8088/8086 como consecuencia de haber detectado una excepción. I as interrupciones se permiten/inhiben mediante la máscara de interrupciones de la palabra de control (0: permitidas, I : inhibidas). Para asegurarse de que las instrucciones de control del procesador 8087 se ejecutan después de que el 8088/8086 termine de ejecutar la instrucción en curso, debe usarse la forma normal (wait) de la instrucción. La instrucción wAIT del 8088/8086 permite sincronizar la cPU con el 8087 para que no se ejecute la siguiente instrucción hasta que el 8087 no termine de ejecutar la instrucción en curso. Para llevar a cabo esto, el programador debe insertar la sentencia FWAIT (nombre simbólico alternativo de WAIT) inmediatamente antes de una instrucción 8088/8086 para que pueda acceder a una dirección de memoria accedida previamente por una instrucción 8087. Excepto para FNSTENV y FNSAVE, todas las instrucciones de control es1án autosincronizadas y no es necesario incluir FWAIT. FINIT/FNINIT FDISI/FNDISI ....... FENI/FNENI . . FLDCW FSTCW/FNSTCW FSTSW/FNSTSW .... FCLEX/FNCLEX .... FSTENV/FNSTENV FLDENV FSAVE/FNSAVE FRSTOR FINCSTP FDECSTP FFREE FNOP FWAIT Inicializar eI8087 Desactivar interrupciones Activar interrupciones Cargar palabra de control Almacenar palabra de control Almacenar palabra de estado Borrar excepciones Almacenar entorno Cargar entorno Salvar estado Restaurar estado Incrementar puntero de la pila Decrementar puntero de la pila Liberar (borrar) registro No operación Esperar a que termine el 8087 (parar el 8088/ 8086) 794 Instrucciones 8087 (por orden alfabét¡col Instrucción Lógico F2XMI ST:2sr -1 FABS 51: lSTl FADD FADD ST,ST(i) FADD ST(i),ST FADD MEM ST : ST + ST(l), POP ST :ST+ST(i) ST(i): ST(i) + ST ST :ST+MEM FADDP ST(i),ST ST(i): ST(i) + ST, POP FBLD MEM PUSH, ST : MEM FBSTP MEM MEM: ST, POP FCHS ST FCLEX/FNCLEX Borrar campos de la palabra de estado: banderas de excepciones, bandera de interrupciones y bandera de ocupado. FCOM FCOM Sr(i) FCOM MEM sT-sr(l) sr-sT(i) FCOMP FCOMP ST(i) FCOMP MEM sT-sr(l), PoP sT-sr(i), PoP FCOMPP sT-sr(l), PoP, POP FDECSTP puntero - pila : puntero- Pila- I FDISI/FNDISI Inhibir interrupciones. FDIV FDIV ST,ST(i) FDrV ST(i),ST FDIV MEM ST : ST(l) / ST, POP ST : ST'/ ST(i) sT(i):sT(i)/sT ST :ST/MEM ST(i) : ST(i) / ST, POP FDIVP : -ST ST-MEM ST-MEM, POP 796 FDIVR FDrVR ST, ST(i) FDIVR ST(i),ST FDIVR MEM ST(l): ST / ST(l), POP ST :ST(i)/ST ST(i): ST / ST(i) ST :MEM/ST FDIVRP ST(i),ST ST(i): ST / ST(i), POP FENI/FNENI Permitir interrupciones FFREE ST(i) TAC(i) vacío FIADD MEM ST:ST+MEM FICOM MEM ST-MEM FICOMP MEM ST-MEM, POP FIDIV MEM ST: ST / MEM FIDIVR MEM ST: MEM / ST FILD MEM ST FIMUL MEM ST: ST * MEM FINCSTP puntero-pila : puntero_pila + I FINIT/FNINIT Inicializar 8087 FIST MEM MEM : ST FISTP MEM MEM: ST, POP FISUB MEM ST: ST-MEM FISUBR MEM ST: MEM-ST FLD ST(i) T' : ST(i), PUSH, ST: T, FLD MEM PUSH, ST : MEM FLDCW MEM palabra de-control : MEM FLDENV MEM entorno : MEM FLDLC2 PUSH, ST: log,,,2 : MEM FLDLN2 PUSH, ST: log2 FLDL2E PUSH, ST: logze FLDL2T PUSH, ST = logzl0 FLDPI PUSH, ST = n FLDZ PUSH,ST= *0.0 FLDl PUSH, ST = 1.0 FMUL ST,ST(i) FMUL ST(i),ST FMUL MEM ST :ST*ST(i) ST(i): ST(i) * $1 ST :ST * MEM FMULP ST(i),ST ST = ST * ST(i), POP FNOP ST: ST FPATAN Tr : ÍItc tan ST(I) : T' FPREM POP, ST ff, ST ST : resto d. FPTAN Y/X: tan(ST), ST: Y, PUSH, ST: X sr(1) FSAVE/FNSAVE : entero más próximo a ST estado : MEM MEM : estado FSCALE ST: ST * 2sr(r) FSQRT ST FST Sr(i) FST MEM MEM: ST FRNDINT FRSTOR MEM FSTCW/FNSTCW MEM ST : raíz cuadrada de ST ST(i) :51 MEM : palabra-de-control FSTENV/FNSTENV MEM MEM: entorno FSTP ST(i) FSTP MEM ST(i) : ST, POP MEM: ST, POP 797 FSTSW/FNSTSW MEM MEM : palabra_de_estado FSUB FSUB ST,ST(i) FSUB ST(i),ST FSUB MEM ST(l): ST(I)-ST, POP FSUBP ST(i),ST ST : ST-ST(i) sT(i) : ST(i)-sT ST = ST-MEM ST(i) : ST(i)-ST, POP FSUBR FSUBR ST, ST(i) FSUBR ST(i),ST FSUBR MEM ST(1): ST-ST(1), POP ST : ST(i)-ST ST(i) = ST-ST(i) ST : MEM-ST FSUBRP ST(i),St ST(i) : ST-ST(i), POP FTST ST : ST-0.0 FWAIT Esperar a que termine el 8087 FXAM Examinar registro ST de la pila FXCH FXCH Sr(i) Tr : ST(1), ST(l): ST, ST : T, T, : ST(i), ST(i) : ST, ST : T, FXTRACT Tr : exp(ST), Tz : mantisa(ST), ST : T,, PUSH, ST : Tz FYL2X T' : ST(1) * logz(ST), PoP, ST: T, FYL2XPI Tr : ST + l,T2:ST(1) * log2Tr, POP, ST:T, Ejemplo Supongamos que queremos realizar el cálculo: RES = AAxBB CC Un sistema sería el siguiente: FINIT FLD CC FLD BB 798 inicializar el 8087 push, ST: CC push, ST: BB FLD AA FMUL ST,ST(1) FDIV ST,ST(2) FST RES push, ST: AA ST:STxST(1):AAxBB ST: ST / ST(2): AA x BB / CC RES:ST:AA*BB / CC La pila después de la instrucción FLD AA es: ST sr(1) sr(2) Otro sistema. más sencillo. sería: FINIT AA FLD FMUL BB FDIV cc inicializar el 8087 push, ST = AA ST: ST * BB :4"{ * BB FST RES = ST ST:ST / CC:AA*BBlCC RES : AA {,BB / CC Las vers¡ones del programa MACRO ASSEMBLER y las instrucciones 8087 La versión 1.0 del MACRO ASSEMBLER no reconoce las instrucciones del 8087. Para incluirlas, es necesario definir macros mediante WAIT y ESC. Por ejemplo, la macro para definir la instrucción FST es: FST MACRO VALOR WAIT ESC WAIT ENDM ; esperar a que quede disponible el 8087 OAh,VALOR ; FST ; esperar a que acabe el 8087 Afortunadamente, la versión 3.0 ya reconoce las instrucciones 8087. Para ensamblar el módulo fuente hay que utilizar el comando MASM/R. 799 Apéndice A Juego de caracteres ASGII estándar Dec. 0 16 32 Hex. 0 123456 00 NUL DLE SP ll SOH DCI 22 STX DC2 aa JJ ETX DC3 # 44 EOT DC4 $ 55 ENQ NAK Vo 66 ACK SYN & 77 BEL ETB 88 BS CAN ( 99 HTEM) l0A LF SUB l1 B VT ESC + 12C FFFS, 13D CR GS t4E SO RS 15F SIUS/ ! >k NUL - Nulo /N¿rl//. 48 64 80 lt2 7 0@P'p lAaaq 2BRbr 3CScs 4DTdt 5EUeu 6FVfv TC;Wgw 8HXhx 9IYiy :JZjz ;Ktk{ Mlm) ?OoDEL SOH - Comienzo de cabecera (Stort of Heading). 800 96 NUL Nulo /Nalf. Comienzo de cabecera (Start of Heqding). Comienzo de texto (Start of Text). ETX Fin de texto (End of Text). Fin de transmisión (End of Transmision). EOT ENQ Petición (Enquiry). ACK Reconocimiento (A c know led ge). BEL Altavoz (Bell). Retroceso (Backspace). BS HT Tabulación horizontal (Horizontal Tobulotion). Alimentación de linea (Line Feed). LF VT Tabulación vertical (Vertical Tabulotion). Alimentación de página (Form Feed). FF Retorno de carro (Carriage Return). CR - Shift Out. SO - shift In. SI SOH STX DLE - Escape de enlace de datos (Data Link Escape). DC - Control de disposit\vo (Device Control). NAK - Reconocimiento negativo (Negative Acknowledge). SYN - Parada de sincronismo (Synchronous ldle). ETB - Fin de bloque de transmisión (End of Transmission Block). CAN - Cancelar (Concel). EM - Fin del medio (End of Medium). SUB - Sustituir (Substitute). ESC - Escapar (Escape). FS - Separador de fichero (File Seporator). GS - Separador de grupo (Group Seporator). RS - Separador de registro (Record Separator). US - Separador de unidad (Unit Separator). SP - Espacio (blanco). DEL - Borrar (Delete). 801 Juego de caracteres (00-7F) ASCII para el IBM PC Valor cloc¡m8l 802 I 0 r6 32 48 64 80 96 tt2 I 2. 3 4 5 6 7 .¡] Valor hexadecima 0 0 0 Blanco (Nulo) I l 2 2 3 3 4 4 5 5 6 6 7 7 8 8 9 9 r0 A ( p I I A a a q t rl 2 B R b r ? !! # 3 C S c S I qT $ 4 D T d t 'r I % 5 E U e u ó I & 6 F V f v O t , 7 G w t)g w ( 1 8 H X h x Blanco Espacío . c c o J ) * d ll B t2 C I t_ r3 D ah l4 E ) r5 F + Y + 0 @ P 9 a a a ) ) a ? I Y I v J Z j K t k I L M I m n N o z I I t I o A Juego de caracteres (80-FFl ASCII para el IBM PC Valor decimal l} I t28 t44 r60 t16 t92 208 224 240 Valor hexaoectma 8 9 0 0 a É I I ü 2 2 J 3 4 4 5 5 6 6 7 7 8 8 9 9 r0 A ll B t2 C r3 D t4 E l5 F A , B A /\ a q A e e A lfl I' IL 2 /\ ¿ r t - r1 Y2 TT r tr o J tr v ? v e ü I c oc p + o _T| ó tL 0 t- J e o C¿ o JL :il r d c^.- Vq oo I Y I ó A A f (( R )) J -J-l rL _l a T I \ F .* u \ u \ E :.:.: o u á o n \ \ a o N= o D L a 2 I a 2 , .E e o a C € n n 2 I BLANCC 'FF' 803 Garacteres para el dibujo de recuadros t94 2LB r T L1e 11-91 2to F 203 T 186 ll I r-e5 l:-gz*lreo 2o4 lf zoa jf ),9zLrJ2rl 2OO U l_96 : 205 rL 209 n183 lf zrs-lf ll raz 1J-84 2I4 n r-eg F zra* J l-Bl- r-ee zL]- rL 207 21_O 'Tr T 2L2trJtgo lL J t8g 208 Caracteres de relleno y sombreado nitad del carácter 804 carácter completo 22O 1 223 T L76 ',,,' zzt | 222 rzaf; zrcl I il res Jl rgg 202 t_9 3 213 f Tl-87 177 ii.:, Apéndice B Tabfa de potencias de 2 I 0 2 I 4 2 8 J l6 4 32 l 64 6 r28 7 256 512 | 024 2 048 4 096 8 9 l0 il 8 t92 t2 t3 16 384 32 768 t4 l5 65 536 t3l 072 218 474 976 7 t0 656 s62 949 953 42t 3t2 125 899 906 842 624 2 251 799 813 685 248 4 503 599 627 37A 496 48 49 50 9 007 199254740992 53 l8 014 398 s09 481 984 36 028 797 0t8 963 968 54 72057 594037 927 936 r44 rr5 188 075 855 872 56 | 288 230 376 tst 7 rt 744 576 460 752 303 423 488 I t52 92r 504 606 846 976 2 30s 843 009 2r3 693 9s2 4 6tr 6860t8 427 387 904 9 223 372 036 854 775 808 r8 446 744 073 709 551 616 36 893 488 147 4t9 103 232 5l 52 55 57 58 59 60 6l 62 63 64 65 805 2N 262 144 524 288 I 048 s76 N l8 t9 73 786 976 294 838 206 464 r47 573 952 589 67 6 412 928 295 t47 90s 1',79 3s2825 856 66 67 590 295 810 358 705 651 7t2 68 69 70 2 361 183 241 434 822 606 848 7l 72 3l 4 722 366 482 869 645 2r3 696 9 444 732 965 739 290 427 392 l8 889 465 931 478 580 854784 37 778 931 862 957 t6t 709 568 75 ss1 863 72s 914 323 419 136 151 l15 727 451828646838272 302231 454903 65',t 293 676 544 604 462 909 807 3r4 587 353 088 | 208 925 819 614 629 174706 176 80 8 589 934 s92 JJ 2 417 851 639 229 258 349 4r2 352 81 t7 179 869 184 34 82 34 359 738 368 35 687r9 476736 36 137 438 953 472 274 8',77 906 944 549 755 813 888 3t 38 39 4 835 703 278 458 516 698 824704 9 671 406 556917 033 397 649 408 19 342 813 1 13 834 066 795 298 816 38 685 626 227 668 133 590 597 632 77 371 2s2 455 336 267 t8t 195 264 r54742 504 910 672 534362390 528 309 485 009 821 345 068 72478r 056 88 89 2097 152 4 194 304 20 N 2N 2l 22 8 388 608 t6 7-r'7 216 33 554 432 24 67 108 864 26 134 217 '.728 268 435 456 536 870 9r2 | 0'73'.l41 824 2 r47 483 648 25 2',7 28 29 30 4294967 296 5lt 627 776 40 2 r99 023 255 552 4398046 5ll 104 4l 42 8 796 093 022 208 t7 s92 186 044 416 35 184 372088832 70 368 744 177 664 t40 737 488 355 328 43 1 099 44 45 46 47 l 180 591 620717 4tt 303 424 618 970 0r9 642690 137 449 562 ttz | 237 940 039 285 380 274 899 124 224 2475 880 078 570',760 549798248 448 4 951 760 l5'7 l4l 521 099 596 496 896 9 903 520 3r4 283 042 199 192 993',792 l9 807 040 628 566 084',398 385 987 584 39 614 081 257 132 168 796 771 975 168 73 74 75 76 77 78 79 83 84 85 86 87 90 9l 92 93 94 95 Tabla de potencias de 16 I 806 0 l6 I 256 4 096 65 536 l 048 576 2 J 4 5 16777 2t6 6 268 435 456 7 4294967 296 8 N l6N 68 719 476 736 l 099 5lr 627 776 t7 592 186044 416 28t 4749167t0 656 4 503 599 627 370 496 72057 594037 927 936 I rsz92l 504 606 846976 t8 446 744 073'.709 551 616 295 14'.7 905 179 352 825 856 4',722 366 482 869 645 2r3 696 75 557 863 725 9t4 323 4t9 t36 | 208 925 819 614 629 174 706 176 t9 342 813 l13 834 066 795 298 8t6 309 485 009 821 345 068 724181 056 4 951 760 ts',? r4t 52t 099 596 496 896 79 228 162 5r4 264 337 593 543 950 336 9 l0 ll t2 l3 t4 l5 l6 l7 l8 t9 20 2l 22 23 L+ | 267 650 600 228 229 401 496 703 205 376 25 20 282 409 603 651 670 423 947 25t 286 016 324 5r8 553 658 426 726 783 I 56 020 576 256 s 192 296 858 534 827 628 530 496 329 220 096 83 076 749',736 557 242056 48'7 94r 267 52r s36 1 329 227 995 784 9t5 872 903 807 060 280 344 576 2r 267 647 932 558 653 966 460 9r2 964 485 5r3 216 26 340 282 366 920 938 463 463 374 607 43r 768 zrt 456 s 444 5r7 870 735 015 415 4r3 993 718 908 29r 383 296 87 ll2 285 93t 760 246 646 623 899 502 532 662 132 736 | 393 796 574 908 163 946 345 982 392 040 s22 594 123 776 22 300 745 198 530 623 l4l 535 718 272 648 361 505 980 416 356 81 | 923 t76 489 970 264 571 492 362 373 784 095 686 656 5 708 990 770 823 839 524 233 r43 877 797 980 545 530 986 496 27 28 29 30 3l JJ 34 35 36 JI 38 807 Apéndice C Tabla de conversión hexadecimal/decimal 4 5 2 J 0 Hex. Dec. Hex. Dec. Hex. Dec. Hex. Dec, Hex. Dec. 00 00 00 00 00 00 I I 048 576 I 65 536 | 4096 | 256 l16 ll 2 2097 r52 2 t3t 072 2 8192 2 5t2 232 22 3 3 r45 728 3 196 608 3 12288 3 768 3 48. JJ 4 4 t94304 4 262 t44 4 16384 4 1024 464 44 5 5 242880 5 327 680 5 20 480 5 1280 580 )) 6 6291 456 6 393216 6 24 576 6 1536 696 66 7 7 340032 7 458752 7 28672 7 t'792 7 lt2 77 Hex. Dec. 8 8 388 608 9 9 437 t84 A l0 485 760 B ll 534 336 c 12 582912 D 13 631 488 E 14 680 064 F 15 728 640 808 8 9 A B C D E F 524 288 589 824 655 360 720 896 786 432 851 968 9t1 504 983 040 8 9 A B c D E F 32768 36864 40960 45 056 49 152 53248 573M 6t 440 8 9 A B c D E F 2048 2304 2560 2816 3072 3328 3584 3840 8 9 A B c D E F 128 144 160 176 192 208 224 240. 88 99 Al0 Bll ct2 D13 E14 F15 EJEMPLOS DE UTILIZACION DE LA TABLA l. Conversión de hexadecimal a decimal de A3D: A en columna 2 :2560 (valor decimal) 3 en columna I = D en columna 0: 48 (valor decimal) 13 (valor decimal) ,6rt (rrl", d..t."l) 2. Conversión de decimal a hexadecimal de 2621: Valor original :2621 Número inferior o igual más próximo :2560 - A00 (hexadecimal) Número inferior o igual más próximo: 48 * 30 (hexadecimal) Diferencia: 6l l3 Diferencia : Número inferior o igual más próximo: 13 Diferencia = D (hexadecimal) 0 A3D (hexadecimal) 80ff Apéndice D Tiempos de ejecución de las instrucciones Las tablas que vienen a continuación sirven para calcular el número de ciclos del reloj del microprocesador 8088/8086 que son necesarios para la ejecución de cada tipo de instrucción. Para convertir ciclos a nanosegundos, hay que tener en cuenta la frecuencia del reloj del microprocesador: frecuencia (f) : 4,77 MHz : 4'170 000 ciclos/seg. período (l ciclo) : l/f :210 nanoseg9. :210 x 10-e segs. frecuencia (f) : 8 MHz : 8 000 000 ciclos/seg' período (l ciclo) : l/f :125 nanosegs. : 125 x 10-e segs. La tabla D-l indica el número de ciclos necesarios por cada modo de direccionamiento de la memoria. Es la variable M que aparece en las instrucciones de la tabla D-2 que hacen referencia a la memoria. Al utilizar la tabla D-2, hay que tener en cuenta: ¡ Algunas instrucciones consumen más ciclos si sus operandos son de tipo palabra que de tipo byte. En estas instrucciones aparece "b(p)", en donde "b" es el número de ciclos si los operandos son de tipo byte y "p" es el número de ciclos si los operandos son de tipo palabra. o En las instrucciones de bifurcación (iump) y de ejecución de bucles (loops), aparece "a ó b" . Si se realiza la transferencia de control, hay 810 que usar el valor mayor ("a"). Si no se realiza, hay que usar el valor menor ("b"). o En las instrucciones de manejo de cadenas (strings), aparece "rep", que indica valor por cada repetición. o En las instrucciones de manejo de bits, aparece "bit", que indica valor por cada bit. ETEMPLO DE UTILIZACION DE LAS TABLAS Vamos a calcular el número de ciclos de la instrucción: MOV AX,ES:TABLAISI] Como esta instrucción es del tipo "MOV registro,memoria", la tablaD-2 nos indica 8(12) + M. Como los operandos son de tipo palabra, hay que seleccionar 12, es decir, 12 + M. Para calcular M nos vamos a la tabla D-1. Como el modo de direccionamiento del operando es "Indice i Desplazamiento", hay que seleccionar 9. Pero como además hay sustitución del segmento (ES), hay que añadir dos ciclos. Luego M : 9 -f 2 : ll. El número total de ciclos será: 12 * M = 12 + ll:23. Tabla D-l Modo de direccionamiento de la memoria Desplazamiento Formato del operando desplazamiento etiqueta Base BX] Indice BP] SI] Ciclos* 6 5 DI] Base + Desplazamiento Indice + Desplazamiento Base + Indice Base * Indice + Desplazamiento [BX] + desplazamiento [BP] + desplazamiento [SI] + desplazamiento [DI] + desplazamiento 9 lBXltsrl tBXltDrl 7 tBPltsrl IBPltDrl 8 tBXltSIl * desplazamiento tBXltDIl + desplazamiento l1 tBPltSU + desplazamiento tBPltDIl + desplazamiento l2 * Sumar dos ciclos cuando se utilice sustitución de segmento. 8f1 Tabla D-2 Instrucción Bytes AAA 4 I AAD 60 2 AAM 83 I AAS 4 I reglstro, reglstro a J registro,memoria memoria,registro registro,valor 9(13) + M z 2-4 2-4 ADC ADC ADC ADC ADC ADC ADD ADD ADD ADD ADD ADD AND AND AND AND AND AND CALL CALL CALL CALL CALL memoria,valor acumulador,valor 16(24) + M I - 3-4 l7(25) + M 3-6 4 ¿-J J 2 9(13) + M 2-4 2-4 A registro,registro registro,memoria memoria,registro registro,valor 4 3-4 memoria,valor l7(25) + M 3-6 acumulador,valor 4 t6(24) + M registro, registro J registro,memoria memoria,registro registro,valor 9(13) + M 'tA t6(24) + M 2-4 4 3-4 memoria,valor l7(15) + M acumulador,valor 4 3-6 z-J procedimiento---near z5 36 procedimiento--far p unt ero-tipo _-rn emori a I 6 29 +M 2 J 5 2-4 1A 2 57+M 2-4 CBW 2 I CLC 2 I CLD 2 I CLI ¿ I CMC 2 I J 2 CMP CMP CMP 812 Ciclos p untero ---registro I 6 -tipo puntero-tipo__¡nemoria3 2 reglstro,reglstro reglstro,memona memona,reglstro 9(13) + M 1A 16(24) + M 2-4 Tabla D-2 (continuación) Instrucción CMP CMP CMP registro,valor memoria,valor acumulador,valor Ciclos A 10(14) + M 4 Bytes 3-4 3-6 2-3 CMPS cadena-destino.cadena__fuente CMPS (repetir)cadena-destino,cadena__fuente 22(30) 9 + 22(30)/rep I CWD 5 I CMPSB : CMPS CMPSW : CMPS DAA I DAS DEC DEC DEC DIV DIV DIV DIV ESC ESC I 4 I registroS t J 2 registrol6 2 I I memoria l5(23) + M registro8 80-90 registrol6 t44-t63 memoria8 (86-96) + M 1A L-+ memorial6 (ls4-172\ + M 2-4 valor,memoria 8(12) + M 2-4 valor,registro 2 2 HLT 2 IDIV registroS lDlV registrol6 IDIV memoria8 IDIV memorial6 IMUL registro8 IMUL registrol6 IMUL memoria8 IMUL memorial6 l0l-l l2 165-184 (107-l l8) + M (175-194) + M 80-98 2 2 2 2 2-4 2-4 128-t54 2 2 (86-104) + M (138-164) + M 2-4 2-4 2 I IN IN acumulador,valor8 l0(14) acumulador.DX 8(12) INC INC INC registro8 J registrol6 2 2 I memoria l5(23) + M 2-4 52 I 2 INT INT a J valor (no tipo 3) 5l 813 Tabla D-2 (continuación) Instrucción INTO IRET Bytes s3ó54 I I Jccc etiqueta-corta 16o4 2 JCXZ etiqueta_corta l8ó6 2 JMP JMP JMP JMP JMP JMP etiqueta corta l5 l5 l5 etiqueta __near etiquetaJar puntero-tipo__-rnemorial6 puntero-tipo__registrol6 puntero-tipo---rnemoria32 LAHF l8+M 2 J 5 1^ L-+ ll 2 24 +M 1A + I LDS registro 16,memoria32 24 +M 2-4 LM registro l6,memoria l6 2+M ¿-+ LES registro l6,memoria32 24 +M 2-4 2 I LOCK LODS LODS cadena--fuente t2(r6) I (repetir)cadena__fuente 9 + 13(17)/rep I LODSB LODSW : LODS : LODS LOOP etiqueta-corta LOOPE etiqueta_corta LOOPNZ : LOOPNE 1765 18ó6 2 2 LOOPNE etiqueta-corta 19ó5 2 MOV MOV MOV MOV MOV MOV MOV MOV MOV MOV MOV 10(14) l0(14) J a J 2 2 8(12) + M 9(13) + M 2-4 LOOPZ :LOOPE 814 Ciclos memoria.acumulador acumulador,memoria registro,registro registro,memoria memoria,registro -^ L-+ registro,valor memoria,valor 4 l0(14) + M 3-6 segmento,registrol6 segmento,memorial6 registrol6,segmento memoria.sesmento ,segme 2 2 8(12) + M 2-4 2 2 2-4 9(13) + M Tabla D-2 (continuación) Ciclos Instrucción MOVS cadena-destino,cadena--fuente MOVS (repetir)cadena-destino,cadena--fuente MOVSB : MOVS Bytes l8(26) I 9 + 17(25)/rep I 70-77 I l8-133 2 2 (76-83) + M (128-143) + M 2-4 J 2 16(24) + M 2-4 J I J 2 t6(24) + M 2-4 J 2 9(13) + M L-+ 2-4 MOVSW = MOVS MUL MUL MUL MUL registro8 NEG NEG registro memoria registrol6 memoria8 memorial6 NOP NOT NOT OR OR OR OR OR OR registro memoria OUT OUT POP POP POP registro,registro registro,memoria memoria,registro registro,valor 16(24) + M / + 2-4 3-4 memoria,valor l7(25) + M 3-6 acumulador.valor 4 z-J valor8.acumulador l0(14) 2 DX,acumulador 8(12) I registro t2 t segmento (CS ilegal) l2 I 25+M 2 ^ POPF t2 I PUSH registro PUSH segmento (CS ilegal) PUSH memoria l5 t4 I 24 +M I 2 -4 PUSHF t4 I registro,l 2 ¿ registro,Cl memoria,l memoria,Cl 8 + 4/bit 2 l5(23) + M 2-4 20(28)+M+4/bit 2-4 registro,l 2 ¿ registro,Cl memoria,l 8 + 4/bit 2 l5(23) + M 2-4 RCL RCL RCL RCL RCR RCR RCR memoria 815 Tabfa D-2 (continuación) Instrucción RCR memoria.CL REP REPE REPNE REPNZ Ciclos Bytes 20(28\+M+4/bit z-4 2 2 I I I 2 REPZ = REPNE = REPE RET RET RET RET (mismo seg, sin pop) (mismo seg, con pop) (distinto seg, sin pop) (distinto seg, con pop) 20 24 ROL ROL ROL ROL registr0,l registro,CL memoria,l memoria,CL 2 8 + 4/bit 20(28)+M+4/bir 2-4 ROR ROR ROR ROR registro, I 2 "| registro,CL memoria,l memoria,CL 8 + 4/bit ) l5(23) + M 2-4 2-4 JT l5(23) + M 20(28)+M+4/bir SAHF SAL SAL SAL SAL registro, I ") A registro,CL memoria,l memoria,CL 8 + 4/bit 1 ¿-+ 2-4 2-4 2 8 + 41bit 15(23) + M 2 SBB SBB registro,registro registro,memoria memoria,registro e(13) + M registro,CL memoria, l memoria,CL 2 ls(23) + M 20(28)+M+4/bit registro, l 20(28)+M+4/bit 2 2-4 2-4 J 16(24) + M 2-4 z-4 registro,valor + SBB SBB memoria,valor acumulador,valor 17(25) + M 4 3-6 z-5 SCAS SCAS SCASB cadena-destino l5(1e) I I SCASW SHL 816 t l a J I SAR SAR SAR SAR SBB SBB I a (repetir)cadena-destino = SCAS : SCAS = SAL 9 + l5(19)/rep 3-4 Tabfa D-2 (continuoción) Ciclos Instrucción SHR SHR SHR SHR registro,l registro,CL memoria,l memoria,CL Bytes 2 2 2 8 + 4/bir l5(23) + M 20(28)+M+4/bit 2-4 2-4 STC 2 I STD ) I STI 2 I STOS cadena--fuente STOS (repetir)cadena--fuente STOSB = STOS STOSW : STOS l l(15) 9 + l0(14)/rep SUB registro,registro SUB registro,memoria SUB memoria,registro SUB registro,valor SUB memoria,valor SUB acumulador,valor TEST registro,registro TEST registro,memoria TEST memoria,registro TEST registro,valor TEST memoria,valor TEST acumulador.valor 4 WAIT 3+5n XCHC acumulador,registrol6 XCHC memoria,registro XCHG registro,registro XLAT tabla__fuente XOR registro,registro XOR registro,memoria XOR memoria,regisl.ro XOR registro,valor XOR memoria,valor XOR acumulador,valor 2 ¿-+ J 9(13) + M 16(24) + M 4 2-4 J-+ l7(25) + M 3-6 4 2-3 .J 2 9(13) + M 2-4 2-4 16(24) + M 3-4 5 ll +M 3-6 I J I l7(25) + M 2-4 + ) ll I I 1 J 2 9(13) + M 16(24) + M 4 2-4 2-4 3-4 l7(25) + M 3-6 4 ¿-3 817 Apéndice E Matriz del juego de instrucciones del 8088/8086 SIMBOLOS UTILIZADOS b - operación a nivel byte. d - directo. f - desde registro de la CPU. i - inmediato. ia - inmediato a acumulador. id - indirecto. is - inmediato, byte, extensión del signo. I - largo, es decir, a distinto segmento. m - memoria. r/m - desplazamiento es el byte 2. si - corto mismo segmento. sr - registro de segmento. t - a registro de la CPU. v - variable. w - operación a nivel palabra. z - cero. 000 001 010 0ll 100 101 100 lll Inmediato ADD OR ADC SBB AND SUB XOR CMP Shifr ROL ROR RCL RCR SHLiSAL SHR Grp I TEST NOT NEC MUL IMUL DIV Grp 2 INC CALL CALL JMP I,id id JMP t,id PUSH id mod 818 r/m DEC SAR IDIV n2 16 )z 48 64 80 96 I 2 J 4 5 6 l ADD b,f ,r/m ADD w,f ,r /m ADD b,t,r/m ADD w rtrr/m ADD ADD PUSH POP b,ia w,ia ES ES ADC ADC w,f,r/m ADC ADC PUSH POP b,t,r/m w,t,r/m ADC b,i ADC b,f ,r/m wri SS SS 22 AND b,f ,r/m AND w,f,r/m AND b,t,r/m AND w rtrf /m AND b,i AND SEG :ES DAA wri JJ XOR XOR XOR XOR SEG b,t,Í/m w,t,r/m wri :SS AAA w,f ,r/m XOR b,i XOR b,f ,r /m INC INC CX INC DX INC BX INC INC INC INC AX SP BP SI DI PUSH PUSH PUSH PUSH PUSH PUSH CX DX PUSH BX PUSH AX SP BP SI DI 71 JO JNO JB/ JNAE JNB/ JAE JE/ JNE/ JNZ JBE/ JZ JNA JNBE/ JA 88 lnmed lnmed lnmed lnmed TEST TEST b,r/m w,r/m b,r/m b,r/m w,r/m XCGH b,r/m XCHG is,r/m 99 NOP XCHG CX XCHG DX XCHG BX XCGH XCHG XCHG SP BP SI XCHG DI MOV MOV MOV MOVS MOVS CMPS CMPS 0 0 Dec. Hex. 00 ll 44 55 66 l0A ll MOV m-AL mrAX AL*m AX-n B MOV i- AL MOV i- CL t2c 13D t4E 15 F b b MOV i- DL MOV i- BL MOV MOV i*CH MOV ir DH MOV RET RET LES LDS MOV MOV Shifr AAM AAD IN IN i*AH b,i,r/m (i + SP) Shifr Shift w,r/m shifr b b,v LOOPNZ/LOOPZ LOOPNE LOOPE LOOP LOCK REP JCXZ REP HLT w,i,r/m XLAT OUT OUT b b Z i-BH CMC Grp I b,r/m Grp I w,r,/m 819 Dec. 128 Hex. 8 00 OR ll 22 JJ 44 55 t44 9A 160 \92 208 CDEF 224 B OR OR PUSH w,i CS 176 240 OR w ,f,r /m OR OR b,f ,r/m b.t,r/m w rtrr/m hi SBB SBB SBB w,f,Í/m SBB PUSH POP b,t,r/m SBB w rtrr /m SBB b,f ,r /m b,i wri DS DS SUB b,f ,r /m SUB SUB SUB SUB SUB w ,f,r /m SEG b,t,r/m w rtrr /m wri :CS DAS b,i CMP CMP CMP CMP wri :DS AAS w rtrr /m CMP b,i SEC w,f ,r/m b,t,r/m CMP bi,f ,r/m DEC DEC AX DEC DEC DEC DEC DEC DEC CX DX BX SP BP SI DI POP POP SI DI POP POP POP POP AX POP CX DX BX SP POP BP JS JNS 66 77 88 MOV 99 JP/ JNP/ JL/ JNL/ JLE/ JNLE/ JPE JPO JNGE JGE JNG JG LEA MOV srrf,r/m r/m SAHF LAHF SCAS MOV w,f ,r/m MOV MOV MOV b,f ,r/m b,t,r/m w,t,r /m sf ,t,r /m CBW CWD CALL WAIT PUSHF POPF l,d l0A ll B TEST TEST LODS LODS SCAS w,i STOS b STOS b,i w b w b MOV MOV MOV MOV i-AX i*CX t2c 13D t4E 15F 820 irDX i-BX POP i*SP i*BP MOV MOV MOV MOV i*SI i-DI RET RET INT l,(i + SP) a J INT INTO IRET I ESC ESC ESC ESC ESC ESC ESC ESC 0 I 2 3 4 5 6 7 CALL JMP JMP JMP IN IN OUT OUT d d l,d si,d v,b CLC STC CLI STI CLD v'b STD Grp 2 Grp 2 b,r/m w,f /m Apéndice F Algoritmo de Bresenham Se presenta el problema de trazar una recta entre dos puntos dados (xl,yl) y (x2,y2) activando una serie de puntos intermedios que se aproximen lo más posible a la recta teórica: (x2,y2) Ly = yZ-yl (x l,y l) Ax + x2-xl Para lograr esto existen muchos algoritmos. El algoritmo de Bresenham es el más conocido y utilizado. Tiene la ventaja de que todas las operaciones se realizan con números enteros. Se define Ax : xz-x, y Ay :yz-yt. Vamos a suponer, en primera aprorimación, que Ax ) Ay, es decir, que la recta que une el punto I con el punto 2 se encuentra en el primer octante. Los valores de lá "escalera" o poligonal que buscamos los vamos a definir mediante las coordenadas "i" y "j" relativas al punto l, es decir, las coordenadas absolutas de cada punto de la poligonal son: x:Xrfi y:YrlJ 821 "i" La variable toma los valores 0, 1,..., Se trata de calcular los valores j asociados a cada i: jo, j,,...,j0". En general, ^x. j,. Ay i' 0 Es evidente Que jo:0 (la recta arranca en el punto l) y j* : Ay (la recta termina en el punto 2). Para pasar de j,_, a j, hay que incrementar ji_r en 0 ó l, es decir, se elige tramo recto (0) o tramo diagonal (l). Vamos a definir: d' : i, -i,-, Por tanto: 4 :0 indica tramo recto. 4 : I indica tramo diagonal. Se trata entonces de calcular ó,, ór,..., do*. En una situación general, en donde se conoce j,_,, vamos a calcular d. Si se elige tramo recto (d : 0), la diferencia vertical respecto a la recta teórica que une el punto I con el punto 2 es (en el punto i): o. Av : I _¡i_Ji_r Si se elige tramo diagonal (4 : l), esta diferencia es: 4 :t#-(i,, * t) :i#-j,-,-r El signo es positivo si el punto se encuentra en el lado inferior de la recta y negativo si se encuentra en el lado superior. Sid+do ) 0, entonces hay que elegir tramo diagonal (d : l). Sid,+do ( 0, entonces hay que elegir tramo recto (4 :0). e2 Hay que evaluar, por tanto, el signo de la expresión: av 2.i,,-llo d,+dd-rr-ff Multiplicando por Ax, E,:2i' Ly-2 'i'-' ' Ax-Ax E' ) 0 - ó, : 1 (tramo diagonal) E'(0-4:0(tramorecto) Para i : l, i,_, :io : 0y E, = 2. Ly-Lx. Bastaría con evaluar Q para i:1,2,..., Ax y ver el signo para decidir la elección de tramo. Pero es más sencillo calcular E,*, en función de E': :2i' Ly-2 'i'-' ' Ax-Ax Ei*r : 2 (i + l) ' LY-2 'i' 'Ax-Ax E¡ E,*,-E, :2'Ly-2Ú,-i,-,) 'Lx':2'Ly-2 'd, 'Ax Entonces, si se elige tramo recto (d :0), Ei*r : E¡ * E.. Y si se elige tramo diagonal (d' : 1), Ei*r : E + Eo. Siendo E, :2 'Ay, Eo + 2' Ly-2 ' Ax, que son valores constantes. Algoritmo (caso pr¡mer octantel o Vqlores iniciales: Ax : xz-xr, Ay : yr-y, F* : 2' Ly, Eo : 2' Ly-2' Lx X:xt, Y:Yr E :2'Ay-Ax . Dibujo de la rects: Haceri:laAx+1 Dibujar punto (x,y) SiE>O d: l, E: E + Eo (tramo diagonal) En caso contrario 823 d=0, E=E+$ (tramo recto) x:X*1, y:y*ó Fin bucle Fin Ejemplo para el caso Ax :6, Ly :2: F-,:4, Eo:4 -12: -8, E:4-6: -2 -l) d:0, E=-2+4: 2 --Z) d= l, E- 2-:8:-l - 3) d:0, E=-6*4:-2 d=0, E=-2+4= 2 :-4) 5) ó: l, E- 2-8:-6 - 6) d:0, E=-6*4=-2 Los valores de d, , dr, ór, ó0, dr, du son 0 I 0 0 I 0: Caso general En el caso generalr Ia recta l-2 puede quedar dentro de uno de los ocho octantes posibles. En este caso, hay que considerar incrementos x,y para cada tipo posible de tramo (recto o diagonal): : incremento x para tramo recto. dr, : incremento y para tramo recto. d*¿ : incremento x para tramo diagonal. 4¿ : incremento y para tramo diagonal. d", Octante I 2 4 5 6 8 824 ór, ór, l0 0l 0l 0 -l 0 -l0 -l 0 -.-l l0 ó*¿ ó!,1 I I -l -l -l -l I I -l -l _-t -l Es decir: Ax>0-4¿:1,^x<0-4J:-l AY ) 0 - 4a = l, AY ( 0 * dr¿ :-l Y 4, - d*d, dy. : óya Y si lAxl > lAvl entonces dr, : 0, caso contrario :0. es d. Algoritmo (caso generall El algoritmo de determinación de tramo recto o diagonal es el mismo que el anterior, pero intercambiando Ax por Ay en los octantes2,3,6y 7. Es el siguiente: o Cálculo de los incrementos para el caso tramo diagonal (d,o,4o): 4:1,4:l ay: yr-y' SiAy(0 d, 4o : -dr' AY : -AY :4 AX: Xz-Xr SiAx(0 4:-4, Ax:-Ax 4o :4 o Cálculo de los incrementos para el caso tramo recto (d.,dr,): SiAx)Ay 4:0 En caso contrario 4:0 Intercambiar Ax por Ay 4.:4 4,:4 825 o Valores iniciales: X:Xr, Y:Yr F. :2' Ly, Ea:2 ' Ay-2 ' Ax E : 2'Ay-Ax . Dibujo de la recta: Hacer i: I a Ax + l. Dibujar punto (x,y) SiE>O x:x*d*¿, y-y*dy,i, E:E+Eu (tramo diagonal) En caso contrario x:x*d*,, y :y * óy,, E:E+E, (tramorecto) Fin bucle Fin. 826 Apéndice G Un programa para recuperación de ficheros borrados Hemos visto que cuando se borra un fichero se realizan dos operaciones: . El primer carácter del nombre del fichero en el directorio se cambia a o: E5h. . Las entradas de la FAT correspondientes a ese fichero se ponen a cero. Por tanto, los datos en sí del fichero no se han borrado y podrían recuperase siempre que no se hayan hecho operaciones sobre el disco que hayan ocasionado la reutilización del espacio liberado. El programa UNDEL permite recuperar un fichero borrado, tanto en diskette (doble cara y 9 sectores/pista) como en disco duro. Para recuperar el fichero hay que actuar sobre las dos áreas del disco afectadas: el directorio raiz y la FAT. La secuencia de operaciones que se realiza es la siguiente: o Busca una entrada en el directorio con un nombre que empiece por o: E5h y cuyos restantes caracteres coincidan con el nombre del 827 fichero a recuperar. Podría haber varias entradas que cumplan estas condiciones y que corresponderían a varios ficheros borrados previamente como, por ejemplo, NOMBRE.DOC y HOMBRE.DOC (pues sólo difieren en el primer carácter). Una vez Iocalizada la entrada en el directorio. se toma el valor del campo "cluster inicial" (que no ha sido borrado). Comprueba que la entrada de la FAT de número de orden igual al cluster inicial (la primera entrada de la FAT tiene número de orden cero) es cero, es decir, el cluster correspondiente no ha sido reutilizado. Si así fuera, el programa termina con un mensaje que indica esta circunstancia. Se toma del directorio el campo de longitud del fichero (que sigue intacto también). A continuación calcula el número de clusters ocupados por el fichero: n:(lf-l)/lc+l siendo: lf : longitud del fichero (bytes). lc: longitud de un cluster (bytes). Se recorre la FAT para localizar las siguientes n entradas con valor cero (que indican cluster disponible) y se reconstruye la cadena de clusters. Para tener la seguridad de que los clusters recuperados pertenecen al fichero, existe la opción /V, que permite visualizar el primer sector de cada cluster, para que el usuario confirme si el cluster pertenece o no al fichero. Esta visualizaciín tiene sentido para el caso de ficheros de texto, pero no para el caso de ficheros tipo EXE o COM, por ejemplo. Después de la recuperación del fichero, es conveniente ejecutar el comando externo CHKDSK del DOS, que inspecciona la FAT para detectar posibles errores, como: clusters huérfanos (que no pertenecen a ningún fichero), cadenas cruzadas (clusters que pertenecen a varios ficheros, etc.). LAS ENTRADAS FAT Las entradas FAT se organizan por pares, es decir, cada par ocupa tres bytes. Si una entrada (par) contiene l23h y la siguiente (impar) contiene 456h, los tres bltes son: 23h, 6lh y 45h, como vamos a ver. En lenguaje de máquina, para encontrar el valor de la tabla FAT correspondiente a un cluster determinado, se calcula cluster x 3 desplazamiento sobre la FAT, que apunta a X,)i)i)Qh. Si el-rturteres par, se descarta Xr. Si es impar, se descarta )ío. Si AX es el número de orden de la entrada en la FAT, y DX es el valor de esa -: entrada. las instrucciones son: 828 t ; se calcula BX = 3 'r AX / 2 ; SHL BX,I BX: AX BX:2*AX BX: 3xAX BX:3 *AX / 2 JZ sí ... usar los l2 bits menos significativos MOV BX,AX ADD BX,AX SHR BX,I TEST AX,I ¿entrada par? PAR MOV CL,4 SHL DX,CL PAR: OR WORD no ... usar los l2 bits más sienificativos PTR FATIBXI,DX Ejemplo de entroda par: AX:2, DX: 0123h :2301 b¡es:012345 FAT ABC (suponemos que DEF GH I JKL tl ll A-,..:L:0) entradas: 0123 BX : (3 x2)/2:3 palabra FATIBXI : FAT[3] : GHIJ : IJGHh. :2301 : 0123h. DX :2311 : Il23h. operación OR ¡l ll Ejemplo de entrada impar: AX : 3, DX : 0456h : 5604. b¡es:012345 FAT ABC DEF 23r I KL lt t¡ ll l¡ 0r23 entradas: BX: (3 x3)/2:4 CL:4(desplazar4bits) SI{L DX,CL ; DX:4560h :6045 palabra FATIBXI : FAT[4] : IIKL : KLIlh. :6045 :4560h. DX :6145 :4561h. operación OR bytes: FAT entradas: 012345 ABC DEF 236 t45 0123 ¡l 829 UNDEL.ASM i ; Programa: UNDEL. . ; ñoe¡*in¡iAn. Recupera fichero borrado. ; Formato: ; UNDEL/V nonbre_fichero lv = indica visualización del primer sector de cada cluster i /an¡i¡nrl \ ; nombre_fichero = nombre del fichero a recuperar, ; Slmbolos: fcb3os param may_v min_v cr If equ 5ch equ Blh equ 562fh equ 762fh equ 13 equ 10 ; posición del fcb del- fichero dentro del PSP i posición parámetros comar\do UNDEL ; (dentro del PsP) t /v (v=56h, /=2fh.) , /v (v=76h, /=2fh) ; retorno de carro i alimentación de lfnea Observaciones: - Estructura def disquete doble cara y 9 sectores/pista: cara 0 cara 1 sectores 1234 56789 1 2 3 BF¡'FFDDDD D D D sectoreslógicos 0I234567 8 91011 B = registro de autoarranque (boot) F=FAT primera copia: sectores 1ógicos L y 2 (2 sectores) segunda copia: sectores lógicos 3 y a (2 sectores) D = directorio (7 sectores) - Estructura de1 disco duro: sectores Iógicos 0 1 2 .. . 16 l7 , ,. B F F .., F D.., 48 D B = registro de autoarranque (boot) F=FAT primera copia3 sectores lógicos 1 a 8 (8 sectores) segunda copia: sectores l6gicos 9 a 16 (8 sectores) D = directorio (32 sectores) - Estructura de una entrada del directorio (campos utilizados): Campo Despf. Longitud Nombre fichero 0 8 26 28 Extensión Cluster inicialLongitud fichero 830 a I 3 2 (bytes en orden inverso) 4 (bytes en orden inverso) ; codigo empezar: segment assume cs : codigords :codigores :codigo org Jmp variables operacion 100h primero ; para poder convertir a .com i bifurca a zona de programa db selecciona lectura/grabación de cluster ? ñ=loar1=nr¡h¡r primer cluster del- fichero cluster inicial dw ? J.ong_fidhero dw ? núnero de clusters ocupados por eI fichero unidad db 0 unidad del- fichero a recuDerar men no existe db cr,lf,'Fichero no encontrados' men-re$rabado db cr,If,'EI fichero ha sido regrabado$' menjertenece db crr1f,'¿Este sector pertenece a1 fichero? (s/n)$' datos_cluster db 8 dup(512*.dup(0)) ; espacio para directorio y FAT ; (un cluster) sector visual- db 512 dup(0) ; ht{lizado para visualización sector sector = (cl-uster-2)*2 + 12 = cfuster*2't B (disquete) sector = (cluster-2)*8 + 49 = cluster*8 + i3 (disco duro) sector = (cl-uster-2)*varl + var2 varl vat2 Iong_cfuster nsectores sector_dir_ini sector dir fin i ; dw2 dw8 dw 1024 dw 2 dw 3 dw 11 longitud de un cluster (bytes) nro. de sectores por c.Iuster sector ]ógico inicial directorio sector 1ógico final directorio - nsectores ---------- primero: undel- proc mov sub jnc mov int unidad conocida: mov mov ; inicio de1 proceso al,cs:fcb__pos ; obtener el número de Ia unidad a1,1 ; Zes 1 (a:) o 2 (b:)7 unidad_conocida ; sl ... bifurcar ahrJ.9h ; obtenerlo con int 21h 21h i aI = número de unidad (0=A,I=B,etc.) unidadral dx,sector_dir_ini ; guarda número de la unidad ; inicia búsqueda en directorio i dx = nro. de1 sector lógico ; inicializar variables si disco duro cmp unidad,2 ; ZunidadCoD? jb bucle ; no .,. bifurcar mov varlr B mov var2,33 mov sector_dir_inir 9 mov sector_dir_fin,49 mov nsectores, S mov long_cluster,4096 8[f1 i buscar en eI directorio bucle: cmp leer dir {h ah, 9- mov lea int dx rmen_no_existe 21h Jmp Iee¡ dir: and ca l1 Lea buclecmp: salir i sal-ir operación: .l-eer cluster l-eer cluster prepara búsqueda de entrada fichero borrado empieza con o = 0e5h contador = lonqitud del cluster operacion r 0 c.Luster acc di , datos-_cluster aI, 0e5h mov mov c¡a ; avanzar nsectores (1 cluster) ¡. Lfin de directorio? nó - trifrrrca e leer directorio i error i ms¡rsaje de fichero no encontrado dx, nsectores dx, sector_dir_fin add buscar: ef fichero cx , l-ong_c]-uster ch )cxz mov mov bucle si, f cbjos+2 bx,11 dec cmps Je cmp )nz bx [di], [si] buclecmp bx,0 buscar t busca entrada en directorio si contador = 0, siguiente cluster apuntar a segundo carácte! del- nombre i comparar caract, de nombres i ¡ i decrementa contador i ócaracteres iguales? sf ... entonces comparar sgte. i Znombres iguales? '¡ i no .,. seguir búsqueda en dir. ; fichero encontrado sub di,12 mov mov or call mov mov i di apunta a primer carácter entrada ax, cs ! f cbjos+1 ; obtener primera letra [di],ax i moverl-a a primera posición operacionr l ; seleccionar grabación cluster cluster acc i graba nombre en directorio ax, [di+26 ] ¡ obtiene nro. de1 cluster inicialcLuster inicial,ax ; guardarlo ; calcular el nro. de clusters ocupados por e1 fichero a partir de J.a ; longitud de1 fichero ; nro. de cl-usters = (longitud -1)/Iong_cluster + I mov mov c1c sub sbb div inc mov ax, Idi+28 ] dx, I d1+30 ] axr 1 dx,0 ;cf=0 i restar fichero (palabra inferior) fichero (palabra superior) I long_cluster i ax = cociente i sumar 1 long_fichero, ax ; guardarlo en long_fichero ax ; ver si en la FAT está libre el cluster inicial mov dxrl ; leer l-a FAT (sector lógico ini.cial) and operacionr0 ; selecciona lectura de I cluster callcl-uster acc mov cx,long-fichero ; contador de clusters del fichero 82 mov dec cafl cmp ia mov mov int mov Iea int jnP ax, cluster_inLcial ax fat cero dx, óluster_inicial l1enar ah, 1 3h dx, f cb3os 21h ahr9 dx , men_regrabado 2lh salir i recuperar Ia FAT llenar: mov mov cmp je caIl ultima: callloop axrdx dx, 0fffh cx, I comprueba si ha sido regrabado retrocede 1 cluster e1 sgte.espacio vacio en Ia FAT ¿es cluster iniciaL? sl ... rellenar la rAT fichero regrabado entrada en dir' borrar 'at nOS llamar salida con error dx = despl. mensaje Llamar aI DOS espacio en la FAT para fichero supone ú1tima entrada del" fichero ultima fat_cero lúltirna entrada? sl ... no busca entrada con cero l1ama con ax = rlltima entrada retorna dx = nueva entrada cambiar fat cambia la FAT Ilenar - siguiente cluster ; grabar la f'AT (primera y segunda copia) mov dxrl i sector 1ógico inicial primera copia or operacionrl ; seleccionar grabación call cluster-acc ; grabar 1 cluster (prinera copia) ' add dxrnsectores i sector 1ógico inicial segunda copia call cluster_acc ; grabar 1 cluster (segunda copia) salir: int 20h i salida undel endp ---------cluster_acc proc leer o grabar cluster entrada: dx = número del sector lógico (inicial). operacion = 0¡leer l,grabar salida: datos_cl-uster = datos del cluster leldo. t push push Push ax bx i salvar registros push push dx mov mov t aL = nro. de la unidad ; se leen 2 sectores = 1 cluster bx, datos_cluster ; apunta área datos_cluster operacion, I ; loperación leer? escribir i no ... bifurcar 25h i lectura de disco test jnz int di a1,unidad cx, nsectores &B escribir: recup jmp recup int 26h ; grabar en disco ; recuperar banderas ; (salvadas por int 25h o 26h) i recuperar registros 3 popf pop pop pop pop pop di dx cx bx ax cLuster_acc endp i:--------fat cero Droc Localiza siguiente entrada cero en Ia FAT entrada! ax = número de Ia entrada en Ia FAT sal"ida: dx = número de la entrada cero en la FAT push push push ; salvar registros ax bx cx inc ax i ax es eI puntero (despl. en 1a FAT) ; calcular bx = ax*3/2 (cada entrada son 1,5 bytes) mov sh1 add shr mov test i)a mov shr entrada3ar: dx, 0fffh dx, o cmp dx, cluster _inicial iñé mov io mov mov cmp io pops ! 834 A cmp and opcion: bx=ax bx = 2*ax bx, ax bx = 3*ax bx, 1 bx = 3*ax/2 dx,word ptr datos_clusterlbx] i dx = nro. cluster libre axrl ; ánúmero entrada par ? entradajar sl ... usar 12 bits más signif. i al i no ... usar 12 bits menos signif. dx, cl bx, ax bx, I dx, ax pops bx, param cx, Ibx] cx rmin_v opcion obtiene 12 bits ácl-uster = 0? no .,. siguj.ente cluster ax = entrada en la FAT ¿primer cl-uster? sl, saltar opción /V Zopción lV? comprobar para /v sf .,. hacer /V cmp cx, may_v ina Pops no ,,, entonces salir call ¿es /v? Iistar )cxz ver_sig muestra contenido de sector si cx = 0, cluster no pertenece pop cx recuperar registros pop pop bx ax fat_cero endp ; ---------- ii"tu. proc ! escribe por pantalJ-a el contenido de un sector i entrada: dx = nro, del cluster ; salida: cx = I si cluster pertenece al- fichero cx = 0 si c.Luster no pertenece al- fichero i t push ; salvar registro dx + var2 sector = varl*cluster mov mu1 add mov ; ; add add mov mov lea int popf mov mov int mov int ax,dx varl ax,var2 dx,ax dx,dx dx,8 al,unidad cx,1 bxrsector-visual 25h ah,2 d},cr 21h dl,lf 2l-h i ax = dx (nro. del cluster) ; ax = varl*(nro. del cluster) + v¿¡l i ax = varl*(nro. del cluster) i dx = nro. del sector i dx = 2 x dx (nro. del secto.r) i +8 para saltar boot, FAT y direct. ; obtiene unidad ; un sector a leer ; lo carga en área sector-visual; lee el sector i recuperar banderas salvadas por int. ; función: escribir carácter en dl ; escribir retorno de carro i llamar al- DOS ; escribir avance de l-fnea i llamar al- DOS ; bucle caracteres del- sectox mov hrr^l ó ñrt . mov int inc cmp -iha J"" ; inicializar bx, o d1, sector_visual I bx ] 21h bx bx,512 hrr¡la nrJ- lea ah,9 dx rmenjertenece mov ah, 1 mov cmp cx, 1 aI r 'S' cmp aI, 's' mov int int ia io mov encontrado: pop contador caracteres i nostrarlo Por Pantall-a ; siguiente carácter ,. ¿5L2 caracteres? onfnnaéq rCnefif ¡ó i función: escribir mensaje pantalla cx, 0 ;. llamar af DOS frrnción: Icar carácter de teclado ; llamar af DOS ; supone cluster perteneciente al fich. ; ¿se tecleó S? t sl .. bifurcar ; áse tecleó s? t sl ,,. bifurcar ; cluster no pertenece al fichero dx ; recupera dx ¿Ln 21h encontrado encontrado 835 Iistar ; endp ---------- cambiar_fat proc ; cambiar entrada en Ia FAT i i entrada: ax = número de la entrada en 1a FAT dx = valor push ax i salvar registros push bx push cx push dx mov shI add shr test jz mov shI p_entradajar: or pop pop pop pop ; desplazamiento en 1a FAT ; multipJ-ica x 2 bx, ax ;. suma ax para obtener 3*ax rlivi¡]a nnr t bx, 1 ax,1 ; Zel número de Ia entrada es par? p_entrada3ar ; sf ,,. usar 12 bits menos signif. cI, 4 i no ,., usar 12 bits nás signif. dx, cl ; nrlmero de cluster en la FAT word ptr datos_clusterIbx] rdx bx, ax bx, I dx cx bx ax canbiar_fat endp codigo ends end 836 empezar i recuperar registros Indice altabético A COMBIAS,630. 69, 168. AAD, 69, 169. AAM, 69, 170. AAS, 69, 171. ADC, 69, 172-173. ADD, 69,90-174. Algoritmo, 636, 638,658-659, 668, 671-672, 82t-826. AND, 52, 69,74, 175-176. Aplicación: BLPD,725. BLPF,726. BIPRES, 727-729. BIPRESU, 730. Brs,73t-732. cBP, 739. cBS,740-741. COMASBO, 626. COMASHX, 627 . coMBoAS, 628-629. coMcRHx, 631-632. coP, 633-634. DIMSECG, 524. DIMSECL,525. DIPDIR, 526-528. DIPFMT, 529-531. DIPSECL, 532-535. DISFMT, 536-538. FIMABRIR,556. FIMCERR,557. FIMCREA, 558. FIMGRAB, 559-560. FIML, 56t-562. FIMPUNTO, 563.564. FIPLISTA, 565.567. FIPREGS, 568-570. FIPSEC, 57t-573. FISERROR, 574-576. FISPARAM, 577-578. 837 IGMCOMUN, 494. IGPERSE, 495-496. IGSBAN, 497.499. IGSLIN, 5OO-503. IGSPRT, 504-506. IGSPUNTO, 507-509. LIMCLAB, 673-676. LIMGESB, 677.678. LIPCLAB, 679-680. LIPCLAC, 68I.682. LIPGESB, 683-684. MAPPRIMO, 661-663. MAPRAIZ2, 664-667. MPMMULTT, 639-@0. MPMRESTA, 641.642. MPMSUM AR, 643.644. MPPDIVID, 645-646. MPPMULTI, 647-648. MPPRESTA, @9-650. MPPSUMAR, 651-652. MPSDIVID, 653-657 . PAMCUR, 347. PAMCURL, 348-349. PAMESCN, 350. PAMESCT, 351. PAMTEXTO, 352. PAPACII, 357-359. PAPANIM, 353-356" PAPATR, 360-362. PAPATRS, 363-365. PAPEJEM, 366.367. PAPLINEA, 368-369. PAPOBJ, 370-372.' PAPRASTE, 373-374. PAPTEXTO, 375.376. PAPTXT, 377. PAPTXTRA, 378-379. PAPVECTO, 380-381. PASBLOC, 382-383. PASBOR, 385. PASORRA, 386-390. PASOBJ, 39T-394. 838 PASPUNTO, 395-396. PASRASTE, 397-400. PASTEXTO,4O1. PASTXT, 402-403. PASTXTRA, 404-406. PASVECTO, 407-409. PEMAUX, 757. PEMDO,758-759. PEMDOI,760. PEMDO2, 761. PEMFOR, 762-763. PEMIF, 764-765. PEPDO, 766-767. PEPDOI, 768-769. PEPDO2, 770-771. PEPFOR, 772-773. PEPIF, 174-775. PGPLINEA, 420-421. PGPOBJ, 422-425. PGPRASTE, 426-427. PGPTABLA, 428-429. PGPTXTRA, 430.431. PGPVECTO, 432-433. PGSBLOC, 434-435. PGSBORRA,437. PGSLINEA, 438-MI. PGSOBJ, 442.M6. PGSPUNTO, 447-448. PGSPUNX, 449-451. PGSPUNXX, 452-454. PGSRASTE, 455-458. PGSTXTRA, 459-46T. PGSVECTO, 462-464. REPCAP, 692-696. REPRELO J, 697.699. SOMELISA, 596-597. soMNorAS, 598-599. SOMRETAR, 600. SoPMUSIC, 601-602. soPSoNMl, 603-604. soPSoMN2, 605-606. SOPTECLA, 607-609. SOSMUSIC, 610-612, coBol-, 712,738. sosNoTA, 613-615. sossoNMl, 616-618. COMMENT, 90, IOI. TEPFLE, 472-474. TEPLEER, 475-476. TEPTECLA, 477-478. TESESPER,479. TESFLE, 480-482, TESLEER, 483. TESTECLA, 484-485. Coprocesador, 34, 779. CREF, 90, IO2. VAPALMA, 704.705. DAA, 69, 189. DAS, 69, 190. DB, 88, 103-104. DD, 88, 105-106, 785. VAPBOOT, 706-707. VAPEXE, 708-711. Asíncrono, 580, 582, 586. ASSUME, 63, 88, 98, B BASIC, 7 13, 7 L5-723, 733-735. BCD, 26-27, 76. Boot, 512. Buffer, 331, 342, 410, 490, 540. Bus de control, 32. datos, 3l-32, 295,780. direcciones, 3l-32, 37, 780. coMMoN, 157 . cwD, 69, 188. D DEBUG, 3I7. DEC, 69, l9l. Disco, 510-518. DIV, 69, 192-193. DOWHILE, 751-754. DQ, 88, 107-108, 785. DT, 88, 109, 785. DTA (Disk Transfer Areo), 541, 546,548-549, 553-554. DW, 88, 110-lll, 785. E C c,745-746. CALL, 64, 70,73,76, 177-178. cBw, 69, 179. cl-c, 71, 180. cLD, 71, l8l. cLr,7l, 182. Cluster, 513, 515-519, 828. cMc, 71, 183. cMP, 69, 77, 184. CMPS, 71,79, 185. CMPSB, 71,79, lg5. CMPSW, 71,79, 185. ELSE, 89. END, 88, 112. ENDIF, 89. ENDM, 90,92, ll3. ENDP, 88, 114. ENDS, 88, l15. Ensamblador, 314, 318, 519, 715, 719, 736. EQ, 53. EQU, 88, ll6-117. ESC, 71, 80, 194-195. EVEN, 88, 118. EXITM, 92, II9. EXTRN, 88, 120-121. F FBLD, 789. FBSTP, 789. FBC (File Control Block), 541549, 555. FIFO, 669. FILD, 789. lnterfaz de control, 713. datos, 713. Interrupciones, 300-3 I 4, 334, 337 , 467-468, 487-488, 520, 522, 545, 582, 584, 589, 685, 689, 690, FIST, 789. FISTP, 789. Flag, 40-41, 80, 167, 261,277. FORTRAN, 7t3, 742-744. FOR-NEXT, 75t, 7 55-7 56. Frecuencia, 31, 33, 587, 589, 591- INTO, 71,81,205. IRET, 71, 81, 206. IRP, 92, 130. IRPC, 92, l3l. 594, 810. FST, 789. FSTP, 789. FXCH,789. J G GE, 53. GROUP, 88, 122-124. GT, 53. H HIGH, 59. HLT, 71,80, 196. I IDIV, 69, lg7-lgg. IF, 89, 125-126. IF-ELSE, 751,754-755. Impresora, 486-493. IMUL, 69, lgg-200. IN, 68, 72,201,296. 8r() INC, 69, 202. INCLUDE,88, t28-t29. INT, 65, 71, 81, 203-204. 700. JA, 70, 207. JAE, 70, 208. JB,70, 209. JBE,70,210. JC,70, 209. JCXZ, 70,211. JE,212. JG,70, 213. JGE,70, 214. JL, 70,215. JLE,70, 216. JMP, 70, 76,217-218. JNA, 70, 210. JNAE, 70,209. JNB, 70, 208. JNBE, 70, 207. JNC, 219. JNE, 220. JNG, 216. JNGE, 2I5. JNL, 70, 214. JNLE, 70,213. JNO, 70, 221. JNP, 70, 222. JNS, 70, 223. JNz,70,220. JO,70,224. JP,70,225. JPB,70,225. JPO,70,222. J5,70,226. J2,70,212. MASK, 56. Memoria virtual, 34. MOD,5l. Modem,580-585. Montador, 315-316, 318, 322, 733. MOV, 64, 68, 72, 84-86, 90, 99, 239-240. MOVS, 71,79,241. MOVSB, 71,79,241. MOVSW, 71,79,241. L MUL, 69,244-245. LABEL, 89, 132-133. LAHF, 68, 73, 227. LALL, 89, 134. Música, 593-594. LDS, 68, 72,228. LE, 53. LEA, 64, 68,72,229. LENGTH, 56. LES, 68, 72,230. LFCOND, 90, 135. LIFO, 669. LIST, 90, 137. Lista, 668-671. LOCAL, 92, 138. LOCK, 71, 80, 231-232. LODS, 71,80,233. LODSB, 71, 80,233. LODSW, 71,80,233. LOOP, 70, 78,235-236. LOOPE, 70, 78, 237. LOOPNE, 70,78, 238. LOOPNZ, 70,78, 238. LOOPZ, 70, 78, 237. LOW, 59. LT, 53. M Macro, 90-97, 139-140, 337-339, 345. N NAME, 88, 141. NE, 53. NEG, 69,246. NOP, 71, 81, 247. NOT, 52, 69,74, 248. Numeración binaria, 17-25, 622624. Numeración hexadecimal, l8-19, 22-25,808-809. Numeración octal, 18. o OFFSET, 55. oR, 52, 69,74, 249-250. Ordenación, 669-671. oRG, 142. ORIGIN, 88. our, 68,72,296. OUT (9oOUT), 90, 143. Overflow, 38, 304, 787. 841 P S PAGE, gg, 144. SAHF, 73,269. SAHP,69. sAL, 69, 75,270-271. SALL, 89, T34. sAR, 69, 75,272-273. sBB, 69, 274-275. scAS, 71,79,276. scASB, 71,79,276. scAsw, 71,79, 276. Paralelo, 579. PASCAL, 713, 747, 749. Pila, 40, 42, 60-63, 73, 157, 323, 328, 669, 7 14, 7 45, 7gl-792, 7gg790. Plotter, 490. POINTER, 56. POP, 68,72,74, 252. POPF, 69,73,253. PPI, 588-592. PROC, 88, 145-146. PSP, 3l t-313. PUBLIC, 88, 147-149. PURGE, 92, I5O. PUSH, 63, 69,72,74, 254. PUSHF, 69,73,255. R Secuencial, 542, 547, 668. SEG, 54. SEGMENT, gg, 100, 156, l5g-159. Serie, 579, 580, 582, 584, 586. SFCOND, 90, 135-136. sHL, 51, 69,75. SHORT, 58. sHR, 52, 69, 75, 279-279. SIZE, 55. sTC,72,290. sTD,72, 281. sTI,72,282. sTos, 71, 90,293. sTosB, 71,80,293. sTosw, 71, 80,293. RADIX, 88, 15I. Random, 542-543, 548-549. RCL, 69, 75, 256-257. RCR, 69,75, 259-259. RECORD, 152-153. REP, 71, 7g-79,260. REPE, 71,79-79, 260. REPNE, 71,79-79, 260. REPNZ, 71,79-79,260. REPT, 92, 154. REPZ, 71,79-79, 260. RET, 64, 70,73,76, 263-264. ROL, 69,75,265-266. ROR, 69,75, 267-269. RS-232, 579, 582-593. 8i4í2 STRUC, 89, 160-162, 327. suB, 63, 69,285. SUBTTL, 89, 163. T TEST, 70, 74, 296-297. TFCOND, 90, 135-136. THIS, 58. TITLE, 89, 164. TYPE, 55. U x UART, 580-582, 584. XALL, 89, 134. Underflow, 787. XCREF, 90, IO2. xcHG, 69,72,289. XLAT, 69,72,290. XLIST, 90, 137. xoR, 52, 70, 74, 291-292. w WAIT, 72. 843 ANAYA MULTIMEDIA INFORMATICA PERSONAL-PROFESIONAL EL LIBRO DEL WORDSTAR. Trucos y recursos.-Julie Anne Arca. EL LIBRO DEL ATARI ST. Manejo, aplicaciones y GEM.-Jeremy Vine. EL LIBRO DEL IBM PC, XT, AT. Programación, uso y aplicaciones.Louis E. Frenzel, Jr., Louis E. Frenzel IIL PROGRAMACION EN C. Introducción y conceptos auanzados.M. Waite, S. Prata, D. Martin. MARKETING Y VENTAS CON LOTUS l-2-3. Técnicas comerciales para su miooordenador.-Míchael V. Laric, M. Ronald Stiff. PROGRAMACION DEL Z8}.-Rodnay Zaks. EL LIBRO DEL APPLEllc. Programación, uso y aplícaciones.-Philip Lieberman. EL LIBRO DEL RS-232.-John Campbell. EL LIBRO DEL LOTUS 1-2-3. Desarrollo de aplicaciones profesiona/es.-Alan Simpson (2." ed.). MICROINFORMATICA PARA DIRECTIVOS. Cómo rentabilizar su ordenqdor per sonal- pr ofe sional.-Dick Heiser. PROGRAMACION GRAFICA EN EL IBM PC.-Dan Illowsky, Michael Abrash. QUILL. Tratamiento de textos en eI QL.-F. Simon, C. Spottiswoode, Blueprint. EASEL. Gráficos de negocios en el QL.-Alison Spottiswoode, Blueprint. ABACUS. Aplicaciones de Ia hoja electrónica en el QL.-Clare Spottiswoode, Blueprint. ARCHIVE. Manejo de lq base de datos en el QL.-Ian Murray, Blueprint. MATEMATICAS PARA PROGRAMADORES. Sistemas de numeración y aritmética binaria.-William Barden, Jr. INTRODUCCION AL UNIX SISTEMA V.-Mitchell Waite, Stephen Prata, Donald Martin. GEOMETRIA DE TORTUGA. El ordenador como medío de exploración de las matemóticas. Harold Abelson, Andrea diSessa. INTRODUCCION AL MS-DOS.-The Waite Group, Kate O'Day. PROLOG. Programación y aplícaciones en Inteligencia ArtiJicial.-4. A. Berk. LISP. E/ lenguaje de Ia Inteligencia ArtiJicial.-4. A. Berk. PROGRAMACION EN C CON TINY C.-Scott B. Guthery. dBASE lll. Guía del programador.-George Tsu-der Chou. I l I I