Vous êtes sur la page 1sur 9

Entrada y Salida (E/S) en el Lenguaje Ensamblador 8086

Cada microprocesador proporciona las instrucciones para E/S de los dispositivos que se unen a l, ej. el teclado y la pantalla. Los 8086 proporciona las instrucciones in para la entrada y out para la salida. Estas instrucciones son absolutamente complicadas de utilizar, as que en lugar de esto, utilizamos generalmente el sistema operativo para hacer E/S. El sistema operativo proporciona una gama de los subprogramas de E/S, en mucho de la misma manera que una biblioteca extensa de subprogramas disponibles para el programador de C. En C, para realizar una operacin de E/S, llamamos un subprograma usando su nombre para indicar sus operaciones, ej. putchar(), printf(), getchar(). Adems podemos pasar un parmetro al subprograma, por ejemplo se pasa como parmetro el caracter que ser mostrado por el putchar() ej. putchar(c). En el lenguaje ensamblador debemos tener un mecanismo para llamar al sistema operativo para que realice E/S. Adems debemos poder decir al sistema operativo qu clase de operacin de E/S deseamos realizar, ej. leer un caracter del teclado, exhibir un carcter o una secuencia en la pantalla o para hacer E/S en el disco. Finalmente, debemos tener medios para pasar parmetros al subprograma operativo. En el lenguaje ensamblador 8086, no llamamos subprogramas del sistema operativo por nombre, en vez de esto, utilizamos un mecanismo de interrupcin del software. Las seales de una interrupcin ordenan al procesador suspender su actividad actual (es decir su programa corriendo) y de pasar control a un programa del servicio de la interrupcin (es decir parte del sistema operativo). Una interrupcin del software es generada por un programa (en oposicin con una generada por el hardware). La instruccin interna 8086 genera una interrupcin del software. Utiliza un solo operando que es un nmero que indica qu subprograma del MSDOS debe ser invocado. Para E/S y algunas otras operaciones, el nmero usado es 21h. As, la instruccin int 21h transfiere control al sistema operativo, a un subprograma que maneje operaciones de E/S. Este subprograma maneja una variedad de operaciones de E/S llamando subprogramas apropiados. Esto significa que debes tambin especificar qu operacin de E/S (ej. leer un caracter, mostrar un caracter) deseas realizar. Esto es hecho poniendo un nmero especfico en un registro. El registro ah se utiliza para pasar esta informacin. Por ejemplo, el subprograma para mostrar un caracter es el subprograma nmero 2h. Este nmero se debe almacenar en el registro ah. Ahora estamos en una posicin para describir salida del caracter. Cuando se acaba la operacin de E/S, el programa del servicio de la interrupcin termina y nuestro programa ser reasumido en la instruccin del siguiente int.

Salida de Caracteres:
La tarea aqu es mostrar un solo carcter en la pantalla. Hay tres elementos implicados en realizar esta operacin usando la instruccin int:

1- Especificamos el caracter que se mostrar. Esto es hecho almacenando el cdigo ASCII del
caracter en un registro especfico del 8086. En este caso utilizamos el registro del d1, es decir utilizamos el d1 para pasar un parmetro al subprograma de la salida. 2- Especificamos cules de los subprogramas de E/S del MSDOS deseamos utilizar. El subprograma para mostrar un caracter es el subprograma nmero 2h. Este nmero se almacena en el registro ah. 3- Solicitamos al MSDOS para realizar la operacin de E/S usando la instruccin interna. Esto significa que interrumpimos nuestro programa y transferimos control al subprograma del MSDOS que hemos especificado usando el registro ah. Ejemplo 1: Escriba un fragmento de cdigo para mostrar el caracter ' a ' en la pantalla: Versin en C: putchar( a ) ; Versin en 8086:

mov dl, a ; dl = a mov ah, 2h ; subprograma de caracter de salida int 21h ; llama al caracter de salida del ms-dos Como puedes ver, esta tarea simple es absolutamente complicada en lenguaje ensamblador.

Entrada de Caracteres:
La tarea aqu es leer un solo caracter del teclado. Hay tambin tres elementos implicados en la ejecucin el caracter de entrada:

1- As como para el caracter de salida, especificamos cules de los subprogramas de E/S del MSDOS
deseamos utilizar, es decir el caracter de entrada del subprograma del teclado. Este es el subprograma numero 1h del MSDOS. Este nmero se debe almacenar en el registro ah. 2- Llamamos al MSDOS para realizar la operacin de E/S usando la instruccin int para la salida del caracter. 3- El subprograma del MSDOS utiliza el registro al para almacenar el caracter que lee del teclado. Ejemplo 2: Escriba un fragmento de cdigo para leer un caracter desde el teclado Versin en C: c = getchar(); Versin en 8086: mov ah, 1h ; subprograma de entrada del teclado int 21h ; caracter de entrada ; carcter es almacenado en a1 mov c, a1 ; copia el caracter de a1 a c El ejemplo siguiente combina dos los anteriores, leyendo un carcter del teclado y exhibindolo. Ejemplo 3: leyendo un caracter y mostrandolo Versin en C: c = getchar(); putchar( c ) ; Versin en 8086: mov ah, 1h ; subprograma de entrada del teclado int 21h ; caracter de entrada ; carcter es almacenado en a1 mov d1, a1 ; copia el caracter a d1 mov ah, 2h ; subprograma de salida de carcter int 21h ; muestra el caracter en d1

Un programa completo:
Ahora estamos en una posicin para escribir un programa completo 8086. Debes utilizar un editor para incorporar el programa en un archivo. El proceso de usar el editor (editar) es una forma bsica de procesamiento de textos. Esta habilidad no tiene ninguna importancia en la programacin. Utilizamos los programas de MASM y del ACOPLAMIENTO de Microsoft para montar y unir programas del lenguaje ensamblador 8086. Los archivos del programa de MASM deben tener nombres con la extensin (3 caracteres despus del perodo) asm. Llamaremos nuestro primer programa prog1.asm, en el mostramos la letra ' a ' en la pantalla. (puedes utilizar cualquier nombre que desees. Es una buena idea elegir un nombre de archivo significativo). Habiendo ingresado y guardado el programa usando un editor, debes entonces utilizar los comandos de MASM y del ACOPLAMIENTO para traducirlo al cdigo mquina y poder ejecutarlo, y es como sigue: C> masm prog1 Si tienes errores de sintaxis, obtendrs mensajes de error de estos puntos. Despus tienes que editar tu programa, corregirlo y repetir el comando anterior, osino para proceder al comando de acoplamiento, presiona RETURN en respuesta a los avisos para los archivos desde el masm o el acoplamiento. C> link prog1 Para ejecutar el programa, incorpora simplemente el nombre del programa y presiona enter:

C> prog1 a C> Ejemplo 4: un programa completo para mostrar la letra a en la pantalla: ; prog1.asm: muestra la letra a en la pantalla ; Author: Joe Carthy ; Date: March 1994 .model small .stack 100h .code start: mov dl, a ; almacena el codigo ascii de la a en d1 mov ah, 2h ; funcion ms-dos para caracter de salida int 21h ; muestra el caracter en el registro d1 mov ax, 4c00h ; retorna a ms-dos int 21h end start Las primeras tres lneas del programa son comentarios para dar el nombre del archivo que contiene el programa, explican su propsito, dan el nombre del autor y la fecha en la que el programa fue escrito. Las primeras dos directivas, .model y .stack se refieren a cmo tu programa ser almacenado en memoria y que tamao de pila requiere. La tercera directiva, .code, indica donde las instrucciones de programa (es decir el cdigo del programa) comienzan. Por el momento, s suficiente para decir que necesitas comenzar todos los programas en el lenguaje ensamblador en un formato particular (no necesariamente como el formato dado arriba). Tu programa debe tambin acabar en un formato particular, la directiva del final indica donde acaba tu programa. En el centro se encuentra el cdigo que tu mismo escribes. Debes tambin especificar donde comienza tu programa, es decir cual es la primera instruccin a ser ejecutada. ste es el propsito de la etiqueta, start. (nota: Podramos utilizar cualquier etiqueta, ej. begin en lugar de start). Esta misma etiqueta es tambin usada para la directiva end. Cuando un programa ha acabado, volvemos al sistema operativo. De la misma manera que al realizar una operacin de E/S, esto tambin es logrado usando la instruccin int. En este tiempo se utiliza el subprograma de ms-dos nmero 4c00h. Este es el subprograma para terminar un programa y volver al MSDOS. Por lo tanto, aqu estn las instrucciones: mov ax, 4c00h; Cdigo para retornar a MSDOS int 21H; Termina programa termina un programa y te retorna a MSDOS.

Un pequeo consejo (tip) para ahorrar tiempo:


Puesto que tus programas comenzarn y acabarn a usar el mismo formato, puedes ahorrarte tu tiempo introduciendo este codigo para cada programa. Creas una plantilla del programa llamado por ejemplo, template.asm, que contiene el cdigo estndar para comenzar y para acabar tus programas del lenguaje ensamblador. Entonces, cuando deseas escribir un nuevo programa, copias este programa a un archivo nuevo, opcion de la plantilla por ejemplo, prog2.asm, como sigue (ej. con el comando de copia del MSDOS): C> copy template.asm io2.asm Despus editas prog2.asm e introduces tu cdigo en el lugar apropiado. Ejemplo 3.9: La siguiente plantilla podras utilizar para tu primer programa ; <nombre de archivo>.asm: ; Author: ; Date: .model small .stack 100h .code start: ; < tu codigo va aqui > mov ax, 4c00h ; retorna a ms-dos int 21h

end start Para escribir un nuevo programa, introduces tu cdigo en el lugar apropiado segn lo indicado arriba. Ejemplo 3.10: Escribe un programa que lee un caracter desde el teclado y lo muestra en pantalla. ; prog2.asm: lee un caracter y lo muestra ; Author: Joe Carthy ; Date: March 1994 .model small .stack 100h .code start: mov ah, 1h ; subprograma de entrada de teclado int 21h ; lee el carcter dentro de a1 mov dl, al mov ah, 2h ; despliega el subprograma int 21h ; muestra el caracter en d1 mov ax, 4c00h ; retorna a ms-dos int 21h end start Si se asume que se introduce la letra ' B ' en el teclado cuando ejecutes el programa, la salida aparecer como sigue: C> prog2 BB Reescribe el programa anterior para utilizar un aviso: C>prog4 ?B B ; prog4.asm: aviso del usuario con ? ; Author: Joe Carthy ; Date: March 1994 .model small .stack 100h .code start: ; muestra ? mov dl, ? ; copia ? a dl mov ah, 2h ; despliega subprograma int 21h ; llama ms-dos para desplegar ? ; lee caracter desde el teclado mov ah, 1h ; subprograma de entrada de teclado int 21h ; lee el carcter dentro de a1 ; guarda el carcter ingresaso mientras desplegamos un espacio mov bl, al ; copia caracter a b1 ; muestra el caracter del espacio mov dl, ; copia espacio dl mov ah, 2h ; despliega subprograma int 21h ; llama ms-dos para mostrar espacio ; muestra caracter leido desde teclado mov dl, bl ; copia caracter ingresado a d1 mov ah, 2h ; despliega subprograma int 21h ; mustra caracter en dl mov ax, 4c00h ; retorna a ms-dos int 21h end start Nota: En este ejemplo debemos ahorrar el caracter introducido (lo ahorramos en bl) de modo a utilizar el ax para el nmero del subprograma de la exhibicin. Ejemplo 3.12: Modifica el programa anterior de modo que el caracter que entrara, se exhibe en la lnea siguiente, como se indica seguidamente C> io4 ?x x En esta versin, necesitamos hacer salir los caracteres del retorno del carry y de la lnea de avance:

El retorno (Carriage Return ASCII 13D) es el caracter de control para traer el cursor al comienzo de una lnea. La linea de avance(Line-feed ASCII 10D) es el caracter de control que trae el cursor abajo a la lnea siguiente en la pantalla. (utilizamos el CR de las abreviaturas y el LF para referir a retorno y a line-feed en comentarios.) En programas de C y de Java utilizamos el carcter ' \n ' del newline para generar una nueva lnea que en efecto cause un retorno y un linefeed que se transmitirn a su pantalla. ; io4.asm: mensaje de usuario con ?, ; leer caracter y exhibir los caracteres CR, lf ; seguido por el carcter que entr. ; Author: Joe Carthy ; Date: March 1994 .model small .stack 100h .code start: ; muestra ? mov dl, ? ; copia ? a dl mov ah, 2h ; despliega el subprograma int 21h ; muestra ? ; lee caracter desde teclado mov ah, 1h ; subprograma de entrada de teclado int 21h ; lee caracter dentro de al ; guarda el carcter ingresaso mientras desplegamos Return and Linefeed mov bl, al ; save character in bl ;muestra Return mov dl, 13d ; dl = CR mov ah, 2h ; despliega el subprograma int 21h ; muestra CR ;muestra Line-feed mov dl, 10d ; dl = LF mov ah, 2h ; despliega el subprograma int 21h ; muestra LF ; muestra caracter leido desde teclado mov dl, bl ; copia caracter a dl mov ah, 2h ; despliega el subprograma int 21h ; muestra caracter en dl mov ax, 4c00h ; retorna a ms-dos int 21h end start La identacin y la documentacin, segn lo mencionado antes, son la responsabilidad del programador. El programa 3,13 abajo es una manera totalmente vlida de incorporar el programa presentado anterior en el ejemplo 3,12: Example 3.12 sin identacin ni comentarios .model small .stack 100h .code start: mov dl,? mov ah,2h int 21h mov ah,1h int 21h mov bl,al mov dl,13d mov ah,2h int 21h mov dl,10d mov ah,2h int 21h mov dl,bl mov ah,2h int 21h mov ax,4c00h

int 21h end start Qu programa fue ms facil de leer y entender???

String de salida:
Un String(secuencia) es una lista de los caracteres tratados como unidad. En lenguajes de programacin denotamos un String constante usando comillas, ej. "incorpore el primer nmero". En lenguaje ensamblador 8086, las comillas solas o dobles pueden ser utilizadas.

Definiendo variables String:


Las 3 definiciones siguientes son maneras equivalentes de definir un String "ABC": version1 db abc ; string constante version2 db a, b, c ; caracteres constantes version3 db 97, 98, 99 ; codigos ASCII La primera versin utiliza el mtodo de idiomas de alto nivel e incluye simplemente la secuencia en comillas. ste es el mtodo preferido. La segunda versin define una secuencia especificando una lista de las constantes de caracter que forman el String La tercera versin define una secuencia especificando una lista de los cdigos ASCII que forman el String. Podemos tambin combinar los mtodos antedichos para definir una secuencia como en el ejemplo siguiente: message db Hello world, 13, 10, $ El mensaje de la secuencia contiene ' hola mundo ' seguido por el retorno (ASCII 13), el line-feed (ASCII 10) y el carcter de ' $ '. Este mtodo es muy til si deseamos incluir caracteres de control (tales como return) en una secuencia. Terminamos la secuencia con el carcter de ' $ ' porque hay un subprograma del MSDOS (nmero 9h) para exhibir secuencias que espera que la secuencia sea terminada por el carcter de ' $ '. Es importante entender que el db no es una instruccin del lenguaje ensamblador. Es llamada directiva. Una directiva dice al ensamblador para hacer algo, cuando se traduce tu programa a codigo maquina. La directiva del DB dice a ensamblador que almacene unos o ms bytes en una posicin de memoria nombrada. De los ejemplos antedichos, las localizaciones nombradas son version1, version2, version3 y mensaje. Estos son en efecto, variables String. Para exhibir un String debemos saber dnde comienza y termina. El principio de la secuencia es dado obteniendo su direccin usando al operador compensado. El extremo de una secuencia puede ser encontrado conociendo la longitud de la secuencia o almacenando un carcter especial en el extremo de la secuencia que acta como centinela. Hemos utilizado ya los subprogramas del MSDOS para el carcter E/S (nmero 1h para leer un solo carcter del teclado y nmero 2h para exhibir un carcter en la pantalla.)

Salida de Strings:
El MSDOS proporciona el subprograma nmero 9h para mostrar los String que son terminados con el carcter de ' $ '. Para utilizarlo debemos: 1- Asegurar que la secuencia termina con el carcter de ' $ '. 2- Especificar q la secuencia que se exhibir est almacenado en el registro dx 3- Especificar que el subprograma de la salida de la secuencia 9h est almacenado en ah. 4- Usar int 21h para llamar a ms-dos para ejecutar el subprograma 9h. El cdigo siguiente ilustra cmo el String hola mundo, seguido por los caracteres de la retorno y del line-feed, puede ser exhibido. Escriba un programa para exhibir el mensaje hola mundo seguido por retorno y line-feed: ; io8.asm: muestra el mensaje hola mundo ; Author: Joe Carthy

; Date: March 1994 .model small .stack 100h .data message db Hola mundo, 13, 10, $ .code start: mov ax, @data mov ds, ax ; copia direccion del mensaje a dx mov dx, offset message mov ah, 9h ; string de salida int 21h ; muestra string mov ax, 4c00h int 21h end start En este ejemplo, utilizamos la directiva .data. Se requiere esta directiva cuando las variables de la memoria se utilizan en un programa. Las instrucciones: mov ax, @data mov ds, ax se tratan de variables de la memoria que tienen acceso y deben ser utilizadas con los programas que utilizan variables de la memoria. Vea el libro de textos para la informacin adicional. El operador offset permite que tengamos acceso a la direccin de una variable. En este caso, lo utilizamos para tener acceso a la direccin del mensaje y almacenamos esta direccin en el registro dx. El subprograma 9h puede tener acceso al mensaje del string (o a cualquier string), una vez que se haya pasado la direccin en que comenzaba el string. Ejercicios: 1- Escriba un programa para mostrar MS-DOS usando (a) caracter de salida y (b) string de salida 2- Escriba un programa para mostrar el mensaje ' Ding! Ding! Ding!' y cdigo ASCII 7 de salida tres veces. (el cdigo 7 del ASCII es el carcter del belio. Produce en tu maquina un beep! 3- Escriba un programa para producir un beep (seal sonora), mensaje '?' como aviso, lea un carcter y exhbalo en una nueva lnea.

Instrucciones de control de flujo. Subprogramas:


Un subprograma permite que demos un nombre a un grupo de instrucciones y usar ese nombre cuando deseamos ejecutar esas instrucciones, en vez de tener que escribir las instrucciones otra vez. Por ejemplo, las instrucciones para mostrar un carcter se podran dar con el ya conocido putc (o lo que elijas). Entonces para mostrar un carcter pudes utilizar el putc conocido que causar las instrucciones apropiadas al ser ejecutado. Esto se refiere como llamar el subprograma. En lenguaje ensamblador 8086, la llamada de la instruccin se utiliza para invocar un subprograma, as que por ejemplo, un subprograma del putc sera llamado como sigue: call putc ; mustra el caracter en dl El proceso de dar a un grupo de instrucciones un nombre se refiere como definir un subprograma. Esto se hace solamente una vez.

Definiciones de los subprogramas putc, getc y puts


putc: ; muestra el caracter in dl mov ah, 2h int 21h ret getc: ; lee el caracter dentro de al mov ah, 1h int 21h ret puts: ; display string terminated by $ ; dx contains address of string

mov ah, 9h int 21h ret La instruccin de ret termina el subprograma y arregla para que la ejecucin reasuma en la instruccin despus de la instruccin de la llamada. Referimos generalmente a esa parte de un programa donde la ejecucin comienza como el programa principal (main). En la prctica, los programas consisten en un programa principal y un nmero de subprogramas. Es importante observar que los subprogramas hacen nuestros programas ms fciles leer, escribir y mantener incluso si los utilizamos solamente una vez en un programa. Nota: Los subprogramas se definen despus del cdigo para terminar el programa, pero antes de la directiva del final. Si pusiramos los subprogramas anterior en el cdigo, seran ejecutados sin ser llamado (la ejecucin bajara a travs en ellos). Esto no se debe permitir que suceda. El programa siguiente ilustra el uso de los subprogramas antedichos. C> sub Enter a character: x You entered: x ; subs.asm: mensaje de usuario para ingresar un caracter ; y mostrar el carcter ; Author: Joe Carthy ; Date: March 1994 .model small .stack 100h .data prompt db Enter a character: $ msgout db You entered: $ .code start: mov ax, @data mov ds, ax ; copia la direccion del mensaje a dx mov dx, offset prompt call puts ; muestra el mensaje call getc ; lee carcter dentro al mov bl, al ; guarda carcter dentro de bl ;muestra el siguiente mensaje mov dx, offset msgout call puts ; ; muestra el caracter ingresado mov dl, bl ; copia carcter a dl call putc mov ax, 4c00h ; retorna a ms-dos int 21h

Definiendo Constantes: Macros


La directiva equ es utilizada para definir constantes: Por ejemplo si deseamos utilizar el CR de los nombres y LF, para representar los cdigos ASCII del retorno y line-feed, podemos utilizar este directorio para hacerlo: CR equ 13d LF equ 10d MAX equ 1000d MIN equ 0 El ensamblador, substituye todas las ocurrencias del CR por el nmero 13 antes de que el programa se traduzca al lenguaje maquina. Realiza los reemplazos similares para las otras constantes. Esencialmente, el directorio del equ proporciona una facilidad de la substitucin del texto. Una sola pieza del texto (CR) es substituida por otro pedazo del texto (13), en su programa. Tal facilidad es a menudo llamada a la facilidad macro.

Utilizamos constantes para hacer nuestros programas ms fciles leer y entender. Ejemplo 3,18: El programa, exhibe el mensaje Hello world y usa la directiva equ io9.asm: muestra el mensaje Hello World ; Author: Joe Carthy ; Date: March 1994 .model small .stack 100h .data CR equ 13d LF equ 10d message db Hello World, CR, LF, $ .code start: mov ax, @data mov ds, ax mov dx, offset message call puts ; muestra el mensaje mov ax, 4c00h int 21h ; subprograma definido por el usuario puts: ; display a string terminated by $ ; dx contiene direccion del string mov ah, 9h int 21h ; string de salida ret end start

Vous aimerez peut-être aussi