Está en la página 1de 15

Universidad De El Salvador

Facultad de Ingeniería y Arquitectura


Escuela de Ingeniería Eléctrica
Sistemas Digitales Programables

Guía de laboratorio # 2.

“Introducción al Macro-ensamblador 80X86”

Docente: Ing. Ricardo E. Cortez

Instructores:
Br. Luis Gerardo Perez Herrera.

Br. Christian Eduardo Tercero Cañas.


Objetivos:

• Dar a conocer al estudiante las directivas más utilizadas del Macro-ensamblador en un


programa en lenguaje ensamblador.
• Familiarizar al estudiante con el Macro-ensamblador y el lenguaje ensamblador.
• Que el estudiante aprenda los procesos de ensamblado y enlazado (link) de programas en
lenguaje ensamblador para su ejecución en una computadora personal.
• Crear el código fuente de un programa en lenguaje ensamblador.

Introducción

Un estudio completo de microprocesadores, no solo involucra comprender el hardware, sino que


también es importante saber su conjunto (set) de instrucciones, el cual comprende su
programación; ya que para darle utilidad al microprocesador es necesario hacer uso de este recurso.

El estudio de los microprocesadores queda justificado debido a que la evolución de la tecnología de


la automatización es impresionante (más concretamente la de computadoras). Los CPU’s de circuito
integrado de mediados y finales de los 70’s como el 8086 y 8088 de INTEL poseían alrededor de 105
transistores y conjuntos de instrucciones de aprox. 100 mnemónicos. En el presente se tienen cpus
en circuitos integrados con más de 106 transistores.

Puesto que desea conocerse el lenguaje ensamblador del 8086 (modo real), es importante aclarar
lo siguiente:

¿Por qué molestarse en aprender lenguaje ensamblador, cuando ahora podemos crear rutinas en
otros lenguajes como C, Basic u otros, en los cuales la programación es mucho más fácil?
Existen muchas ventajas de aprender lenguaje ensamblador como:

1. Habilidad para controlar directamente el hardware y desarrollar fragmentos de programas


de rápida ejecución.
2. Conocimiento profundo de sistemas basados en microprocesadores y de la interfaz
hardware/software.
3. Comprensión de la forma en que se manejan las diversas estructuras de datos tanto a bajo
como a alto nivel.

Dicho de otra forma, alguien puede construir una rutina que controle hardware desde cualquier
plataforma de alto nivel (por ejemplo, un programa que controle el movimiento de un motor de
pasos) y dicho programa puede funcionar perfectamente haciendo interfaz desde una PC
cualquiera. Sin embargo, el problema se presenta cuando se requiere que la aplicación se construya
con un hardware mínimo, donde usar una computadora haría incurrir en un gasto excesivo e
innecesario. Generalmente se opta por utilizar un pequeño microprocesador o microcontrolador de
baja velocidad (por ejemplo un 80286 o inferior); en estos casos el programa de control suele
guardarse en memorias ROM ó EPROM cuya capacidad por unidad difícilmente supera los 64K de
memoria. Claramente se observa que el ahorro de memoria y de hardware es un factor
determinante, por lo que es en estos casos cuando el lenguaje ensamblador se vuelve la opción más
adecuada.
Además, los programadores de las librerías de lenguajes de alto nivel programan en ensamblador,
puesto que necesitan que éstas se ejecuten a gran velocidad.

Los requisitos de software necesarios para programar en ensamblador son:

• Un procesador de palabras que genera códigos ASCII


• Un programa ensamblador.
• Un enlazador (linker).

En esta práctica, se explican los conceptos fundamentales de los programas ensambladores, el


lenguaje ensamblador en la familia 8086 y la forma de crear programas usando el programa
ensamblador MASM de Microsoft.

ACLARACIÓN: En esta práctica NO se enseñará al estudiante a programar, sino a construir


programas. Para poder llevar a cabo esta práctica, el estudiante ya deberá ser capaz de dominar
los elementos mínimos necesarios para programar.

Marco Teórico
La diferencia entre programar en un lenguaje ensamblador y uno de alto nivel es similar a la
diferencia entre un auto con palanca de cambios y uno de transmisión automática: Con la
transmisión automática se gana facilidad, pero se pierde control.

Lenguaje Ensamblador

Una instrucción en lenguaje de máquina, es una cadena de dígitos binarios, representada en la


misma base en que opera la máquina. Cuando dicha cadena es interpretada por el hardware,
provoca una respuesta única por parte del computador.
Es importante recordar que cada familia de microprocesadores tiene su propio y único conjunto de
instrucciones.
Por tanto, si se usa una cadena de bits que por ejemplo, causan la suma de 2 registros en un
procesador INTEL, la misma cadena puede causar su multiplicación en un procesador MOTOROLA.

Actualmente, no se trabaja directamente manipulando cadenas de dígitos binarios, sino que


hacemos uso de representaciones simbólicas de esas cadenas. En el lenguaje ensamblador todos los
operadores se representan mediante nombres escogidos debido a sus cualidades autoexplicativas
y mnemotécnicas. Por ejemplo: ADD es para agregar, SUB es para sustraer y de forma parecida
sucede con los demás códigos.

En la mayoría de lenguajes ensambladores, los programadores escogen los nombres del operador,
dejándonos seleccionar muchos de los operadores que necesitamos. Por ejemplo. Si movemos un
valor de memoria que se ha declarado hacia un registro (MOV AX, VALOR), MOV y AX ya son parte
del lenguaje, pero nosotros declaramos VALOR con todos sus atributos. Probablemente la ventaja
más importante de la programación simbólica, en lugar de usar patrones en bits, es el control que
se obtiene sobre lo que se ha dado en llamar binding (atadura), es decir la asignación de valores
directamente reconocibles por la máquina a expresiones simbólicas que uno puede usar en el
programa fuente.

Otra ventaja de programar en el lenguaje simbólico en lugar de en bits es que los símbolos permiten
ver la generalidad del programa. Aunque ambos son lenguajes simbólicos, hay al menos 3 áreas en
las cuales el lenguaje ensamblador nos permite más control sobre la computadora que un lenguaje
compilador:

1. Refinamiento: Sólo el programador en lenguaje ensamblador determina directa y


conscientemente las instrucciones en lenguaje de máquina que serán
ejecutadas y las representaciones detalladas de los datos sobre los cuales
operan; por estas razones nosotros sólo podemos garantizar que el programa
encajará dentro de un área dada de memoria o se ejecutará dentro de un
período de tiempo dado cuando programemos en lenguaje ensamblador. Para
dar una idea del ahorro en tiempo y espacio que significa programar en
lenguaje ensamblador, observemos la comparación que aparece en el apéndice
A.
2. Atención Rápida: Hay una brecha entre el tiempo que el usuario de un compilador encuentra una
necesidad y el tiempo en el que los escritores del compilador pueden
responder a ella. Con un lenguaje ensamblador, podemos codificar una
solución de manera inmediata (prácticamente la única limitante es nuestra
capacidad de programación).
3. Innovación: El lenguaje ensamblador es casi siempre la elección cuando una aplicación de
computadora totalmente nueva está siendo investigada, aun cuando la
necesidad de su utilización podría no estar muy clara al principio.

Programas ensambladores

Un programa ensamblador es aquel que permite escribir código en lenguaje ensamblador en lugar
de tener que usar largas cadenas de bits en lenguaje máquina. La mnemotecnia es el arte de mejorar
la eficiencia de la mente humana. El código de operación mnemónica es un código en el cual los
nombres de las operaciones son abreviados y expresados mnemónicamente para facilitar recordar
la operación que representan. El programa ensamblador clásico toma una rutina y la convierte a
una forma simbólica binaria para más tarde procesarla por medio de un enlazador (linker). Así, con
el MASM de Microsoft la conversión es hecha en dos pasos; o sea que el código fuente es examinado
dos veces.

La estrategia de dos pasos es muy simple: el primer paso, a través del código fuente, recoge todas
las definiciones de símbolos en una tabla de símbolos. El segundo paso convierte el programa en
una forma simbólica a código binario usando la tabla de símbolos del primer paso.

Los ensambladores permiten usar códigos mnemónicos y que nombres simbólicos sean asignados a
localidades de memoria, proporcionan facilidades para direccionar los cálculos en términos de tales
nombres simbólicos y normalmente permiten introducir constantes numéricas y de caracteres de
diversas formas.

Una instrucción típica consiste de un código de operación, una dirección y uno o más campos de
registros. La dirección podría referirse a un área de datos por ejemplo. Un programa ensamblador
procesa un conjunto fijo de códigos mnemónicos y un conjunto de símbolos definidos por el
programador. La dirección de tales símbolos podrían ser definidas explícitamente o implícitamente
atándolas como rótulos a instrucciones particulares o palabras de datos.

Aunque un símbolo represente una dirección, un ensamblador no puede convertir rótulos de


símbolos directamente en direcciones absolutas porque la dirección en memoria en la cual una
instrucción particular será cargada no se conoce en el momento del ensamble, la dificultad es
resuelta en dos pasos:

1. El ensamblador registra el desplazamiento respecto al principio del código, de la instrucción en


cuestión como el valor del rótulo de símbolo.
2. El ensamblador marca el símbolo a la salida del ensamblador como un valor relativo o
relocalizable; este valor es ajustado más tarde por el enlazador (linker) o el cargador.

Un ensamblador proporciona la siguiente información acerca del programa que se ha ensamblado:

• Listado de instrucciones simbólicas.


• Tabla de símbolos definidos/usados en la rutina.
• Tabla de referencia cruzada: para cada símbolo definido, su nombre, valor y una lista de
todas las instrucciones que lo referencian.

Directivas del programa ensamblador.

Las directivas del ensamblador tienen dos propósitos: uno de ellos es el de brindar información para
controlar el proceso de ensamble. Además proporcionan una forma de definir palabras de datos en
un programa.

Las directivas también se conocen como pseudo-operaciones debido a que comúnmente se


designan mediante códigos especiales en el campo de operación.
Macros y macroensambladores

En su forma más simple, una macroinstrucción (un macro) es una sola instrucción de computadora
que representa una secuencia dada de instrucciones Los macros son usados más usados a menudo
para representar secuencias relativamente cortas de instrucciones o secuencias que involucran un
número relativamente grande de inserción de argumentos. Casi siempre un conjunto de macros se
combina en una biblioteca de macros. Un ejemplo muy común de esto es una biblioteca de macros
para ayudar a comunicarse con el sistema operativo.

A medida que vamos creando programas más y más extensos y complejos nos damos cuenta que
un determinado patrón de instrucciones aparece en varios lugares dentro de un programa, solo con
pequeñas variaciones. Esto es particularmente el caso si hay una operación común que requiere
varias instrucciones para su ejecución. En este caso es conveniente el ser capaz de escribir una sola
llamada y que sea el sistema el que genere la secuencia de instrucciones. Hay algunas ventajas en
esto:

✓ Se escriben menos líneas de código, lo cual significa menos posibilidades de errores.


✓ El programa puede ser más legible, principalmente porque hay menos líneas. El uso de
nombres de macros que sean descriptivos también ayuda a la legibilidad.
✓ Finalmente, si en un momento posterior se hace necesario modificar la función que el macro
realiza, únicamente tenemos que cambiar un lugar (el macro) en vez de hacerlo en múltiples
partes del programa en múltiples programas.

Para trabajar con macros, se necesita una pieza de software llamada macroprocesadores, el cual es
generalmente parte de un lenguaje ensamblador. El trabajo de un macroprocesador es sencillo: El
programador proporciona algunas definiciones de macros y que es lo que las va a reemplazar; y el
macroprocesador luego reemplaza cada aparición del macro con su correspondiente secuencia de
instrucciones definidas.

Un macroprocesador a menudo se combina con un ensamblador para que el programador le


parezca que los dos son uno sólo llamado macro ensambladores.

En el MASM de Microsoft, un nuevo macro puede ser creado (o definido) en cualquier punto de un
programa.
Dado que el macroprocesador, ya sea que esté o no incluido en el ensamblador, es puesto en un
modo especial de creación de macro cuando encuentra una definición de macro. La creación de uno
no genera ninguna instrucción en el programa. Sólo una llamada explícita a un macro genera
instrucciones.

Componentes de un macro
Un macro está pensado para limitar el área de interés para cualquier otra tarea y para minimizar el
impacto de cambios posteriores. Esto lo consigue aislado y formalizando los canales de
comunicación, o interfaces entre sí mismo y otras componentes del programa.

Todos los macros en el MASM poseen un nombre, un inicio, un cuerpo y un final. Normalmente
especifican una lista de uno o más parámetros auxiliares que pueden ser parámetros pasados al
macro. El nombre de un macro es un símbolo estándar de ensamblador. Puede incluir de 1 a 31
caracteres alfanuméricos, incluso los caracteres especiales ($ _ ? . @).
Los nombres auxiliares son una lista de parámetros, separados por comas, los cuales serán utilizados
dentro del macro. Los parámetros son variables temporales cuyos valores podrían cambiar con cada
nueva invocación del macro. Estos parámetros pueden ser numéricos o textos (incluyendo nombres
de registros), otros nombres de macros mnemónicos y etiquetas de programa. Las etiquetas se
refieren o corresponden a valores numéricos o posiciones de memoria.

El cuerpo de un macro consiste de opcodes, directivas, etiquetas y comentarios; es decir, el cuerpo


del macro son líneas de código en lenguaje de ensamble además de documentación interna.

Cuando se invoca un macro, este es expandido de manera que los parámetros referenciados en el
cuerpo se reemplazan por los valores que les hemos pasado. El final es un ENDM, lo cual señala al
macroensamblador que el código del macro ha terminado.

Macros vrs. Subrutinas


Un macro es en realidad reemplazado por su forma expandida después de haber sido procesado por
el macroensamblador, de manera que si nuestro programa contiene “n” llamadas al macro,
entonces “n” copias de las instrucciones que representa son insertadas en el programa. En cambio
en una sub-rutina existe una sola copia de la secuencia de instrucciones y cada llamada se reemplaza
por un salto a esa sección, la cual se ejecuta y luego se retorna.

; Esqueleto del ejemplo de un macro a fin de mostrar las partes


; Principales de un macro.

; NOMBRE MACRO DIRECTIVA PARÁMETROS AUXILIARES

EJEMPLO1 MACRO PARA00,PARA01 ;INICIO DE LA MACRO.

; Ahora van los comentarios internos de la macro.

; El cuerpo de la macro incluye todo lo que se encuentra entre la


; línea que contiene la directiva MACRO y la directiva ENDM.

MOV AX,PARA00 ;instrucción típica.


EXITM ; directiva

ENDM ; Fin del macro.

Tal como veremos a continuación la estructura de un macro tiene muchos puntos en común con la
estructura de un programa completo en lenguaje ensamblador.

Estructura de un programa en el MASM

En el ejemplo que se presenta a continuación se pretende mostrar la estructura de un programa en


lenguaje de ensamble en el ambiente del MASM. Se hace énfasis en el uso de las directivas más
comunes, ya que sería imposible poder incluir todas las directivas en un programa tan pequeño y
sencillo como este. Sin embargo, si queremos conocer las otras directivas estas se encuentran
bastante explicadas en guías posteriores.
Antes de presentar el listado del programa, (ver apéndice “A”) es necesario aclarar que el código
fuente puede ser escrito usando cualquier procesador de texto que genere un archivo en código
ASCII puro. A simple vista se nota que este programa no realiza ninguna cosa importante,
únicamente hemos empleado tres instrucciones en lenguaje de ensamble. De hecho, para el
propósito que ha sido expuesto en este ejemplo, podríamos incluso no haber utilizado instrucciones.
Lo importante es observar la estructura y la forma de utilización de las directivas.

Debe aclararse que aunque en este ejemplo se han utilizado letras mayúsculas para las instrucciones
y las directivas, esto es indiferente para el ensamblador. Podemos incluso mezclar mayúsculas y
minúscula. CSEB significa lo mismo que CseB para el programa ensamblador. Además la línea de
instrucción puede comenzar en cualquier columna y no es obligatorio utilizar un formato tabulado
para el programa fuente, aunque se recomienda por motivos de claridad y legibilidad de un
programa.

Aunque en un programa en ensamblador es posible trabajar con los cuatro segmentos (CS, SS, DS,
ES), solamente es obligatorio el uso de dos segmentos: el de código y el de pila (stack). Para definir
un segmento utilizamos la directiva SEGMENT, la cual tiene el siguiente formato:

nombre SEGMENT alineamiento combinación `clase`


:
:
nombre ENDS

El nombre del segmento puede ser único o puede ser el nombre de varios segmentos. Si esto último
es el caso (varios segmentos tienen asignado el mismo nombre), el MASM trata a los segmentos
como si, fueran piezas de un único segmento.

El alineamiento define el rango de direcciones de memoria de las cuales será seleccionada la


dirección de inicio del segmento. El alineamiento puede ser:

➢ BYTE: El segmento puede comenzar en cualquier byte de la memoria.


➢ WORD: El segmento puede comenzar en el límite de una palabra (donde la dirección sea
par).
➢ PARA: El segmento puede comenzar en el límite de un párrafo (dirección divisible por 16).
➢ PAGE: El segmento puede comenzar en los límites de una página (los últimos ocho bits de
la dirección son ceros).

La combinación indica la manera en que los segmentos serán combinados o cargados cuando se
ejecute el enlazador (linker). Si no se señala ningún tipo de combinación, cada segmento recibe su
propio segmento físico cuando es cargado en memoria. La combinación puede ser cualquiera de las
siguientes: PUBLIC, COMMON, AT (dirección), STACK, MEMORY.

PUBLIC indica que todos los segmentos con el mismo nombre y con atributo PUBLIC serán
encadenados juntos.

STACK sirve para indicar que el segmento es parte de la pila o stack.


COMMON sirve para indicar que todos los segmentos con el mismo nombre comenzaran en la
misma dirección y se traslaparán en memoria.

MEMORY indica que todos los segmentos con este atributo se colocarán en direcciones de número
mayor que cualesquiera segmentos. Con AT (memoria), el segmento se coloca en el párrafo indicado
por memoria, que puede ser cualquier expresión sólida; sin embargo no puede contener una
referencia a algún símbolo definido posteriormente en el archivo fuente.

La `clase` se emplea para hacer referencia a una colección de segmentos, los segmentos con el
mismo nombre de clase se colocan en memoria secuencialmente, siguiendo el orden en que los
encontró el enlazador.

La directiva PAGE (Líneas, columnas) sirve para indicar al ensamblador como queremos que nos
genere el listado ensamblado (los valores por defecto son 66 filas y 80 columnas).

Las directivas TITLE y SUBTTL, sirven para colocar un título y un subtítulo a las páginas del listado
ensamblado.

La directiva .8086 le indica al ensamblador que solo debe aceptar instrucciones válidas para los
procesadores 8086/8088.

La directiva ORG inicializa el contador de localidad del MASM. Este contador de localidad es el que
sirve al MASM para llevar el control de la posición actual en el equipo fuente.

La directiva COMMENT sirve para escribir comentarios. El comentario es encerrado por un símbolo
delimitador ($,&, , etc.).

La directiva DB sirve para reservar un área de memoria o para inicializar un área de memoria de 8
bits; a directiva DW reserva un área de 16 bits y DD un área de 32 bits.

En la línea de nuestro programa ejemplo hemos inicializado una parte de la memoria colocando 64
veces la cadena (`stack`)

La última línea de nuestro programa contiene la directiva END. La cual le indica al ensamblador que
hemos llegado al final del programa fuente. Si después de END colocamos una etiqueta, estamos
indicándole al ensamblador el punto de entrada (dónde comenzar a ejecutar).

Proceso de ensamble del programa

Una vez que hemos creado nuestro archivo fuente (el cual debe llevar la extensión .ASM) estamos
preparados para utilizar el MASM. Vamos a asumir que tanto el programa fuente como los
programas del MASM se encuentran en un mismo directorio. Esto lo haremos por motivos de
facilidad y claridad de la explicación. Sin embargo debemos tener en cuenta que esto NO es lo
recomendable si queremos dedicarnos seriamente a la creación de programas; ya que por lo general
el programa procesador de textos se encuentra en un subdirectorio propio, mientras que el MASM
y el linker se encuentran en otro u otros directorios. Esto no será un problema si manejamos
aceptablemente los comandos del DOS, ya que la manera de invocar al MASM es muy parecida a la
sintaxis del DOS.

En esta ocasión utilizaremos la manera más sencilla de ejecutar el ensamble de nuestro programa,
pero se debe tener en cuenta que existen otras formas de invocar al MASM y también existen
algunas opciones que podemos escoger al momento de realizar el ensamble.

Si los archivos de nuestro interés se encuentran en el directorio raíz del disco A; a partir del prompt
del DOS escribimos:
MASM 

El ensamblador nos responde pidiéndonos el nombre del archivo fuente que queremos ensamblar
(asume que tiene extensión .ASM). Entonces escribimos ese nombre (para este ejemplo es el
archivo PRIMASM.ASM)
Primasm 

A continuación nos pide que indiquemos cual es el nombre que le queremos dar al archivo objeto
que se va a generar. Aparecerá entre corchetes el nombre que le será asignado si nosotros no le
indicamos otro nombre. Si aceptamos ese nombre, únicamente presionamos la tecla ENTER().

De igual manera nos pide que le indiquemos el nombre que queremos poner al listado ensamblado
y al archivo con la referencia cruzada. A diferencia de lo que sucede con el archivo objeto; si solo
presionamos la tecla ENTER le estamos indicando que NO queremos que cree esos archivos.

Para nuestro ejemplo si queremos esos dos archivos, por lo tanto escribimos:

Primasm 
Primasm 

Para finalizar, el MASM nos indica si detectó algún error. En caso de que no nos diga explícitamente
cual es el error cometido, puede indicarnos el número de error.

Suponiendo que no se ha detectado ningún error, el siguiente paso es utilizar el programa LINK para
crear un programa ejecutable y relocalizable a partir del programa objeto creado por el MASM.

PROCESO DE ENLAZADO (LINKEO) DEL PROGRAMA

Para ejecutar el encadenamiento (ejecución del programa LINK), solamente escribimos:

link

A continuación, se nos pide que indiquemos el archivo objeto que se desea enlazar. En este caso,
el archivo es PRIMASM.OBJ.
A continuación, se nos pide introducir el nombre del programa ejecutable que va a ser creado. Por
defecto se crea un archivo con el mismo nombre, pero extensión .EXE (PRIMASM.EXE para este
caso). Si este nombre le parece adecuado, solamente presione ENTER ( ).

Finalmente, se pide el nombre que desea ponerle al archivo que contenga el mapa de símbolos. Se
pide también el nombre de las bibliotecas que se desean enlazar con nuestro programa objeto. De
momento no se trabajará con estas últimas peticiones, así que presionaremos [ENTER] 2 veces
seguidas ( ).

Si el enlazador (linker no encuentra ningún error, se creará el programa ejecutable. Para correrlo,
solamente escribimos su nombre a partir de la línea de comandos del DOS como se muestra:

Primasm 

Ya que el programa no posee ninguna instrucción que genere alguna salida visible o audible, no será
posible apreciar el correcto funcionamiento del programa. Además, al correr el programa, se
perderá el control sobre la computadora. Esto se debe a que los programas escritos para correr bajo
DOS deben cumplir con algunas formalidades que permitan su ejecución normal y luego, al finalizar,
debe devolver el control al sistema operativo; pero dado que la creación de programas ejecutables
bajo el DOS NO es uno de los objetivos de esta práctica, se dejará para un laboratorio posterior.

El objetivo de esta práctica es la creación del listado ensamblado, lo cual ya se hizo. En este listado
ensamblado aparece tanto el código fuente como la representación del código de máquina para
cada instrucción ensamblada además de los números de línea asociados con cada línea de listado
(estos números sirven como una referencia para conocer la localización de símbolos) y una columna
mostrando el desplazamiento en hexadecimal (partiendo de cero) de cada instrucción que aparece
en el listado.

Para ver todo lo anterior, podemos escribir TYPE primasm.lst , o bien podemos auxiliarnos
de un procesador de textos tal como el block de notas (NOTEPAD) o cualquier otro.

Como sugerencia, se recomienda antes de realizar la práctica, trate de ensamblar manualmente el


programa PRIMASM.ASM y luego compare los resultados con los obtenidos en PRIMASM.LST
Desarrollo de la práctica

1. Escriba el programa del apéndice A en un procesador de texto y cree un archivo ASCII puro
con extensión .ASM
2. Ensamble el programa y genere el código objeto respectivo. Si encuentra errores, corríjalos
e intente ensamblar nuevamente hasta tener éxito.
3. Imprima el código objeto.
4. Utilice el programa LINK (el enlazador) para crear el programa ejecutable.
5. Córralo.
6. Repita todos los pasos anteriores para el programa del apéndice B.

Asignaciones

✓ Explique el proceso de ensamble de un programa en macro assembler.

✓ Investigue y explique los métodos de lectura de teclado y la impresión en pantalla.

✓ Diseñar un programa en el que se solicite el ingreso de 4 números entre 0 y 20 (los números


menores a 10 deben ser ingresados con un cero a la izquierda), luego del ingreso que
muestre un menú estilo tabla solicitando la operación que se desea realizar, que no distinga
entre minúscula y mayúscula para seleccionar la opción del menú y que en el caso de
ingresar una opción no válida (siempre durante el menú) muestre un mensaje de error y
aguarde a que se presione enter para volver al menú.

✓ Diseñar un programa en el cual se ingresen dos números de un byte cada uno, y que solicite
la operación matemática a realizar, la cual se seleccionara de acuerdo a la siguiente tabla:

Letra Operación
S Suma
R Resta
M Multiplicación
D División
Cualquier otra letra Operación no valida
Sin que haga diferencia entre mayúsculas y minúsculas, es decir si se ingresa “S” o “s” el
programa siempre realice la suma y así con las demás instrucciones.

✓ Diseñe un programa con dos tablas de 10x5, es decir, tablas de 10 posiciones de 5 bytes
cada una de nombres USERS y PASSWORD la primera posición de la tabla USERS debe
contener 5 caracteres (USER1) y la primera posición de la tabla PASSWORD contener 5
caracteres (PASS1). En principio el programa debe solicitar un usuario y contraseña (que
serán los guardados por defecto), de lograr esto correctamente debe mostrarse un menú
estilo tabla

La descripción de las opciones es la siguiente:


debe solicitar un nombre de usuario y una password (imprimir * por cada
N
carácter ingresado) y al finalizar esperar enter para volver al menú,
Debe mostrar un mensaje "sesión finalizada" y volver al menú y por ende
X
restringir las opciones I y N hasta que se inicie sesión.
B Solicitará lo mismo que al inicio del programa.
Debe imprimir los usuarios y contraseñas de la forma USER1-->PASS1 y la opción
I
E finaliza el programa

Todo ingreso de datos correctamente deberá ser almacenado en USERS y PASSWORD


respectivamente, no distinga entre minúscula y mayúscula para seleccionar la opción del menú y
que en el caso de ingresar una opción no válida (siempre durante el menú) muestre un mensaje de
error y espere a que se presione enter para volver al menú
ANEXO

Apéndice A

PAGE 50,132
TITLE PRIMASM Primer programa en ensamblador (PRIMASM.ASM)
SUBTTL Uso de directivas y estructuras de un programa.
.8086

COMMENT +
DESCRIPCION: Este módulo limpia el contenido
del registro AX, haciéndolo cero.
Después coloca en el registro AX
el número 18.
+

STACK SEGMENT PARA STACK 'STACK' ; inicio del segmento de pila.

; A continuación se inicia con cero el segmento de pila (STACK) y


se
; carga con una cadena de caracteres ( 64 veces la palabra
'STACK').

DB 64 DUP ('STACK')

STACK ENDS ; Fin del segmento de pila.

CSEG SEGMENT PARA PUBLIC 'CODE' ; inicio del segmento de código.

ORG 0

ASSUME CS:CSEG,SS:STACK ; definimos los segmentos.

CODIGO PROC NEAR

SUB AX,AX ; Borra el contenido de AX


MOV AX,18D ; asigna a AX el valor 18 (decimal).
SUB AX,18D ; resta 18 decimal a AX,
; volviendo su valor a cero.

CODIGO ENDP

CSEG ENDS ; fin del segmento de código.

END CODIGO ; fin del programa.


Apéndice B

; Programa para desplegar todos los caracteres en pantalla

; El primer paso a dar es definir los segmentos:

; Segmento de pila (STACK) de longitud 256 bytes:

STACK SEGMENT PARA STACK 'STACK'


DB 256 DUP (0)

STACK ENDS

; Segmento de código:

CODE SEGMENT PARA PUBLIC 'CODE'

INICIO PROC FAR


ASSUME CS:CODE,SS:STACK
PUSH DS
MOV AX,0
PUSH AX

; PRIMER PASO: limpiar la pantalla

MOV AX,0B800H ; Dirección del segmento de memoria


; para el adaptador del monitor.
MOV ES,AX ; Fijar a ES como registro base.
MOV DI,0 ; Desplazamiento inicial del segmento ES.
MOV AL,' ' ; Caracter para borrar.
MOV AH,07H ; Byte de atributo para un
; despliegue normal.
MOV CX,2000 ; Número de veces a repetir la
; instrucción que sigue a REP.
CLD ; STOS cargue la memoria y
REP STOSW ; Escribe el caracter contenido en AL
; a la pantalla.

; SEGUNDO PASO: Llenar la pantalla con 256 caracteres


; separados por una fila y una columna c/u.

MOV AL,0 ; AL contiene el caracter a desplegar.


MOV AH,0 ; AH contiene el número de columna.
MOV DI,160 ; DI contiene el desplazamiento y se
; inicia para que apunte al primer
; caracter de la 2a. fila.
; Lazo que llena la pantalla:

LAZO: MOV ES:[DI],AL ; Pone el caracter en la memoria del


; adaptador.
ADD DI,4 ; Apuntar a la próxima posición.
ADD AH,2 ; Actualizar la columna.
CMP AH,80 ; Detectar fin de fila.
JB SALTO ; Si no es fin de fila, saltar
; (ir a "SALTO").
ADD DI,160 ; Si es fin de línea, cambiar de fila.
MOV AH,0 ; Volver a primera columna.
SALTO: CMP AL,255 ; ¿Se han desplegado todos los caracteres?
JE FINAL ; Si ya se desplegaron todos los caracteres,
; ir a la salida.
INC AL ; Ir al próximo caracter.
JMP LAZO ; volver al inicio del lazo.

; TERCER PASO: Después de escribir todos los caracteres, esperar,


; borrar la pantalla y volver al DOS.

FINAL:
MOV AX,400H ; Define el tiempo del retardo
; junto con CX.
RETARDO: MOV CX,0A000H ; El retardo variará según la
; velocidad del CPU.
; Aproximadamente 5 seg. en una
; CPU Pentium ® 75 MHz.
RETARDAR: LOOP RETARDAR
INC CX
DEC AX
JNZ RETARDO
MOV DI,0
MOV AL,' '
MOV AH,07H
MOV CX,2000
REP STOSW
RET

INICIO ENDP
CODE ENDS

END INICIO

Escriba el programa del apéndice B como un procedimiento cercano (denominado


CARACT), el cual debe ser llamado por un programa principal similar a
PRIMASM en cuyo segmento de código se define:

CODIGO PROC FAR


PUSH DS
MOV AX,0
PUSH AX
CALL CARACT
;Aquí escribir instrucciones para leer la tecla "enter". Si es la
;tecla "enter" escribir a continuacion:
RET ;retorno a DOS. Si no es la tecla "enter", esperar hasta que lo
;sea.
CODIGO ENDP
CSEG ENDS
END CODIGO

También podría gustarte