lunes, 1 de abril de 2019

Programa utilizando LOOPE

Este es un programa que utiliza ciclos condicionales, en este caso LOOPE.

Codigo:

org 100h
.stack 64
.data
.code
inicio:
mov cx,10 ;cantidad de veces que repetira
mov al,'>' ;caracter inicial

Lee_car:
mov ah,0eh ;Funcion para imprimir caracter
int 10h ;llama a la bios

mov ah,00 ;funcion de espera de un caracter del teclado
int 16h ;llama al bios
cmp al,'S' ;compara el caracter con 'S'
loope Lee_car ;si es igual salta a otro

mov ah,0eh ;funcion para imprimir caracter
int 10h ;llamada al bios

;colocar el fin de la linea para que baje una linea y lo imprima
mov ah,0eh ;funcion del bios para imprimir caracter
mov al,10
int 10h ;para servicio de video

;colocar el retorno de carro para ir al inicio
mov al,13
int 10h
;prepara la salida del programa
mov ax,4c00h
int 21h
end inicio

Resultado:

Programa multiplicador de 2 cifras en ensamblador

Este programa lo que hace es multiplicar 2 cifras en ensamblador.

.model small ;Modelo de memoria m?s utilizado
.stack

.data        ;definición de datos(variables), donde se almacenara información
.code
   chr1  db ? ;primer digito
   chr2  db ? ;segundo digito
   chr3  db ? ;multiplo
   chr4  db ?
   r1    db ? ;resultado 1
   r2    db ? ;resultado 2
   r3    db ?
   r4    db ?
   ac    db 0 ;acarreo
   ac1   db 0
.startup
   ;cls
   mov ah,00h     ;Function(Set video mode)
   mov al,03      ;Mode 80x25 8x8 16
   int 10h        ;Interruption Video

   mov ah,01h     ;Function(character read) Guarda en AL
   int 21h        ;Interruption DOS functions
   sub al,30h     ;ajustamos valores
   mov chr1,al    ;[chr1].chr2 * chr3 = ac.r1.r2

   mov ah,01h     ;Function(character read) Guarda en AL
   int 21h        ;Interruption DOS functions
   sub al,30h     ;Ajustamos valores
   mov chr2,al    ;chr1.[chr2] * chr3 = ac.r1.r2

   mov ah,02h     ;Function(character to send to standard output)
   mov dl,'*'     ;Character to show
   int 21h

   mov ah,01h     ;Function(Read character) Guarda en AL
   int 21h        ;Interruption DOS Functions
   sub al,30h     ;Transform(0dec = 30hex)
   mov chr3,al    ;chr1.chr2 * [chr3] = ac.r1.r2
  
   mov ah,01h     ;Function(Read character) Guarda en AL
   int 21h        ;Interruption DOS Functions
   sub al,30h     ;Transform(0dec = 30hex)
   mov chr4,al    ;chr1.chr2 * [chr3] = ac.r1.r2

   mov ah,02h     ;Character to send to standar output
   mov dl,'='     ;
   int 21h        ;Interruption DOS functions

   ;Realizamos operaci?n   
  
   mov al,chr4  ;al=5       ;unidad del segundo numero
   mov bl,chr2  ;bl=5       ;unidad del primer numero
   mul bl       ;bl=25      ;multiplicar
   mov ah,0     ;ah=0       ;limpiamos ah0
   aam          ;ax=02  05  ;separamos de hex a dec
   mov ac1,ah   ;ac1=02     ;decenas del primera multiplicacion
   mov r4,al    ;r4=05      ;unidades del primera multiplicacion
            
   mov al,chr4  ;bl=4       ;unidades del segundo numero
   mov bl,chr1  ;al=5       ;decentas del primer numero
   mul bl       ;al=14h     ;multiplicar
   mov r3,al    ;r3=14h     ;movemos el resultado de la operacion a r3
   mov bl,ac1   ;bl=02      ;movemos el acarreo a bl
   add r3,bl    ;r3=16h     ;sumamos resultado mas acarreo
   mov ah,00h   ;ah=00      ;limpiamos ah por residuos
   mov al,r3    ;al=16h     ;movemos el resultado de la suma a al
   aam          ;ax=02  02  ;separamos  de hex a dec
   mov r3,al    ;r3=02      ;guardamos unidades en r3
   mov ac1,ah   ;ac1=0      ;guardamos decenas en ac1
  
      

   mov al,chr3    ;al=2     ;al = chr3
   mov bl,chr2    ;bl=5     ;bl = chr2
   mul bl         ;al=10    ;AL = chr3*chr2 (BL*AL)
   mov Ah,0h      ;ah=0     
   AAM            ;ax=01 00 ;ASCII Adjusment
   mov ac,AH      ;ac=01    ;ac = AH (Acarreo)
   mov r2,AL      ;r2=0     ;r2 = AL       (Unidad del resultado)

   mov al,chr3    ;al=2     ;AL = chr3
   mov bl,chr1    ;bl=4     ;BL = chr1
   mul bl         ;al=8     ;AL = chr1*chr3 (BL*AL)
   mov r1,al      ;r1=8     ;r1 = AL       (Decena del resultado)
   mov bl,ac      ;bl=01    ;BL = Acarreo anterior
   add r1,bl      ;r1=9;    ;r1 = r1+ac (r1 + Acarreo)
   mov ah,00h     ;ah=00
   mov al,r1      ;al=9     ;AL = r1 (Asignaci?n para el ajust)
   AAM            ;ax=00 09 ;ASCII Adjustment
   mov r1,al      ;r1=09    ;r1 = AL
   mov ac,ah      ;ac=0     ;ac = AH (Acarreo para la Centena del resultado)
  
  
   ;suma final
   ;R4 resulta ser las unidades de mul y no se toma en cuenta ya que se pasa entero
  
  
   mov ax,0000h   ;limpiamos ax
  
   mov al,r3      ;al=02        ;movemos el segundo resultado de la primera mult a al
   mov bl,r2      ;bl=0         ;movemos primer resultado de la segunda mult a bl
   add al,bl      ;al=2         ;sumamos
   mov ah,00h     ;ah=00        ;limpiamos ah
   aam            ;ax=00  02    ;separamos hex a dec
   mov r3,al      ;r3=02        ;r3 guarda las decenas del resultado final
   mov r2,ah      ;r2=0         ;r2 se utiliza como nuevo acarreo
  
   mov ax,0000h   ;''''
  
   mov al,ac1     ;al=02        ;movemos el acarreo de la primera mult a al
   mov bl,r1      ;bl=9         ;movemos segundo resultado de la segunda mult a bl
   add al,r2      ;al=2         ;sumamos el nuevo  acarreo de la suma anterior  a al
   add al,bl      ;al=Bh        ;sumamos al a bl
   mov ah,00h     ;ah=00        ;limpiamos el registro ah
   aam            ;ax=01 01     ;separamos de hex a dec
   mov r1,al      ;r1=01        ;r1 guarda las centenas
   mov r2,ah      ;R2=01        ;ah se sigue utilizando como acarreo
  
   mov al,r2      ;al=01        ;movemos el acarreo a al
   mov bl,ac      ;bl=00        movemos ac a bl
   add al,bl      ;al=01        ;sumamos al a bl
   ;aam            ;separamos hex a dec
   mov ac,al      ;ac=01        mov al a ac como nuestro acarreo final
  
 
  
   ;Mostramos resultado
   mov ah,02h 
   mov dl,ac
   add dl,30h
   int 21h        ;Mostramos ac (millar) ac=1

   mov ah,02H
   mov dl,r1
   add dl,30h
   int 21h        ;Mostramos r1 (centena) r1=1

                 
  
   mov ah,02H
   mov dl,r3                                  
   add dl,30h
   int 21h        ;Mostramos r3 (decena)  r3=2
  
   mov ah,02H
   mov dl,r4
   add dl,30h
   int 21h        ;unidad r4=5
  
.exit
end   

Resultado:

Programa detector de subcadenas

En esta entrada veremos el código de lo que es un detector de subcadenas en Ensamblador.

org 100h
include 'emu8086.inc'
mov si, 0 ;ponemos si en 0

comienzo:
mov al, msg2[0] ;copiar la primera letra de la palabra A al
cmp msg[si],"$" ;si es el fin de la cadena mandar a final
jz noacepta ; brinca si en efecto es el final de la cadena
;si no continuo con las siguientes lineas
cmp msg[si], al ;comparar si encuentra la primera letra de la cadena en msg2
jne seguir ;brica si es diferente
;si no continuo con la ejecucion

mov di, 1 ;poner en 1 di

comprobar:
mov al, msg2[di] ;extraigo el siguiente caracter de msg2
mov bx, di ;igualo bx=di
cmp msg[si+bx], al ;consiguo el caracter ubicado en la posicion si+bx y lo comparo con al (al contiene el caracter de msg2)
jne seguir ;si no coincide mandar a seguir
;si no continuo con las siguientes lineas

inc di ;incrementar di para seguir recorriendo cadena

cmp msg2[di],"$" ;si es el fin de la cadena y el programa llego
jz resultado ;aca quiere decir que la cadena es parte de la palabra


loop comprobar ;bucle para recorrer cadena


seguir:

inc si ;para seguir recorriendo la palabra

loop comienzo ;bucle principal para recorrer palabra

resultado:
print "Si lo contiene"
jmp final ;brinco al final

noacepta:
print "No la contiene"
jmp final ;brinco al final



final:
ret

msg db "tecnologico$"
msg2 db "logi$"

Resultado:

Programas con la instruccion de LOOP



En este apartado veremos las diferentes formas de utilizar la instruccion LOOP


Codigo 1:

.model tiny
name "Bucle"

.data
dato db 10,13 ,'Letrero $'

.code
Inicio:
mov cx,50
comienzo:
mov dx,OFFSET dato
mov ah,09
int 21h
;inc cx
loop comienzo
ret






Codigo 2: LOOP con libreria emu8086

org 100h
include 'emu8086.inc'

mov cx,10 ;Vueltas que va a dar el programa

comienzo:
printn 'letrero'

loop comienzo


ret


Unidad 2: Ciclos condicionales

Etiquetas de instrucciones
Las instrucciones JMP,Jnnn y LOOP requieren de un operador que se refiere a la etiqueta de una instrucciones.


Salto incondicional (JMP)

Una instrucción usada mas comúnmente para la transferencia de control es la instrucción de JMP. Un salto es incondicional, ya que la operación transfiere el control bajo cualquier circunstancia.
Una operación JMP dentro del mismo segmento puede ser corta o cercana. En su primer paso por un programa fuente, el ensamblador genera la longitud de cada una de las instrucciones. Sin embargo, una instrucción JMP puede ser de dos o tres bytes de longitud. Este tipo de operaciones al ir a una etiqueta dentro de -128 a +127 bytes , se considera un salto corto.



Instrucción LOOP 

Esta instrucción requiere de un valor inicial en el registro CX. En cada iteracion, LOOP de forma automática disminuye 1 de CX. Si el valor en el registro CX es cero, el control pasa a la instrucción siguiente; sino es así y CX no es igual a cero, el control pasa a la dirección del operando. La distancia debe ser un salto corto, desde -128 hasta +127 bytes. Para una operación que exceda este limite, el ensamblador envía un mensaje como "salto relativo fuera de rango".


Tabla de las instrucciones LOOP

Instrucciones de salto condicional

El ensamblador permite usar una variedad de instrucciones de salto condicional que transfiere el control dependiendo de las configuraciones en el registro de banderas. Por ejemplo, puede comparar dos campos y después saltar de acuerdo con los valores de las banderas que la comparación establece.


Finalmente, agregare un sitio de consulta en donde viene un gran catalogo de todas las instrucciones condicionales que podemos encontrar en ensamblador y una breve explicación de cada una de ellas y como se utilizan.
Ejemplo de algunas instrucciones condicionales:

  • JE. Salto si es equivalente a lo que se compara
  • JG. Salto si es mas grande a su comparación
  • JGE. Salto si es mas grande o igual a su compacidad.
  • JL. Salgo si es menor a lo que se compara.

Salto condicional con banderas

Tabla de saltos condicionales con parámetros dentro de la sintaxis

Uso de Banderas en ensamblador



Las banderas son aquellas que registran el estado del procesador, normalmente asociado a una comparación o a una instrucción aritmética. Las banderas del procesador 8086 son:

CF: Bandera de acareo.
OF: Bandera de desbordamiento (aritmético).
ZF: Bandera de resultado 0 o comparación igual.
SF: Bandera de resultado o comparación negativa.
PF: Bandera de paridad (número par de bits).
AF: Bandera auxiliar. Indica si hay necesidad de ajuste en las operaciones aritméticas con números
BCD.

Banderas de control:
DF: Bandera de dirección. Controla la dirección de las operaciones con cadenas de caracteres
incrementando o decrementando automáticamente los registros índices (SI y DI)
IF: Bandera de interrupciones. Indica si están permitidas o no las interrupciones de los dispositivos
externos.
TF: Bandera de atrape. Controla la operación de modo paso a paso (usada por el programa DEBUG).

Veamos algunos ejemplos:

Para activar la bandera CF haremos una suma, una suma entre 2 numeros, en este caso 255 + 1, de manera que supere el limite del registro inferior.


Codigo:


.model small

.stack

.data

.code

mov al,255

mov bl,1

add al,bl


.exit




end




La bandera ZF sirve para indicar que el valor del resultado es cero:


Codigo:


.model small

.stack

.data

.code

mov al,2

mov bl,2

sub al,bl


.exit

end







En el caso de SF esta se encedera al obtener un resultado negativo en los registros:


Codigo:


.model small .stack .data .code mov al,1 mov bl,2 sub al,bl .exit end