domingo, 10 de marzo de 2019

Saltos condicionales y ciclos condicionales

Programas con saltos condicionales

JMP – Salto incondicional. No depende de ninguna bandera del registro de banderas para
llevarse a cabo, puede ser de tres tipos:
- corto
- cercano
- lejano
El salto corto ocupa 2 bytes así lo que permite transferir el programa a localidades entre +127 y –
128 bytes desde la localidad donde esta la instrucción.
El salto lejano es una instrucción de 3 bytes así que permite cambiar el flujo hasta de -/+32
Kbytes desde donde se localiza la instrucción.
El salto lejano es una instrucción de 5 bytes permitiendo brincar a cualquier localidad de
memoria dentro de la maquina. En μP 386 y 486 el brinco corto esta entre +/- 2 Gbytes si se
trabaja en el modo protegido y de 4 Gbytes si es lejano.

Saltos condicionales

Las instrucciones de salto condicional prueban las banderas de signo cero o acarreo
o paridad o sobreflujo y si la condición es verdadera se ejecuta la transferencia.

Ejemplos:

En este primer ejemplo establecemos dos valores: 25 y 10 para ser comparados, utilizando el salto condicional "je" que salta si se cumple la condición de que los valores sean iguales .




En este ejemplo se muestra el uso de tres tipos de saltos el "je" que condiciona si los valores son iguales, jc que evalúa los bit d estados, si cf=0, entonces sera mayor el  segundo valor, y para cuando zf=1, sera mayor el primer valor y usamos el salto "jnz".



En este ejemplo se hace una suma, colocamos un valor en ax y bx en este caso sera 3 y 4, salta al procedimiento de cal y ahí hace la suma


Aquí podemos observar como se coloca el 3 en ax y el 4 en cx
Se hace la suma y se coloca el resultado en ax.



Bucles

Las instrucciones de bucle se usan para realizar estructuras repetitivas, y utilizan el registro CX
como contador.
LOOP – Es realmente un decremento de cx y un brinco condicionado, esta instrucción decrementa cx y si este no es igual a cero brinca a la dirección especificada.

LOOPE – Es un loop condicional (similar al “rep”) “repite mientras sea igual”, el ciclo se
mantiene mientras la condición sea igual o cx no sea cero y sale del ciclo si la condición no es
igual o cx es cero.

LOOPNE – Similar al anterior pero ahora el salto se da si la condición no es igual o cx ≠ 0 y si ZF=0.

Ejemplo  usando LOOPNE

En este ejemplo damos un valor a cx de 9, este se ira decrementando cada vez que se repita el ciclo de imprimir el mensaje "letrero"


Ejemplo con LOOP

E un ejemplo parecido al anterior, pero esta vez, el ciclo se repetirá 50 veces


Ejemplo usando jcxz

En este ejemplo se muestra el uso de jcxz el cual hace el salto siempre que cx sea igual a cero, de no ser si el ciclo no se realiza.
como se muestra en la imagen cx tiene un valor de 10 entonces el ciclo solo ocurrirá una vez y se saldrá porque cx no es igual 0.



Comparación de dos cadenas

En este ejemplo tenemos dos cadena a comparar: "tecnologico" y la subcadena "tecno"
si "tecno" es parte de de la cadena entonces se imprimira el mensaje de "Si se encuentra" pero si la subcadena llega a tener algún cambio por ejemplo si ponemos "teno", entonces se mostrara un mensaje de "no se encuentra".

Codigo

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 termina
 
final: 
lea dx,msg4
mov ah,9
int 21h

termina:
ret 

msg db "tecnologico$"
msg2 db "tecno$"
msg4 db "No se encuentra$"
msg3 db "Si se encuentra$"




Uso de LOOPZ

En esta instrucción la condición adicional es ZF = 1.

Este programa lee un carácter ingresado, y si el carácter  es igual a "S" entonces nos volverá a pedir que ingresemos un  carácter, si este nuevo carácter sigue siendo igual a "S" entonces se repite el ciclo así 10 veces ya que es el valor de cx.
Si se ingresa algún carácter diferente, entonces el ciclo termina.
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 al 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

El programa termina por el caracter diferente a "S"

El carácter es aceptado, el ciclo sigue y ZF esta en 1.



PROGRAMA QUE MULTIPLICA DOS NÚMEROS


Código

.model small ;Modelo de memoria mas utilizado
.stack

.data        ;definicion de datos(variables), donde se almacenara informacion
.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 



Programa de multiplicación de dos cifras usando la librería "emu8086.inc"

name "Multiplica dos numeros"
include "emu8086.inc"
org 100h

.model small ;Modelo de memoria mas utilizado
.stack

.data        ;definicion 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
   int 10h        ;Interruption Video
;lea SI, msg1
;CALL   print_string 
printn 'Ingresa los numeros a multiplicar '

   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 operacion 

   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:
    printn " "
    printn " "
    print "Presiona enter para salir... "
    mov ah, 0
    int 16h

ret 

.exit
end 



No hay comentarios:

Publicar un comentario

Unidad 3 -Unidad 4

Unidad 3 Modularizacion Programación modular Los avances en la programación de computadoras han permitido crear hermosas y grandes aplic...