martes, 12 de marzo de 2019

UNIDAD 2

Unidad 2 :Ciclos condicionales

Algunos de los programas que ya hemos visto a lo largo del curso han sido de forma lineas. Tienen una secuencia de linea a linea sin hacer algún salto significativo a alguna parte del código.
Muchas de las veces los programas no son tan sencillos como esta forma lineal de programar, es por eso que se implementan los ciclos y saltos a ciertas partes de un programa.
Este tipo de requisitos implica la transferencia de control a la dirección en donde se encuentre la instrucción que no va de inmediato de la que se este ejecutando. Este tipo de transferencia de control puede ser hacia adelante, para ejecutar pasos nuevos, o hacia atrás, para repetir algún paso.


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.


;Ejemplo del uso de un salto condiconal
JMP A90 ;Indicamos a donde saltara desde esta linea
. . .
A90: MOV AH, 00 ;al encontrar la etiqueta, realizara lo que se encuentra en ella


org    100h

mov    ax, 5          ; asigna un 5 a ax. 
mov    bx, 2          ; asigna un 2 a bx. 

jmp    calc            ; va a 'calc'. 

back:  jmp stop      ; va a 'stop'. 

calc:
add    ax, bx         ; suma bx y ax 
jmp    back           ; va a la etiqueta back

stop:

ret                   ; Detiene el sistema 


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


;Ejemplo del uso de LOOP
.MODEL SMALL
.CODE
ORG 100H
MAIN PROC NEAR
MOV AX,01 ;Iniciación de AX,
MOV BX,01 ;BX y
MOV CX,01 ;CX a 01
MOV CX,10 ;Iniciar 
A20: ;Número de iteraciones 
ADD AX, 01 ;Sumar 01 a AX
ADD BX, AX ;Sumar AX a BX
SHL DX, 1 ;Multiplicar por dos a DX 
LOOP A20 ;Iterar si es diferente de cero
MOV AX, 4C00H ;Salida a DOS 
MAIN ENDP
END MAIN

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.




PROGRAMAS CON CICLOS CONDICIONALES: 

En esta entrada dejare varios ejemplos de programas que utilizan ciclos condicionales en su estructura, para recalcar un poco mas de la investigación que antes ya había documentado en una entrada pasada.

Código 1:

org    100h
include 'emu8086.inc'

mov    al, 25     ; asigna 25 a al 
mov    bl, 10     ; asigna 10 a bl

cmp    al, bl     ; compara al con bl 

je     equal      ; salta si al = bl (zf = 1). 

putc   'n'        ; si llega aqui, entonces bl y al no son iguales 
jmp    stop       ; asi que imprime 'n' y salta a stop 

equal:            ; si llega aqui,
putc   'y'        ; entonces al=bl e imprime y 

stop:

ret               ; llega aqui sin importar nada 



se asignas los valores a los registros


Como los numeros son diferentes, nos impreme la letra n


En caso de modificar y hacer a ambos numeros iguales


                             Nos mandará a la pantalla la letra Y

Código  2:

include 'emu8086.inc'
.model small
.stack
.data
    num1 db 8
    num2 db 8
    msg1 db 'Numeros iguales','$'
    msg2 db 'Numero 1 mayor','$'
    msg3 db 'Numero 2 mayor','$'
    
.code
    main:
    mov ax, @data
    mov ds,ax
    
    mov al,num1
    cmp al,num2
    
    jc Mayor2   ;Brinca si es mayor el numero 2
    jz igual    ;Salta si es igual
    jnz Mayor1  ;Brinca si es mayor el numero 1
    
.exit

igual:
    mov ah,09h
    lea dx ,msg1
    int 21h   
    ;printn 'Los numeros son iguales'
.exit 

Mayor1:
    mov ah,09h
    lea dx, msg2
    int 21h
    ;printn 'El numero 1 es mayor'
.exit

Mayor2:
    mov ah,09h
    lea dx, msg3
    int 21h
    ;print 'El numero 2 es mayor'
.exit
end


En si, lo que realiza este ultimo programa es la comparación de dos números mediante la instrucción cmp, al
momento de compararlos tenemos tres lineas de brincos condicionales; JC, JZ, JNZ.
Cada una dará un salto hacia la etiqueta que se le tiene asignada siempre y cuando cumpla con la condición que tiene
cada una de ellas.

Finalmente, muestro los tres posibles mensajes que puede darte el programa cuando se cumplan las condiciones de las 
instrucciones; Si los numeros son iguales, si el primer numero es mayor que el segundo o si el segundo numero es mayor 
al primer numero.








PROGRAMAS IMPLEMENTANDO LA INSTRUCCIÓN DE LOOP


En esta entrada, veremos diferentes formas de utilizar la instrucción LOOP y sus otras versiones dentro de nuestro emu8086.
Originalmente, loop se utiliza para que un ciclo se realice diferentes veces. Sin embargo,existen otras formas en que loop puede ser implementado.

Código 1:


1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
.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



Código 2: uso de libreria con la librería emu8086




1
2
3
4
5
6
7
8
9
10
11
12
org 100h        
include 'emu8086.inc'
   
  mov cx,10   ;Vueltas que va a dar el programa
   
  comienzo:
  printn 'letrero'
   
 loop comienzo
ret




PROGRAMA DE COMPARACIÓN DE CADENAS. SI SE ENCUENTRA DENTRO  DE LA CADENA A COMPARAR



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 final      ; brinca si es igual
cmp msg[si], al   ;comparar si encuentra la primera letra de la cadena
 jne seguir    ;brica si es diferente
mov di, 1         ;poner en 1 di 
comprobar:
 mov al, msg2[di]
 mov bx, di
 cmp msg[si+bx], al     ;posicion de la letra coincidente + di, comparar con la cadena
 jne seguir             ;si no coincide mandar a seguir 
 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:
   
 mov di,1
 inc si       ;para seguir recorriendo la palabra
loop comienzo   ;bucle principal para recorrer palabra
resultado:
  mov dx, offset msg3    ;copiar msg3 a dx
  mov ah, 9              ;preparar ah con 9 para la interrupcion 21h
  int 21h                ;mostrar contenido en dx
  jmp fin 
   
final:   
lea dx,msg4
mov ah,9
int 21h
fin:
ret  
msg db "zoologico$"
msg2 db "zuo$"
msg4 db "No se encuentra$"
msg3 db "Si se encuentra$"


Comparamos las palabras ZOOLOGICO con ZUO


Comparamos las palabras ZOOLOGICO con ZOO




PROGRAMA CON LOOPZ. VÍDEO

Código 1:
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
     
    ;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


Si bien, al correr el programa es algo confusa su ejecucion.
Ya que se esperaria que se imprima 10 veces la letra si es una S mayuscula(o al menos ese fue mi caso)

Pero no, el programa no saldra de la funcion de input a menos que se le ingrese una letra diferente a la S mayuscula.

Aqui tenemos un ejemplo de ello, si ingresamos una sola letra a en este caso..


El programa al registrar esa letra, termina automáticamente el programa
En cambio, si ingresamos la letra S mayuscula, veremos lo siguiente..
El programa reconoce la letra y nos permite escribir solo 10 veces la letra, ya que esa fue la condición que se dio
En caso de que se revisen las banderas, solo la bandera IF se enciende en todos los casos porque es la que indica si se ignora o procesa una entrada desde teclado.

MULTIPLICACIÓN DE DOS CIFRAS EN ENSAMBLADOR
En esta ocasión, les muestro la explicacion del siguiente programa que hace la multiplicacion de dos numeros de dos cifras.

Código 1:
.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  ;unidad del segundo numero
   mov bl,chr2  ;unidad del primer numero
   mul bl       ;multiplicar
   mov ah,0     ;limpiamos ah0
   aam          ;separamos de hex a dec
   mov ac1,ah   ;decenas del primera multiplicacion
   mov r4,al    ;unidades del primera multiplicacion
             
   mov al,chr4  ;unidades del segundo numero
   mov bl,chr1  ;decentas del primer numero
   mul bl       ;multiplicar
   mov r3,al    ;movemos el resultado de la operacion a r3
   mov bl,ac1   ;movemos el acarreo a bl
   add r3,bl    ;sumamos resultado mas acarreo
   mov ah,00h   ;limpiamos ah por residuos
   mov al,r3    ;movemos el resultado de la suma a al
   aam          ;separamos  de hex a dec
   mov r3,al    ;guardamos unidades en r3
   mov ac1,ah   ;guardamos decenas en ac1
   mov al,chr3    ;al = chr3
   mov bl,chr2    ;bl = chr2
   mul bl         ;AL = chr3*chr2 (BL*AL)
   mov Ah,0h      ;
   AAM            ;ASCII Adjusment
   mov ac,AH      ;ac = AH (Acarreo)
   mov r2,AL      ;r2 = AL       (Unidad del resultado)
   mov al,chr3    ;AL = chr3
   mov bl,chr1    ;BL = chr1
   mul bl         ;AL = chr1*chr3 (BL*AL)
   mov r1,al      ;r1 = AL       (Decena del resultado)
   mov bl,ac      ;BL = Acarreo anterior
   add r1,bl      ;r1 = r1+ac (r1 + Acarreo)
   mov ah,00h     ;
   mov al,r1      ;AL = r1 (Asignaci?n para el ajust)
   AAM            ;ASCII Adjustment
   mov r1,al      ;r1 = AL
   mov ac,ah      ;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      ;movemos el segundo resultado de la primera mult a al
   mov bl,r2      ;movemos primer resultado de la segunda mult a bl
   add al,bl      ;sumamos
   mov ah,00h     ;limpiamos ah
   aam            ;separamos hex a dec
   mov r3,al      ;r3 guarda las decenas del resultado final
   mov r2,ah      ;r2 se utiliza como nuevo acarreo
   
   mov ax,0000h   ;''''
   
   mov al,ac1     ;movemos el acarreo de la primera mult a al
   mov bl,r1      ;movemos segundo resultado de la segunda mult a bl
   add al,r2      ;sumamos el nuevo  acarreo de la suma anterior  a al
   add al,bl      ;sumamos al a bl
   mov ah,00h     ;limpiamos el registro ah
   aam            ;separamos de hex a dec
   mov r1,al      ;r1 guarda las centenas
   mov r2,ah      ;ah se sigue utilizando como acarreo
   
   mov al,r2      ;movemos el acarreo a al
   mov bl,ac      ;movemos ac a bl
   add al,bl      ;sumamos al a bl
   ;aam            ;separamos hex a dec
   mov ac,al      ;mov al a ac como nuestro acarreo final
   
  
   
   ;Mostramos resultado
   mov ah,02h
   mov dl,ac
   add dl,30h
   int 21h        ;Mostramos ac (millar)
   mov ah,02H
   mov dl,r1
   add dl,30h
   int 21h        ;Mostramos r1 (centena)
                  
   
   mov ah,02H
   mov dl,r3
   add dl,30h
   int 21h        ;Mostramos r3 (decena)
   
   mov ah,02H
   mov dl,r4
   add dl,30h
   int 21h        ;unidad
   
.exit
end