miércoles, 18 de marzo de 2020

EMULADOR 8086


EMULADOR
Definición de emulador


Primeramente, debemos dejar bien claro lo que es un emulador. El concepto más técnico y aceptado de emulador es el siguiente:
Un emulador es un software originalmente pensado para ejecutar programas de diversas índoles, en una plataforma o sistema operativo diferente al programa que deseamos abrir o ejecutar.Podemos decir entonces, que un emulador es un programa diseñado para crear una plataforma virtual que pueda ejecutar un programa determinado, que no haya sido diseñado para ser ejecutado en el PC.


Para qué sirve un emulador

El principal objetivo del emulador, es crear las condiciones necesarias para poder ejecutar un programa diseñado para otras plataformas distintas al PC, de modo que estos programas son utilizados ampliamente para las siguientes actividades:
  • Probar programas de plataformas informáticas diferentes.
  • Ejecutar juegos de plataforma en un ordenador.
  • Ejecutar programas de ordenadores antiguos.
Como podemos ver, los emuladores son ampliamente utilizados para poder jugar juegos antiguos o de plataformas diversas desde la comodidad de nuestro ordenador, utilizando para ello un programa o archivo llamado ROM.


El emu8086 es un emulador del microprocesador 8086 (Intel o AMD compatible) con assembler integrado. A diferencia del entorno de programación en assembler utilizado anteriormente en la cátedra (MASM), este entorno corre sobre Windows y cuenta con una interfaz gráfica muy amigable e intuitiva que facilita el aprendizaje el leguaje de programación en assembler.






El Emulador EMU8086 es el primer programa que se utiliza en el curso de Microprocesadores . se ha elegido este emulador porque posee una interfaz de usuario muy amistosa que permite familiarizarse con los fundamentos de la programación en lenguaje ensamblador de forma muy intuitiva, aparte de eso brinda una serie de recursos para ejecutar y depurar los programas. También tiene algunas desventajas como el de no soportar algunas de las interrupciones más interesantes que posee el sistema operativo y tampoco puede acceder a los puertos físicos (reales), sino que los emula usando otros programas que ya están incluidos en su respectiva carpeta.

Para iniciar se debe ejecutar el archivos EMU886.exe, que se encuentra en la carpeta del mismo nombre, en el directorio raíz; seguramente en la computadora donde corra el programa tendrá otras alternativas para activar el programa, como un acceso directo en el escritorio o en el menú de programas del sistema operativo.
Si está ejecutando la versión 4.05 del EMU8086 observará primero la pantalla de
Bienvenida (welcome), similar a la que se muestra en la Figura 1





Figura 1. Pantalla de bienvenida del emulador EMU8086.

Se presentan cuatro diferentes opciones para elegir:
  • New : Le permite escribir un nuevo código en lenguaje ensamblador (al que
Llamaremos “Código Fuente” y tendrá extensión .ASM)
  • Code examples: Le permite acceder a una serie de programas ejemplos que
pueden ayudarle a comprender funciones más complejas.
  • Quick star tutor : activa un conjunto de documentos de ayuda, se recomienda
revisarlos frecuentemente en caso de dudas.
  • Recent file : Le muestra los últimos archivos que se trabajaron en la máquina.
Para continuar este primer contacto con el emulador, seleccioneNew. Observará una
nueva caja de dialogo “choose code template”, como se muestra en la Figura 2
Figura 2. Caja de dialogo para seleccionar el tipo plantilla (template).
En ella se le presentan seis opciones, cuatro que le permiten usar plantillas predefinidas con algunos de los tipo de archivo que se pueden crear en lenguaje ensamblador: COM template, EXE template, BIN template y BOOT template (cada uno le permite diferentes características que se abordaran a su debido tiempo en el curso). Dos que le permiten usar un espacio vacío “empty workspace” (sin una plantilla) o activar el emulador mismo. Selecciones la opción del espacio vacío. Observará la ventana de edición o mejor dicho el Entorno de Desarrollo Integrado (Integrated Development Environme IDE), como se muestra en la Figura 3, donde escribirá sus archivos fuentes en lenguaje ensamblador, por favor lo confunda con el lenguaje de máquina.
Podrá ver una barra de menú de Windows con sus opciones file, edit, etc. pero también vera unas opciones poco usuales como assembler, emulator, etc. propias del emulador. También vera una serie de botones que le permitirán crear un nuevo archivo (new), abrir un archivo que ya existe (open), abrir un ejemplo (examples), compilar un archivo fuente (compile), emular un archivo ejecutable (emulate) y otras opciones que ira descubriendo a medida que se familiarice con el programa.
Figura 3. Ventana de edición o Entorno de Desarrollo Integrado IDE del EMU8086.
Bueno, es el momento de estudiar nuestro primer programa en lenguaje ensamblador, el cual imprime en pantalla algunas cadenas de texto. Para comprender mejor como funciona revise primero la Figura 4, donde se presenta un diagrama de flujo.

martes, 17 de marzo de 2020

2.11 OBTENCIÓN DE CADENA CON REPRESENTACIÓN DECIMAL.



En este modo, los datos son proporcionados directamente como parte de la instrucción.
Ejemplo:
Mov AX,34h ;
Copia en AX el número 34h hexadecimal Mov CX,10 ;
Copia en CX el número 10 en decimal
.COMMENT
Programa: PushPop.ASM
Descripción: Este programa demuestra el uso de las instrucciones para el manejo de la pila, implementando la instrucción XCHG con Push y Pop
MODEL tiny
.CODE
Inicio: ;Punto de entrada al programa
Mov AX,5 ;AX=5
Mov BX,10 ;BX=10
Push AX ;Pila=5
Mov AX,BX ;AX=10
Pop BX ;BX=5
Mov AX,4C00h ;Terminar programa y salir al DOS
Int 21h ;
END Inicio
END


2.10 MANIPULACIÓN DE LA PILA.




La pila es un grupo de localidades de memoria que se reservan para contar con un espacio de almacenamiento temporal cuando el programa se está ejecutando.
La pila es una estructura de datos del tipo LIFO (Last In First Out), esto quiere decir que el último dato que es introducido en ella, es el primero que saldrá al sacar datos de la pila.
Para la manipulación de la pila ensamblador cuenta con dos instrucciones especificas, las cuales son las siguientes:
Push:
Esta instrucción permite almacenar el contenido del operando dentro de la última posición de la pila.
Ejemplo:
Push ax    El valor contenido en ax es almacenado en el último espacio de la pila.
Pop:
Esta instrucción toma el último dato almacenado en la pila y lo carga al operando.
Ejemplo:
Pop bx       El valor contenido en el último espacio de la pila se almacena en el registro
El siguiente ejemplo muestra como implementar la instrucción XCHG por medio de las instrucciones Push y Pop. Recuerde que la instrucción XCHG intercambia el contenido de sus dos operandos. 
.COMMENT 
Programa: PushPop.ASM
 
Descripción: Este programa demuestra el uso de las instrucciones para el manejo de la pila, implementando la instrucción XCHG con Push y Pop 
MODEL tiny 
.CODE 
Inicio: ;Punto de entrada al programa 
Mov AX,5 ;AX=5 
Mov BX,10 ;BX=10 
Push AX ;Pila=5 
Mov AX,BX ;AX=10 
Pop BX ;BX=5 
Mov AX,4C00h ;Terminar programa y salir al DOS 
Int 21h ; 
END Inicio 
END


2.9 INSTRUCCIONES ARITMÉTICAS


.
Dentro de ensamblador se pueden llevar a cabo las 4 instrucciones aritméticas básicas, cada una de ellas cuenta con su propia función:
Instrucción de Suma ADD:
Suma los operandos que se le dan y guarda el resultado en el primer operando.
Ejemplo
ADD al, bl: Suma los valores guardados en los registros al y bl, almacenando el resultado en al.
Instrucción de Resta SUB:
Resta el primer operando al segundo y almacena el resultado en el primero.
Ejemplo:
SUB al, bl: Resta el valor de AL al de BL y almacena el resultado en AL.
Instrucción de multiplicación MUL:
Multiplica el contenido del acumulador por el operando, a diferencia de los métodos anteriores, solo es necesario indicar el valor por el que se multiplicará, ya que el resultado siempre es almacenado en el registro AX.
Ejemplo:
MUL DX: Multiplica el valor del registro acumulador (AX) por el de DX.
Instrucción de división DIV:
Divide un numero contenido en el acumulador entre el operando fuente, el cociente se guarda en AL o AX y el resto en AH o DX según el operando sea byte o palabra respectivamente. Es necesario que DX o AH sean cero antes de la operación por lo que es necesario utilizar el ajuste de división antes del la instrucción DIV.
Ejemplo:
AAM: Ajuste ASCII para la división.
DIV  bl: Instrucción que divide los valores en ax y bl.

2.7 INCREMENTO Y DECREMENTO.



En ensamblador existen dos instrucciones que cumplen con el propósito de aumentar o reducir el valor contenido dentro de un registro.
INC:
Incrementa en uno el valor contenido dentro del registro que se le dé como parámetro.
INC al: Aumenta en 1 el valor del registro al.
DEC:
Reduce en uno el valor contenido dentro del registro que se le dé como parámetro.
DEC al: Reduce en 1 el valor del registro al.



2.8 CAPTURA DE CADENAS CON FORMATO.



El capturar cadenas con formato permite el movimiento, comparación o búsqueda rápida entre bloques de datos, las instrucciones son las siguientes:
MOVC:
Esta instrucción permite transferir un carácter de una cadena.
MOVW:
Esta instrucción permite transferir una palabra de una cadena.
CMPC:
Este comando es utilizado para comparar un carácter de una cadena.
CMPW:
Esta instrucción es utilizada para comparar una palabra de una cadena.
SCAC:
Esta instrucción permite buscar un carácter de una cadena.
SCAW:
Esta instrucción se utiliza para buscar una palabra de una cadena.
LODC:
Esta instrucción permite cargar un carácter de una cadena.
LODW:
Esta instrucción es utilizada para cargar una palabra de una cadena.
STOC:
Esta instrucción permite guardar un carácter de una cadena.
STOW:
Esta instrucción es utilizada para guardar  una palabra de una cadena.


2.6 CICLOS CONDICIONALES


.
Dentro de la programación existen ocasiones en la que es necesario ejecutar una misma instrucción un cierto número de veces, el cual no siempre es conocido por el programador o puede cambiar durante la ejecución del programa, para lo que existen los ciclos condicionales, los cuales una vez se cumpla la condición que tienen establecida, dejaran de ejecutarse como ciclo y permitirán que el programa continúe con su flujo normal.
En ensamblador no existen de forma predefinida estos ciclos, pero pueden crearse haciendo uso de los saltos incondicionales, generando ciclos que se repetirán hasta que se cumpla la condición definida por el programador.
Ejemplo:
mov al, 0: Asigna el valor cero al registro al.
ciclo: Etiqueta a la que se hará referencia para el ciclo condicional.
INC al: Aumenta en 1 el valor del registro al.
CMP al, bl : Comparación entre el valor almacenado en al y el almacenado en bl.
JL ciclo: Instrucción que indica que el flujo del programa continuara desde la ubicación de la etiqueta ciclo si el valor de al es menor al de bl.

Resultado de imagen para Ciclos condicionales asm


2.5 SALTOS.



Los saltos son instrucciones que permiten al programador cambiar el orden de ejecución del programa según sea necesario, dentro de ensamblador existen dos tipos de salto principales: condicionales e incondicionales.
Saltos Incondicionales:
Los saltos incondicionales se utilizan mediante la instrucción JMP, la cual transfiere el control a la línea especificada después de la palabra JMP, la cual puede ser un valor directo o una etiqueta.
También se puede contar como un salto incondicional la instrucción CALL, la cual llama una procedimiento y al terminarla devuelve el control a la línea siguiente de donde se inicio la llamada a procedimiento, pero eso se ve con más detalle en la sección 3.1.
Ejemplo:
Salto: Etiqueta a la que se hará referencia para el salto incondicional.
JMP Salto: Instrucción que indica que el flujo del programa continuara desde la ubicación de la etiqueta Salto.
Saltos Condicionales:
Los saltos condicionales transfieren el control del programa a la ubicación que se les dé como parámetro si al hacer una comparación se cumple la condición establecida en el salto, los saltos condicionales son los siguientes:
JA (Jump if Above):
Salta cuando el valor es superior, su condición es equivalente al salto JNBE (Jump if Not Below or Equal).
JAE (Jump if Above or Equal):
Salta cuando el valor es superior o igual, su condición es equivalente al salto JNB (Jump if Not Below).
JB (Jump if Below):
Salta cuando el valor es menor, su condición es equivalente al salto JNAE (Jump if Not Above or Equal).
JBE (Jump if Below or Equal):
Salta cuando el valor es menor o igual, su condición es equivalente al salto JNA (Jump if Not Above).
JE (Jump if Equal):
Salta cuando el valor es igual.
JZ (Jump if Zero):
Salta cuando el valor es cero.
JNE (Jump if Not Equal):
Salta cuando el valor no es igual.
JNZ (Jump if Not Zero):
Salta cuando el valor no es cero.
JG (Jump if Greater):
Salta cuando el valor es mayor, su condición es equivalente al salto JNLE (Jump if Not Less or Equal).
JGE (Jump if Greater or Equal):
Salta cuando el valor es mayor o igual, su condición es equivalente al salto JNL (Jump if Not Less).
JL (Jump if Less):
Salta cuando el valor es menor, su condición es equivalente al salto JNGE (Jump if Not Greater or Equal).
JLE (Jump if Less or Equal):
Salta cuando el valor es menor o igual, su condición es equivalente al salto JNG (Jump if Not Greater).
Ejemplo:
Salto:  Etiqueta a la que se hará referencia para el salto condicional.
CMP al, bl: Comparación entre el valor almacenado en al y el almacenado en bl.
JG Salto: Instrucción que indica que el flujo del programa continuara desde la ubicación de la etiqueta Salto si el valor de al es mayor al de bl.


2.4 COMPARACIÓN Y PRUEBA.



La comparación y prueba son instrucciones especiales con las que cuenta el microprocesador, estas son CMP y TEST respectivamente.
Comparación (CMP):
Esta instrucción compara los dos valores que se le den como parámetros y modifica las banderas de signo (SF), de cero (ZF) y de acarreo (CF) según sea necesario.
Ejemplo:
CMP ah,10h: Compara el valor almacenado en el registro ah con el valor 10 hexadecimal.
Prueba (TEST):
Verifica que los valores que se le introduzcan como parámetros sean iguales relizando la operación lógica AND, no almacena ningún resultado pero modifica banderas según sea necesario.

ejemplo:

TEST al, 1: Verifica que el valor almacenado en al sea 1
Resultado de imagen para Comparación y prueba.




2.3 CAPTURA BÁSICA DE CADENAS.




Dentro del lenguaje ensamblador no existe el tipo de dato cadena (string en otros lenguajes), por lo que para utilizarla es necesario tratar a las cadenas como un conjunto de caracteres reservados bajo el nombre de una sola variable.
El lenguaje ensamblador cuenta con instrucciones que por su naturaleza sirven para el manejo de cadenas, estas son:
MOVSB:
Mueve un byte desde una localidad de memoria hasta otra.
MOVSW:
Mueve una palabra desde una localidad de memoria hasta otra.
LODSB:
Carga en la parte baja del registro acumulador (AL) el valor de la localidad de memoria determinada por DS:SI.
LODSW:
Carga en el registro acumulador (AX) el valor de la localidad de memoria determinada por DS:SI.
 Captura




2.2 CICLOS NUMÉRICOS.



Como en cualquier otro lenguaje de programación, hay ocasiones en las que es necesario hacer que el programa no siga una secuencia lineal, sino que repita varias veces una misma instrucción o bloque de instrucciones antes de continuar con el resto del programa, es para esto que se utilizan los ciclos.
Existen 5 tipos de ciclos predefinidos en ensamblador, aunque también se pueden crear ciclos personalizados por medio de instrucciones de salto las cuales se verán en la sección 2.6 de este manual.
Los ciclos predefinidos de ensamblador son los siguientes:
LOOP:
Esta función decrementa el valor del registro contador CX, si el valor contenido en CX es cero ejecuta la siguiente instrucción, en caso contrario transfiere el control a la ubicación definida por la etiqueta utilizada al momento de declarar el ciclo.
Ejemplo:
mov cx,25 :    Número de veces que se repetirá el ciclo, en este caso 25.
ciclo:  Etiqueta que se utilizará como referencia para el ciclo loop.
int 21h: Instrucción contenida dentro del ciclo (puede contener más de una instrucción).
loop:  Ciclo loop que transferirá el control a la línea de la etiqueta ciclo en caso de que CX no sea cero.
LOOPE:
Esta función decrementa el valor del registro contador CX, si el valor contenido en CX es cero y ZF es diferente de uno ejecuta la siguiente instrucción, en caso contrario transfiere el control a la ubicación definida por la etiqueta utilizada al momento de declarar el ciclo.
Ejemplo:
ciclo: Etiqueta que se utilizará como referencia para el ciclo loope.
int 21h: Instrucción contenida dentro del ciclo (puede contener más de una instrucción).
loope: Ciclo loope que transferirá el control a la línea de la etiqueta ciclo en caso de que CX no sea cero y ZF sea igual a uno.
LOOPNE:
Esta función decrementa el valor del registro contador CX, si el valor contenido en CX es cero y ZF es diferente de cero ejecuta la siguiente instrucción, en caso contrario transfiere el control a la ubicación definida por la etiqueta utilizada al momento de declarar el ciclo, esta es la operación contraria a loope.
Ejemplo:
ciclo: Etiqueta que se utilizará como referencia para el ciclo loopne.
int 21h: Instrucción contenida dentro del ciclo (puede contener más de una instrucción).
loopne: Ciclo loopne que transferirá el control a la línea de la etiqueta ciclo en caso de que CX no sea cero y ZF sea igual a cero.
LOOPZ:
Esta función decrementa el valor del registro contador CX, si el valor contenido en CX es cero y ZF es diferente de uno ejecuta la siguiente instrucción, en caso contrario transfiere el control a la ubicación definida por la etiqueta utilizada al momento de declarar el ciclo.
Ejemplo:
ciclo: Etiqueta que se utilizará como referencia para el ciclo loopz.
int 21h: Instrucción contenida dentro del ciclo (puede contener más de una instrucción).
loopz: Ciclo loopz que transferirá el control a la línea de la etiqueta ciclo en caso de que CX no sea cero y ZF sea igual a uno.
LOOPNZ:
Esta función decrementa el valor del registro contador CX, si el valor contenido en CX es cero y ZF es diferente de cero ejecuta la siguiente instrucción, en caso contrario transfiere el control a la ubicación definida por la etiqueta utilizada al momento de declarar el ciclo, esta es la operación contraria a loopz.
Ejemplo:
ciclo: Etiqueta que se utilizará como referencia para el ciclo loopnz.
int 21h: Instrucción contenida dentro del ciclo.
loopnz: Ciclo loopnz que transferirá el control a la línea de la etiqueta ciclo en caso de que CX no sea cero y ZF sea igual a cero.
 Resultado de imagen para ciclos numéricos.