3. Manipulación de cadenas (Strings)
Definición de string En el lenguaje ensamblador el tipo de dato cadena (string) no está definido, pero para fines de programación, una cadena es definida como un conjunto de localidades de memoria consecutivas que se reservan bajo el nombre de una variable.
Almacenamiento en memoria De acuerdo con la definición anterior, las siguientes líneas en ensamblador declaran cadenas: .DATA Cadena_ASCII db ‘Cadena’,13,10,’$’ Cadena_Enteros dw 5 Dup (0) Las dos líneas anteriores están declarando variables de tipo cadena. En el primer caso, Cadena_ASCII reserva un total de 9 bytes de memoria (1 byte = 1 Carácter ASCII) incluyendo el carácter ‘$’ que indica fin de cadena. En el segundo caso, Cadena_Enteros reserva espacio para almacenar 3 cantidades enteras o lo que es lo mismo 6 bytes de memoria (1 entero = 2 bytes), todas inicializadas con cero. La diferencia en los casos anteriores radica en el tamaño del dato que compone la cadena, 1 byte para cadenas de caracteres y 2 o más bytes para cadenas de datos numéricos. El almacenamiento en memoria se vería de la siguiente forma:
Instrucciones para el manejo de strings El lenguaje ensamblador cuenta con cinco instrucciones para el manejo de cadenas: MOVS: Mueve un byte o palabra desde una localidad de memoria a otra. LODS : Carga desde la memoria un byte en AL o una palabra en AX. STOS : Almacena el contenido del registro AL o AX en la memoria. CMPS : Compara localidades de memoria de un byte o palabra. SCAS : Compara el contenido de AL o AX con el contenido de alguna localidad de memoria. Las instrucciones para cadenas trabajan en conjunto con la instrucción CLD, la cual permite establecer que el sentido en el que las cadenas serán procesadas será de izquierda a derecha.
Otra instrucción importante es el prefijo de repetición REP, el cual permite que una instrucción para manejo de cadenas pueda ser repetida un número determinado de veces. Los registros índice juegan un papel importante en el procesamiento de cadenas de datos, el par de registros CS:SI indican la dirección de la cadena original que será procesada, y el par ES:DI contienen la dirección donde las cadenas pueden ser almacenadas. Para comprender realmente como funcionan las instrucciones para cadenas analizaremos varios programas que fueron escritos para este fin. Recuerde que las cadenas en ensamblador no se refieren únicamente a cadenas de caracteres ASCII, sino a cualquier tipo de dato. .COMMENT Programa: Cad1.ASM Autor: Juan Carlos Guzmán C. Descripción: Este programa ilustra la forma de utilizar la instrucción MOVS para copiar el contenido de una cadena dentro de otra. .MODEL tiny .DATA cad1 db 'Esta es la cadena1','$' cad2 db 'Esta es la cadena2','$' .CODE inicio: ;Punto de entrada al programa cld ;Procesamiento de cadenas de izq->der. mov cx,18 ;longitud de la cadena original lea di,cad2 ;ES:DI contienen la dirección de Cad2 lea si,cad1 ;DS:SI contienen la dirección de Cad1 rep movsb ;DS:SI->ES:DI, SI=SI+1, DI=DI+1 lea dx,cad1 ;Imprimir Cad1 en pantalla mov ah,09h ; int 21h ; lea dx,cad2 ;Imprimir Cad2 en pantalla mov ah,09h ; int 21h ; mov ax,4c00h ;Terminal programa y regresar al DOS int 21h ; END inicio END .COMMENT Programa: Cad2.ASM Autor: Juan Carlos Guzmán C. Descripción: Este programa demuestra la diferencia entre el uso de MOVSB y MOVSW.
El programa debe copiar Cad3 dentro de Cad1 usando 18 repeticiones con MOVSB, después realiza lo mismo con Cad4 y Cad2 pero usando solo nueve repeticiones de la instrucción MOVSW. El resultado es el mismo en ambos casos .MODEL tiny .DATA cad1 db 'Cadena de prueba1 ','$' cad2 db 'Cadena de prueba2 ','$' cad3 db 18 dup (' ') cad4 db 18 dup (' ') .CODE inicio: ;Punto de entrada al programa cld ;procesamiento de izq->der. mov cx,18 ;Longitud de la cadena lea si,cad3 ;DS:SI->Cad3 lea di,cad1 ;ES:DI->Cad1 rep movsb ;Cad3->Cad1 mov cx,9 ;Longitud de la cadena por pares de bytes lea si,cad4 ;DS:SI->Cad4 lea di,cad2 ;ES:DI->Cad2 rep movsw ;Cad4->Cad2 lea dx,cad1 ; mov ah,09h ;Imprimir Cad1 int 21h ; lea dx,cad2 ; mov ah,09h ;Imprimir Cad2 int 21h ; mov ax,4c00h ;Terminar programa y regresar al DOS int 21h ; END inicio END .COMMENT Programa: Cad3.ASM Autor: Juan Carlos Guzmán C. Descripción: Este programa muestra el uso de la instrucción LODSB. El programa invierte el orden de los elementos de una cadena y los almacena en otra cadena que originalmente esta inicializada con espacios. Al final se imprimen las dos cadenas. .MODEL tiny .DATA cad1 db 'Cadena de prueba','$' cad2 db 16 dup (' '),'$' .CODE inicio: ;Punto de entrada al programa cld ;Procesamiento de izq->der. mov cx,16 ;Longitud de la cadena lea si,cad1 ;DS:SI->Cad1 lea di,cad2+15 ;ES:DI apuntan al final del área reservada para otro: ;almacenar la cadena invertida lodsb ;Obtener el primer carácter de Cad1 mov [di],al ;almacenarlo en la posición actual de DI dec di ;Disminuir DI loop otro ;Obtener siguiente carácter de Cad1 lea dx,cad1 ; mov ah,09h ;Imprimir cadena original int 21h ; lea dx,cad2 ; mov ah,09h ;Imprimir cadena invertida int 21h ; mov ax,4c00h ;Terminar programa y regresar al DOS int 21h ; END inicio END COMMENT Programa: Cad4.ASM Autor: Juan Carlos Guzmán C. Descripción: Este programa utiliza la instrucción STOSB para rellenar un rea de memoria con el contenido del registro AL. En este caso, el área de memoria reservado para la variable Cad1 es rellenada con el carácter ASCII '*'. .MODEL tiny .DATA cad1 db 'Cadena de prueba',13,10,'$' CODE inicio: lea dx,cad1 ;Imprimir Cad1 antes de que sea borrada mov ah,09h ; int 21h ; cld ;Procesamiento de izq->der mov al,'*' ;Inicializar AL con '*' mov cx,16 ;Longitud de la cadena que se va a rellenar lea di,cad1 ;ES:DI->Cad1 rep stosb ;Rellenar 16 bytes de memoria con '*' lea dx,cad1 ; mov ah,09h ;Imprimir Cad1 después de ser borrada int 21h ; mov ax,4c00h ;Terminar programa y regresar al DOS int 21h ; END inicio END .COMMENT Programa: Cad5.ASM Autor: Juan Carlos Guzmán C. Descripción: Este programa utiliza la instrucción CMPSB para comparar si dos cadenas son iguales. En este programa se declaran 3 cadenas de prueba. El registro BH sirve como bandera: BH=0 No hay cadenas iguales BH=1 Cad1 es igual a Cad2 BH=2 Cad1 es igual a Cad3 Se puede cambiar el contenido de las cadenas de prueba para comprobar los tres posibles resultados. .MODEL tiny .DATA cad1 db 'CADENA1',13,10,'$' cad2 db 'CADENA1',13,10,'$' cad3 db 'Cadena2',13,10,'$' error1 db 'No hay cadenas iguales…','$' error2 db 'Cadena 1 = Cadena 2','$' error3 db 'Cadena 1 = Cadena 3','$' .CODE inicio: xor bh,bh ;BH=0 cld ;Comparación de izq->der. mov cx,7 ;Longitud de la cadena lea di,cad2 ;ES:DI-> Cad2 lea si,cad1 ;DS:SI-> Cad1 repe cmpsb ;Comparar Cad1 y Cad2 jne otra ;Son iguales ?No, Comparar Cad1 y Cad3 mov bh,1 ;Si, entonces BH=1 otra: mov cx,7 ;Longitud de la cadena lea di,cad3 ;ES:DI->Cad3 lea si,cad1 ;DS:SI->Cad1 repe cmpsb ;Comparar Cad1 y Cad3 jne salir ;Son iguales ?No, imprimir mensajes. mov bh,2 ;Si, entonces BH=2 salir: cmp bh,0 ;Es BH=0? je ninguna ;Si, Entonces no hay cadenas iguales cmp bh,1 ;No. Es BH=1? je cad1_cad2 ;Si. Entonces Cad1 es igual a Cad2 lea dx,error3 ;Si no es ninguna de las anteriores mov ah,09h ;entonces debe ser que Cad1 es igual que Cad3 int 21h ;imprimir mensaje jmp salir2 cad1_cad2: lea dx,error2 ; mov ah,09h ;Imprimir mensaje int 21h ; jmp salir2 ; ninguna: lea dx,error1 ; mov ah,09h ;Imprimir mensaje int 21h ; salir2: mov ax,4c00h ;Terminar programa y regresar al DOS int 21h ; END inicio END
4. Programación de E/S
Definición de interrupción Una interrupción es un estado en el cual el microprocesador detiene la ejecución de un programa para atender una petición especial solicitada por el propio programa o por un dispositivo físico conectado al microprocesador externamente. Las interrupciones fueron creadas para facilitar al programador el acceso a los diferentes dispositivos de la computadora (puertos de comunicaciones, terminales, impresoras, etc.).
Ejecución de una interrupción Cuando durante la ejecución de un programa se produce una interrupción, el microprocesador realiza los siguientes pasos: 1.- Detiene la ejecución del programa 2.- Almacena los registros CS, IP y Banderas en la pila 3.- Modifica el CS y el IP para que apunten a la dirección donde se encuentra la rutina de interrupción. 4.- Ejecuta las instrucciones de la rutina de interrupción. 5.- Restablece usando la instrucción RETI los valores originales de los registros CS, IP y Banderas. 6.- Continua con la ejecución del programa en el punto donde fue interrumpido. Las rutinas se almacenan en la memoria de la computadora cada vez que ésta es inicializada, a esto se le conoce como vector de interrupciones.
Tipos de interrupciones El microprocesador puede atender dos tipos de interrupciones: interrupciones por software e interrupciones por hardware. Las interrupciones por software son llamadas desde los programas y son proporcionadas por el sistema operativo (MS-DOS). Existen dos tipos de estas: las interrupciones del DOS y las interrupciones del BIOS (Basic Input Output System o Sistema Básico de Entrada/Salida). Estas interrupciones son invocadas con la instrucción INT del ensamblador. Por otro lado, las interrupciones por Hardware son proporcionadas por el propio microprocesador y también existen dos tipos: interrupciones por hardware internas y las interrupciones por hardware externas. Las interrupciones internas son invocadas por el microprocesador cuando se produce alguna operación incorrecta, como por ejemplo, un intento de dividir por cero o una transferencia de datos entre registros de diferentes longitudes. Las interrupciones externas son provocadas por los dispositivos periféricos conectados al microprocesador. Para lograr esto, a cada dispositivo periférico se le asigna una línea física de interrupción que lo comunica con el microprocesador por medio de un circuito integrado auxiliar, el cual se conoce como controlador programable de interrupciones (PIC). Las computadoras basadas en el microprocesador 8086/8088 cuentan solamente con un PIC, con lo cual pueden proporcionar hasta 8 líneas de interrupción (IRQ), las cuales son llamadas IRQ0 a IRQ7, por otro lado, las computadoras basadas en el microprocesador 80286 y posteriores cuentan con dos chips controladores, con los cuales pueden proporcionar hasta un máximo de 16 líneas IRQ, las cuales son llamadas IRQ0 a IRQ15. La siguiente es una lista de las interrupciones por software disponibles por el sistema operativo. Interrupciones del BIOS Manejo de dispositivos periféricos
- INT 10H Manejo de la pantalla.
- INT 13H Manejo de unidades de disco.
- INT 14H Manejo de los puertos de comunicaciones(RS232).
- INT 15H Manejo de cinta magnética.
- INT 16H Manejo del teclado.
- INT 17H Manejo de la impresora.
Manejo del estado del equipo
- INT 11H Servicios de la lista de elementos de la computadora.
- INT 12H Servicios para el cálculo del tamaño de la memoria.
Servicios de fecha y hora
- INT 1AH Manejo del reloj.
Impresión de pantalla
- INT 5H Impresión de la información contenida en la pantalla.
Servicios especiales
- INT 18H Activación del lenguaje Interprete Basic de la ROM.
- INT 19H Activación de la rutina de arranque de la computadora.
Interrupciones del DOS
- INT 20H Termina la ejecución de un programa.
- INT 22H Dirección de terminación. Guarda la dirección donde se transfiere el control cuando termina la ejecución del programa.
- INT 23H Dirección de la interrupción que se ejecuta cuando se presiona Ctrl-Break.
- INT 24H Manejo de errores críticos.
- INT 25H Lectura directa de sectores del disco.
- INT 26H Escritura directa de sectores del disco.
- INT 27H Terminar un programa y devolver el control al DOS sin borrar el programa de la memoria.
- INT 21H Esta interrupción proporciona una gran cantidad de funciones, las cuales deben ser invocadas en conjunto con el registro AH.
- Terminación de un programa.
- Entrada de carácter con eco.
- Salida a pantalla.
- Entrada por el puerto serie.
- Salida por el puerto serie.
- Salida a la impresora.
- E/S directa por pantalla.
- Entrada directa de carácter sin eco.
- Entrada de carácter sin eco.
- Visualizar cadenas de caracteres.
- Entrada desde el teclado.
- Comprobación del estado de entrada.
- Borrar registro de entrada.
- Inicializar unidad de disco.
A continuación se mostrarán algunos programas que utilizan llamadas a diferentes interrupciones por software tanto del BIOS como del DOS. El siguiente programa utiliza la función 09h de la interrupción 21 del DOS para mostrar en la pantalla un mensaje. .COMMENT * Programa: Int1.ASM Autor: Juan Carlos Guzmán C. Descripción: Imprime una cadena de caracteres en la pantalla por medio de la función 09h de la interrupción 21h del DOS. * .MODEL tiny .DATA Mensaje db 'Interrupciones 21h del DOS',13,10,'$' .CODE Inicio: Lea DX,Mensaje Mov Ah,09h Int 21h Mov ax,4C00h Int 21h END Inicio END El siguiente programa exhibe dos cadenas de caracteres en la pantalla, pero a diferencia del anterior éste no regresa al DOS inmediatamente, espera a que cualquier tecla sea presionada y entonces termina, para ello se utiliza la función 10h de la interrupción 16h del BIOS. .COMMENT * Programa: Int2.ASM Autor: Juan Carlos Guzmán C. Descripción: Imprime dos cadenas de caracteres en la pantalla por medio de la función 09h de la interrupción 21h del DOS y después espera a que una tecla sea presionada, esto por medio de la interrupción 16h del BIOS con la función 10h. * .MODEL tiny .DATA Mensaje db 'Mas interrupciones',13,10,'$' Mensaje2 db 'Presione cualquier tecla…',13,10,'$' .CODE Inicio: Lea DX,Mensaje Mov Ah,09h Int 21h Lea DX,Mensaje2 Mov Ah,09h Int 21h Mov Ah,10h Int 16h Mov ax,4C00h Int 21h END Inicio END Como último ejemplo de esta sección, se mostrará un programa que utiliza otra función del BIOS, pero esta vez para posicionar el cursor en diferentes coordenadas de la pantalla, esto con el fin de tener mejor control sobre el lugar en el que los mensajes son visualizados. .COMMENT * Programa: Int3.ASM Autor: Juan Carlos Guzmán C. Descripción: Imprime dos cadenas de caracteres en la pantalla, controlando su posición por medio de la función 02h de la Int 10h del BIOS. * .MODEL tiny .DATA Mensaje db 'Mas interrupciones',13,10,'$' Mensaje2 db 'Presione cualquier tecla…','$' .CODE Inicio: Mov Bh,0 ;Pagina de video 0 Mov dl,30 ;X=30 Mov dh,5 ;Y=5 Mov Ah,02h ;Posicionar cursor Int 10h ; Lea DX,Mensaje ; Mov Ah,09h ;Imprime Mensaje Int 21h ; Mov Bh,0 ;Pagina de video Mov dl,40 ;X=40 Mov dh,24 ;Y=24 Mov Ah,02h ;Colocar cursor Int 10h ; Lea DX,Mensaje2 ; Mov Ah,09h ;Imprimir Mensaje2 Int 21h ; Mov Ah,10h ;Esperar tecla Int 16h ; Mov ax,4C00h ;Terminar programa y salir al DOS Int 21h ; END Inicio END
Definición Una de las principales desventajas de la programación en lenguaje ensamblador es la repetición constante de ciertos grupos de instrucciones. Por ejemplo el siguiente conjunto de instrucciones nos permite imprimir una variable de tipo cadena en la pantalla: Lea DX,Cadena ;Direccionar la cadena Mov AH,09h ;Usar la función 09h para imprimir cadenas Int 21h ;llamada a la interrupción 21h del DOS
Si necesitamos que en nuestro programa se muestren mensajes constantemente, es obvio que debemos duplicar este conjunto de instrucciones por cada mensaje que se desea enviar a pantalla. El principal problema que esto nos ocasiona es que el tamaño de nuestro programa crece considerablemente, y mientras más grande sea el programa, más difícil será encontrar la causa de algún error cuando éste ocurra. La mejor solución en estos casos es el uso de las MACROS. Una macro es un conjunto de instrucciones que se agrupan bajo un nombre descriptivo (macroinstrucción) y que sólo es necesario declarar una vez (macrodefinición). Una vez que la macro ha sido declarada, sólo es necesario indicar su nombre en el cuerpo del programa y el ensamblador se encargara de reemplazar la macroinstrucción por las instrucciones de la macro (expansión de la macro). El formato general de una macro es el siguiente: .MACRO Nombre [(parametro1, parametro2, etc)] INSTRUCCIONES ENDM Nuevamente, lo que se encuentra entre paréntesis cuadrados es opcional. De acuerdo con esto, la macro para imprimir cadenas quedaría de la siguiente forma: .MACRO Imprime_Cad(Cadena) Lea DX,Cadena Mov Ah,09h Int 21h ENDM
Parámetros y etiquetas Dentro de las propiedades más importantes de las macros se deben destacar la posibilidad de utilizar parámetros y etiquetas. Los parámetros permiten que una misma macro pueda ser usada bajo diferentes condiciones, por ejemplo, se puede crear una macro para posicionar el cursor en diferentes coordenadas de la pantalla e indicar sus coordenadas por medio de parámetros. La siguiente macro nos muestra esta propiedad: ;Esta macro posiciona el cursor en las coordenadas que se le indican como ;parámetros. Es el equivalente al GotoXY de Pascal. .MACRO gotoxy (x,y) xor bh,bh ;Seleccionar página cero de video mov dl,x ;Columna mov dh,y ;Renglón mov ah,02h ;Función 02h para posicionar cursor int 10h ;llamada a la int 10h del BIOS ENDM También existen situaciones en las que los parámetros no son necesarios, es por esta razón que los parámetros son opcionales en la declaración de la macro. ;Esta macro realiza una pausa en el programa hasta que una tecla es ;presionada. Es el equivalente del readkey en Pascal. .MACRO tecla mov ah,10h int 16h ENDM
Por otro lado, las etiquetas también son útiles dentro de las macros. Suponga que se desea crear una macro que imprima una cadena un numero n de veces, esta macro podría ser declarada de la siguiente forma: .MACRO Imprime_nCad (Cadena, Cuantos) Mov CX,Cuantos ;Iniciar Contador Lea DX,Cadena ;Direccionar la cadena que se va a imprimir Mov Ah,09h ;Usar la función 09h Otra: ;Etiqueta interna Int 21h ;Imprimir la Cadena n veces Loop Otra ;Siguiente Impresión ENDM
Ensamble de macros Como ya se mencionó antes, una macro es declarada una sola vez y puede ser llamada cuantas veces sea necesario dentro del cuerpo del programa. Cada vez que el ensamblador encuentra una macroinstrucción, verifica si ésta fue declarada; si esta verificación es exitosa, el ensamblador toma las instrucciones del cuerpo de la macro y las reemplaza en el lugar donde la macro fue llamada. El siguiente programa muestra la declaración y uso de las macros: .COMMENT Programa: Macros1.ASM Autor: Juan Carlos Guzmán C. Descripción: Este programa muestra el uso de macros. .MODEL TINY ; Declaración de variables .DATA cad db 'Ejemplo del uso de macros…',13,10,'$' cad1 db 'Presiona una tecla…','$' cad2 db 'Ejemplo del uso de la macro gotoxy…','$' ;Aquí se declaran las macros. ;************************************************************************
;————————————————————————
;Esta macro imprime una cadena pasada como parámetro. ;Utiliza la función 09h de la Int 21h del DOS. .MACRO imprime_cad(cadena) lea dx,cadena mov ah,09h int 21h ENDM ;————————————————————————
;Esta macro realiza una pausa en el programa hasta que una tecla se ;presione. Es el equivalente del readkey en Pascal. .MACRO tecla mov ah,10h int 16h ENDM ;————————————————————————
;Esta macro posiciona el cursor en las coordenadas que se le indican como ;parámetros. Es el equivalente al GotoXY de Pascal. .MACRO gotoxy (x,y) xor bh,bh mov dl,x mov dh,y mov ah,02h int 10h ENDM ;————————————————————-
;Esta macro limpia la pantalla. ;Utiliza la función 06h de la Int 10h del Bios. .MACRO limpiar_pantalla mov ax,0600h mov bh,17h mov cx,0000h mov dx,184fh int 10h ENDM ;————————————————————-
;Aquí comienza el cuerpo del programa principal .CODE inicio: ;Declaración del punto de entrada limpiar_pantalla ;Llamada a la macro gotoxy (0,0) ;Colocar el cursor en 0,0 imprime_cad(cad) ;Imprime el primer mensaje imprime_cad(cad1) ;Imprime el segundo mensaje tecla ;Espera a que se presione una tecla gotoxy (30,12) ;Colocar el cursor en 30,12 imprime_cad(cad2) ;Imprimir el tercer mensaje gotoxy (50,24) ;Colocar el cursor en 50,24 imprime_cad(cad1) ;Imprimir el segundo mensaje tecla ;Esperar por una tecla mov ax,4c00h ;Fin del programa y regresar al DOS. int 21h END inicio END
Ventajas y desventajas Si bien es cierto que las macros proporcionan mayor flexibilidad a la hora de programar, también es cierto que tienen algunas desventajas. La siguiente es una lista de la principales ventajas y desventajas del uso de las macros. Ventajas:
- Menor posibilidad de cometer errores por repetición.
- Mayor flexibilidad en la programación al permitir el uso de parámetros.
- Código fuente más compacto.
- Al ser más pequeño el código fuente, también es más fácil de leer por otros.
Desventajas:
- El código ejecutable se vuelve más grande con cada llamada a la macro.
- Las macros deben ser bien planeadas para evitar la redundancia de código.
Definición de procedimientos Un procedimiento es un conjunto de instrucciones que tienen la finalidad de ejecutar una tarea especifica dentro de un programa. Los procedimientos son muy similares a las macros. Un procedimiento se declara una sola vez en el código fuente y cuando el programa se ensambla y ejecuta, el procedimiento se coloca en memoria para que pueda ser utilizado por el programa. Las principales ventajas en el uso de procedimientos son: permiten una codificación más limpia y compacta, es decir el código fuente es más pequeño; también permiten el ahorro de memoria, esto es porque un mismo procedimiento puede ser llamado varias veces en el mismo programa y sólo requiere memoria una vez. Los procedimientos tienen la desventaja de que reducen la velocidad de ejecución de los programas, esto se debe a la forma en que los procedimientos se ejecutan. A continuación se presentan los pasos necesarios para ejecutar un procedimiento: 1.- Se encuentra la llamada Call 2.- El microprocesador almacena en la Pila el contenido del IP 3.- Se coloca en el IP el valor del desplazamiento correspondiente al Procedimiento 4.- El microprocesador ejecuta las instrucciones del procedimiento 5.- El procedimiento termina cuando se encuentra la instrucción Ret 6.- Se saca de la pila el valor original del IP y se continua el flujo del programa
Un procedimiento se declara de la siguiente forma: PROC nombre instrucción instrucción …. RET ENDP NOMBRE En donde PROC es una palabra reservada que indica el inicio de un procedimiento, RET es una instrucción que indica la terminación del conjunto de instrucciones de un procedimiento y finalmente ENDP es la palabra reservada para fin de procedimiento.
Paso de parámetros Los procedimientos en lenguaje ensamblador no cuentan con un mecanismo para el paso de parámetros; por lo cual, la única forma de lograr esto es colocando los parámetros que nos interesan en los registros de propósito general antes de que el procedimiento sea ejecutado. El siguiente procedimiento coloca el cursor en las coordenadas establecidas en Dl y Dh. Proc GotoXY xor bh,bh mov ah,02h int 10h Ret Endp GotoXY En este ejemplo, las coordenadas XY se deben situar en el registro DX antes de que se llame al procedimiento.
Llamada a procedimientos Los procedimientos son llamados por los programas por medio de la instrucción CALL, seguida del nombre del procedimiento. Ejemplo: Call GotoXY El siguiente programa muestra la forma de pasarle parámetros a los procedimientos por medio de los registros generales. Este programa declara tres procedimientos: GotoXY: Coloca el cursor en las coordenadas especificadas Limpia_Pantalla: Limpia la pantalla Imprime_Cad: Imprime una cadena en la posición actual del cursor .COMMENT * Programa: Proc2.ASM Autor: Juan Carlos Guzmán C. Descripción: Este programa ilustra la forma de utilizar procedimientos en los programas por medio de la instrucción Call y la forma de pasarles parámetros. .MODEL TINY .DATA Cad1 db 'Esta es una cadena de prueba…',13,10,'$' .CODE INICIO: ;Punto de entrada al programa Mov DL,20 ;X=20 Mov DH,10 ;Y=10 Call Gotoxy ;GotoXY 20,10 Lea DX,cad1 ;DX->Cad1 Call Imprime_Cad ;Imprimir Cad1 Mov Ax,04C00h ;Terminar y regresar al dos Int 21h ; END INICIO ;*********************************************************************
;Procedimiento: GotoXY ;Descripción: Coloca el cursor una posición especifica de la pantalla ;Parámetros: Dl=X, Dh=Y ;*********************************************************************
PROC GotoXY Xor Bh,Bh Mov Ah,02h Int 10h Ret ENDP GotoXY ;***********************************************************************
;Procedimiento: Limpia_Pantalla ;Descripción: Imprime una cadena de caracteres en la posición del cursor ;Parámetros: La dirección de la cadena en DX ;***********************************************************************
PROC Imprime_Cad Mov Ah,09h Int 21h Ret ENDP Imprime_Cad END
Procedimientos internos Los procedimientos internos son aquellos que se declaran y se llaman dentro del mismo programa, también son llamados procedimientos locales. El listado anterior muestra la forma de utilizar procedimientos internos.
Procedimientos externos Los procedimientos externos, a diferencia de los internos, se declaran en módulos o programas separados al programa donde el procedimiento es llamado, en otras palabras, la llamada al procedimiento se encuentra en un programa y el procedimiento en otro. Para poder utilizar procedimientos externos, es necesario que sean declarados como públicos en el programa donde se encuentran y que sean llamados como externos en el programa donde serán usados. Para lograr esto, Pass32 cuenta con tres directivas de ensamble: .PUBLIC para declarar los procedimientos como públicos, .EXTERN para indicar que el procedimiento que se va a usar está fuera del programa y .INCLUDE para enlazar el programa que contiene los procedimientos con el programa que los llama. El siguiente programa muestra el uso de las directivas de inclusión. Primeramente, el archivo Proc2.ASM se modificó para que su variable Cad1 fuera declarada como publica, el programa Proc3.ASM contiene la línea .INCLUDE Proc2.ASM, lo cual indica al ensamblador que, en caso de que se soliciten datos, etiquetas o procedimientos externos, éstos se busquen en el archivo incluido. Pass32 proporciona grandes facilidades para el manejo de procedimientos; en este caso, solamente Cad1 debe ser declarada como pública, puesto que los procedimientos se buscan y anexan automáticamente al programa que los llama si es que existen. .COMMENT * Programa: Proc3.ASM Autor: Juan Carlos Guzmán C. Descripción: Este programa ilustra la forma de utilizar procedimientos y datos externos en los programas por medio de las directivas de inclusión include y public. .MODEL TINY .INCLUDE proc2.ASM ;Incluir el archivo proc2.asm ;el cual contiene la variable de cadena ;Cad1 y los procedimientos externos ;usados en este programa. .DATA Cad2 db 'Esta es una cadena de prueba 2…',13,10,'$' .CODE INICIO: ;Punto de entrada al programa Mov Dl,20 ;X=20 Mov Dh,10 ;Y=10 Call GotoXY ;GotoXY 20,10 Lea DX,Cad2 ;DX->Cad2 en Proc3.asm Call Imprime_Cad ;Imprime Cad2 Lea DX,Cad1 ;DX->Cad1 en Proc2.asm Call Imprime_Cad ;Imprime Cad1 Mov AX,04C00h ;Fin del programa Int 21h ; END INICIO END .COMMENT * Programa: Proc2.ASM Autor: Juan Carlos Guzmán C. Descripción: Este programa ilustra la forma de utilizar procedimientos en los programas por medio de la instrucción Call y la forma de pasarles parámetros. .MODEL TINY .DATA .PUBLIC Cad1 db 'Esta es una cadena de prueba…',13,10,'$' .CODE INICIO: ;Punto de entrada al programa Mov DL,20 ;X=20 Mov DH,10 ;Y=10 Call Gotoxy ;GotoXY 20,10 Lea DX,cad1 ;DX->Cad1 Call Imprime_Cad ;Imprimir Cad1 Mov Ax,04C00h ;Terminar y regresar al dos Int 21h ; END INICIO ;*********************************************************************
;Procedimiento: GotoXY ;Descripción: Coloca el cursor una posición especifica de la pantalla ;Parámetros: Dl=X, Dh=Y ;*********************************************************************
PROC GotoXY Xor Bh,Bh Mov Ah,02h Int 10h Ret ENDP GotoXY ;***********************************************************************
;Procedimiento: Limpia_Pantalla ;Descripción: Imprime una cadena de caracteres en la posición del cursor ;Parámetros: La dirección de la cadena en DX ;***********************************************************************
PROC Imprime_Cad Mov Ah,09h Int 21h Ret ENDP Imprime_Cad END
Con estas capacidades, es fácil crear bibliotecas de procedimientos y macros que puedan ser utilizados constantemente por los demás programas, ahorrando con ello tiempo de programación al reutilizar código fuente. El siguiente programa muestra la forma de escribir una biblioteca de procedimientos y la forma de utilizarlos en los programas. .COMMENT * Programa: Proc3.ASM Autor: Juan Carlos Guzmán C. Descripción: Este programa ilustra la forma de utilizar procedimientos y datos externos en los programas por medio de las directivas de inclusión include y public. .MODEL TINY .INCLUDE proclib.inc ;Incluir el archivo proclib.inc ;el cual contiene la variable de cadena ;Cad1 y los procedimientos externos ;usados en este programa. .DATA Cad1 db 'Esta es una cadena de prueba 2…',13,10,'$' Cad2 db 'Presiona una tecla…','$' .CODE INICIO: ;Punto de entrada al programa Call limpia_Pantalla ; Mov Dl,20 ;X=20 Mov Dh,10 ;Y=10 Call GotoXY ;GotoXY 20,10 Lea DX,Cad1 ;DX->Cad1 Call Imprime_Cad ;Imprime Cad1 Mov Dl,40 ; Mov Dh,24 ; Call GotoXY ;GotoXY 40,25 Lea DX,Cad2 ; Call Imprime_Cad ;Imprime Cad2 Call Espera_Tecla ;Esperar por una tecla presionada Mov AX,04C00h ;Fin del programa Int 21h ; END INICIO END .COMMENT Biblioteca de Procedimientos en Lenguaje ensamblador .CODE ;*********************************************************************
;Procedimiento: GotoXY ; Descripción: Coloca el cursor una posición especifica de la pantalla ; Parámetros: Dl=X, Dh=Y ;*********************************************************************
PROC GotoXY Xor Bh,Bh Mov Ah,02h Int 10h Ret ENDP GotoXY ;***********************************************************************
;Procedimiento: Imprime_Cad ; Descripción: Imprime una cadena de caracteres en la posición del cursor ; Parámetros: La dirección de la cadena en DX ;***********************************************************************
PROC Imprime_Cad Int 21h Ret ENDP Imprime_Cad ;**********************************************************************
;Procedimiento: Limpia_Pantalla ; Descripción: Limpia la pantalla de la computadora y coloca el cursor ; en 0,0. ; Parámetros: Ninguno ;**********************************************************************
PROC Limpia_Pantalla mov ax,0600h mov bh,17h mov cx,0000h mov dx,184fh int 10h Mov dx,0000h Call Gotoxy Ret ENDP Limpia_Pantalla ;**********************************************************************
;Procedimiento: Espera_Tecla ; Descripción: Detiene la ejecución de un programa hasta que se presiona ; una tecla ; Parámetros: Ninguno ;**********************************************************************
PROC Espera_Tecla mov ah,10h int 16h Ret ENDP Espera_Tecla
Pascal y ensamblador Como ya se mencionó, la programación en lenguaje ensamblador proporciona un mayor control sobre el hardware de la computadora, pero también dificulta la buena estructuración de los programas. La programación híbrida proporciona un mecanismo por medio del cual podemos aprovechar las ventajas del lenguaje ensamblador y los lenguajes de alto nivel, todo esto con el fin escribir programas más rápidos y eficientes. En esta sección se mostrará la forma para crear programas híbridos utilizando el lenguaje ensamblador y Turbo Pascal. Turbo Pascal permite escribir procedimientos y funciones en código ensamblador e incluirlas como parte de los programas en lenguaje Pascal; para esto, Turbo Pascal cuenta con dos palabras reservadas: Assembler y Asm. Assembler permite indicarle a Turbo Pascal que la rutina o procedimiento que se está escribiendo está totalmente escrita en código ensamblador. Ejemplo de un procedimiento híbrido: Procedure Limpia_Pantalla; Assembler; Asm Mov AX,0600h Mov BH,18h Mov CX,0000h Mov DX,184Fh Int 10h End;
El procedimiento del listado 23 utiliza la función 06h de la Int 10h del BIOS para limpiar la pantalla, este procedimiento es análogo al procedimiento ClrScr de la unidad CRT de Turbo Pascal. Por otro lado, Asm nos permite incluir bloques de instrucciones en lenguaje ensamblador en cualquier parte del programa sin necesidad de escribir procedimientos completos en ensamblador. Ejemplo de un programa con un bloque de instrucciones en ensamblador:{ Este programa muestra como se construye un programa híbrido utilizando un bloque Asm… End; en Turbo Pascal. El programa solicita que se introduzcan dos número, después calcula la suma por medio de la instrucción Add de ensamblador y finalmente imprime el resultado en la pantalla.}Program hibrido; Uses Crt; Var N1,N2,Res : integer; Begin Writeln("Introduce un número: "); Readln(N1); Writeln("Introduce un número: "); Readln(N2); Asm Mov AX,N1; Add AX,N2; Mov Res,AX End; Writeln("El resultado de la suma es: ",Res); Readln; End.
El programa del listado 24 realiza la suma de dos cantidades enteras (N1 y N2) introducidas previamente por el usuario, después almacena el resultado en la variable Res y finalmente presenta el resultado en la pantalla. El lenguaje ensamblador no cuenta con funciones de entrada y salida formateada, por lo cual es muy complicado escribir programas que sean interactivos, es decir, programas que soliciten información o datos al usuario. Es aquí donde podemos explotar la facilidad de la programación híbrida, en el programa anterior se utilizan las funciones Readln y Writeln para obtener y presentar información al usuario y dejamos los cálculos para las rutinas en ensamblador. En el siguiente listado nos muestra la forma de escribir programas completos utilizando procedimientos híbridos. {Este programa solicita al usuario que presione alguna tecla, cuando la tecla es presionada, ésta se utiliza para rellenar la pantalla. El programa termina cuando se presiona la tecla enter. El programa utiliza tres procedimientos: Limpia_Pantalla: Este se encarga de borrar la pantalla Cursor_XY: Este procedimiento reemplaza al GotoXY de Pascal Imprime_Car: Este procedimiento imprime en pantalla el carácter que se le pasa como parámetro. } Program Hibrido2; Uses Crt; Var Car: Char; i,j : integer;{Este procedimiento limpia la pantalla y pone blanco sobre azul} Procedure Limpia_Pantalla; Assembler; Asm Mov AX,0600h Mov Bh,17h Mov CX,0000h Mov DX,184Fh Int 10h End;{Este procedimiento imprime el carácter en la pantalla} Procedure Imprime_Car(C: Char); Assembler; Asm Mov Ah,02h Mov Dl,C Int 21h End;{Este procedimiento tiene la misma función que el procedimiento GotoXY de Turbo Pascal} Procedure Cursor_XY(X,Y: Byte); Assembler; Asm Mov Ah,02h Mov Bh,00h Mov Dh,Y Mov Dl,X Int 10h End; Begin Limpia_Pantalla; Repeat Limpia_Pantalla; Cursor_XY(0,0); Write('Introduce un carácter: '); Car:=ReadKey; Imprime_Car(Car); Limpia_Pantalla; If car <> #13 then Begin For i:=0 to 24 do For j:=0 to 79 do Begin Cursor_XY(j,i); Imprime_Car(Car); End; Cursor_XY(30,24); Write('Presiona enter para salir u otro para seguir…'); Readln; Until car = #13; End.
Tal vez no sea el lenguaje de programación más sencillo de aprender, pero el lenguaje ensamblador es y seguirá siendo una de las herramientas de programación más utilizadas por todas aquellas personas que desean tener un mayor grado de comprensión sobre el funcionamiento a nivel de dispositivo de una computadora personal. El lenguaje ensamblador no está relegado únicamente a computadoras antiguas con sistemas operativos en modo texto como el MS-DOS. Existe en la actualidad una gran cantidad de programas ensambladores que nos permiten programar en ambientes operativos gráficos como Windows 95/98, Windows NT y Linux, y una muestra de ello es el ensamblador que se utilizó para probar los programas de ejemplo de este trabajo. Por lo tanto, si alguien piensa que el lenguaje ensamblador ya pasó de moda, tal vez debería reconsiderar su postura y visitar algunas de las páginas en Internet que se dedican a cubrir temas sobre programación en lenguaje ensamblador y que se actualizan diariamente, tal vez lo que descubra le haga cambiar de opinión.
Abel, P.; Lenguaje Ensamblador para IBM PC y Compatibles; Ed. Prentice Hall; 3ª Edición; 1996. Brey, B.; Los microprocesadores de Intel: Arquitectura, Programación e Interfaces; Ed. Prentice Hall; 3ª Edición; 1995. Caballar, J.; El libro de las comunicaciones del PC: técnica, programación y aplicaciones; Ed. Rama-Computec; 1ª Edición; 1997. Morgan y Waite; Introducción al microprocesador 8086/8088; Ed. Byte Books/Mc Graw Hill; 1ª Edición; 1992. Pawelczak; Pass32 32 bit Assembler V 2.5 Instruction Manual; 1997. Rojas, A.; Ensamblador Básico; Ed. Computec; 2ª Edición; 1995. Socha y Norton; Assembly Language for the PC; Ed. Brady Publishing; 3ª Edición; 1992. Tannenbaum, A.; Organización de Computadoras un enfoque estructurado; Ed. Prentice Hall; 3ª Edición; 1992. Páginas en Internet con información relacionada NASM Home Page: Esta página contiene información sobre la programación en lenguaje ensamblador y una gran cantidad de enlaces hacia otras páginas con temas relacionados. http://www.cryogen.com/Nasm Pass32 Home Page: Esta página contiene la información más reciente sobre el desarrollo y nuevas versiones del ensamblador Pass32 http://www.geocities.com/SiliconValley/Bay/3437/index.html
Autor:
Ing. Juan Carlos Guzmán C.
Página anterior | Volver al principio del trabajo | Página siguiente |