martes, 5 de mayo de 2020

Ejercicio 4

Determinar si un numero es mayor:
 Código:

.model small
.stack
.data

   mensaje1 db 13,10, 'A>B $'   
   mensaje2 db 13,10, 'A<B $' 
   mensaje3 db 13,10, 'A=B $'


.code

inicio:

   mov ax,@data
   mov ds,ax 
 
   mov ax, 6h
   mov bx, 5h
 
   cmp ax, bx
   jg esMayor
   jl esMenor
   je esIgual
 

esMayor: 
   lea dx, mensaje1
   call imprimir
   jmp finalizar

esMenor:
   lea dx, mensaje2
   call imprimir
   jmp finalizar

esIgual:
   lea dx, mensaje3
   call imprimir
   jmp finalizar
   
   
    imprimir:
         mov ah, 9h
         int 21h   
         ret
      finalizar:
         mov ah, 4ch
         int 21h
       
      end inicio


programa :


lunes, 23 de marzo de 2020

Ejercicio 2 en Ensamblador con Emu8086


Ejercicio 1 en Ensamblador con Emu8086




Emulador EMU8086

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:

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.


Ejemplo de un programa en ensamblador



Definición de emulador


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.

Este tipo de programa se diferencia del simulador, ya que éste trata de modelar de manera precisa el dispositivo original para que el programa a ejecutar funcione correctamente en una plataforma distinta. En cambio, el simulador sólo reproduce el comportamiento original de un sistema determinado.

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 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.

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

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
Las instrucciones del ensamblador

Instrucciones lógicas. Son utilizadas para realizar operaciones lógicas sobre los operandos.
AND
NEG
NOT
OR
TEST
XOR
Instrucciones aritméticas. Se usan para realizar operaciones aritméticas sobre los operandos.
ADC
ADD
DIV
IDIV
MUL
IMUL
SBB
SUB


Instrucción AND
Propósito: Realiza la conjunción de los operandos bit por bit.

Sintaxis:

AND destino, fuente

Con esta instrucción se lleva a cabo la operación "y" lógica de los dos operandos:


Fuente Destino | Destino
--------------------------
1 1 | 1
1 0 | 0
0 1 | 0
0 0 | 0
El resultado de la operación se almacena en el operando destino.

Instrucción NEG
Propósito: Genera el complemento a 2

Sintaxis:

NEG destino

Esta instrucción genera el complemento a 2 del operando destino y lo almacena en este mismo operando. Por ejemplo, si AX guarda el valor de 1234H, entonces:

NEG AX

Nos dejaría almacenado en el registro AX el valor EDCCH.

Instrucción NOT
Propósito: Lleva a cabo la negación bit por bit del operando destino.

Sintaxis:

NOT destino

El resultado se guarda en el mismo operando destino.

Instrucción OR
Propósito: OR inclusivo lógico

Sintaxis:

OR destino, fuente

La instrucción OR lleva a cabo, bit por bit, la disyunción inclusiva lógica de los dos operandos:


Fuente Destino | Destino
--------------------------
1 1 | 1
1 0 | 1
0 1 | 1
0 0 | 0
Instrucción TEST
Propósito: Comparar logicamente los operandos

Sintaxis:

TEST destino, fuente

Realiza una conjunción, bit por bit, de los operandos, pero a diferencia de AND esta instrucción no coloca el resultado en el operando destino, solo tiene efecto sobre el estado de las banderas.

Instrucción XOR
Propósito: OR exclusivo

Sintaxis:

XOR destino, fuente

Su función es efectuar bit por bit la disyunción exclusiva lógica de los dos operandos.


Fuente Destino | Destino
--------------------------
1 1 | 0
0 0 | 1
0 1 | 1
0 0 | 0
Instrucción ADC
Propósito: Adición con acarreo.

Sintaxis:

ADC destino, fuente

Lleva a cabo la suma de dos operandos y suma uno al resultado en caso de que la bandera CF esté activada, esto es, en caso de que exista acarreo.

El resultado se guarda en el operando destino.

Instrucción ADD
Propósito: Adición de los operandos.

Sintaxis:

ADD destino, fuente

Suma los dos operandos y guarda el resultado en el operando destino.

Instrucción DIV
Propósito: División sin signo

Sintaxis:

DIV fuente

El divisor puede ser un byte o palabra y es el operando que se le da a la instrucción.

Si el divisor es de 8 bits se toma como dividendo el registro de 16 bits AX y si el divisor es de 16 bits se tomara como dividendo el registro par DX:AX, tomando como palabra alta DX y como baja AX.

Si el divisor fué un byte el cociente se almacena en el registro AL y el residuo en AH, si fué una palabra el cociente se guarda en AX y el residuo en DX.

Instrucción IDIV
Propósito: División con signo

Sintaxis:

IDIV fuente

Consiste basicamente en lo mismo que la instrucción DIV, solo que esta última realiza la operación con signo.

Para sus resultados utiliza los mismos registros que la instrucción DIV.

Instrucción MUL
Propósito: Multiplicación sin signo

Sintaxis:

MUL fuente

El ensamblador asume que el multiplicando sera del mismo tamaño que el del multiplicador, por lo tanto multiplica el valor almacenado en el registro que se le da como operando por el que se encuentre contenido en AH si el multiplicador es de 8 bits o por AX si el multiplicador es de 16 bits.

Cuando se realiza una multiplicación con valores de 8 bits el resultado se almacena en el registro AX y cuando la multiplicación es con valores de 16 bits el resultado se almacena en el registro par DX:AX.

Instrucción IMUL
Propósito: Multiplicación de dos enteros con signo.

Sintaxis:

IMUL fuente

Este comando hace lo mismo que el anterior, solo que si toma en cuenta los signos de las cantidades que se multiplican.

Los resultados se guardan en los mismos registros que en la instrucción MUL.

Instrucción SBB
Propósito: Substracción con acarreo

Sintaxis:

SBB destino, fuente

Esta instrucción resta los operandos y resta uno al resultado si CF está activada. El operando fuente siempre se resta del destino.

Este tipo de substracción se utiliza cuando se trabaja con cantidades de 32 bits.

Instrucción SUB
Propósito: Substracción

Sintaxis:

SUB destino, fuente

Resta el operando fuente del destino.



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.

martes, 17 de marzo de 2020


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.

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. 

SALTOS CONDICIONALES E INCONDICIONALES.


Hasta este punto los programas que hemos examinado han sido ejecutados en forma lineal, esto es con una instrucción secuencialmente a continuación de otra. Sin embargo, rara vez un programa programable es tan sencillo. La mayoría de los programas constan de varios ciclos en los que una serie de pasos se repite hasta alcanzar un requisito especifico y varias pruebas para determinar que acción se realiza de entre varias posibles.
Requisitos como este implican la transferencia de control a la dirección de una instrucción que no sigue de inmediato de la que se esta ejecutando actualmente. Una transferencia de control puede ser hacia adelante, para ejecutar una serie de pasos nuevos, o hacia atrás, para volver a ejecutar los mismos pasos.
Ciertas instrucciones pueden transferir el control fuera del flujo secuencial normal añadiendo un valor de desplazamiento al IP.
Direcciones Corta, cercana y lejana
Una operación de salto alcanza una dirección corta por medio de un desplazamiento de un byte, limitado a una distancia de -128 a 127 bytes. Una operación de salto alcanza una dirección cercana por medio de un desplazamiento de una palabra, limitado a una distancia de -32, 768 a 32, 767 bytes dentro del mismo segmento. Una dirección lejana puede estar en otro segmento y es alcanzada por medio de una dirección de segmento y un desplazamiento; CALL es la instrucción normal para este propósito.
La tabla siguiente indica las reglas sobre distancias para la operaciones JMP, LOOP y CALL. Hay poca necesidad de memorizar estas reglas, ya que el uso normal de estas instrucciones en rara ocasión causa problemas.




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:

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.
Ejemplos:


Ciclos numéricos en ensamblador

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.