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

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

PROGRAMA CON LOOPZ. VÍDEO
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:
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:
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.
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 tinyname "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 comienzoret
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 comienzoret |

PROGRAMA DE COMPARACIÓN DE CADENAS. SI SE ENCUENTRA DENTRO DE LA CADENA A COMPARAR
org 100hinclude 'emu8086.inc'mov si, 0 ;ponemos si en 0 comienzo: mov al, msg2[0] ;copiar la primera letra de la palabra A alcmp msg[si],"$" ;si es el fin de la cadena mandar a final jz final ; brinca si es igualcmp msg[si], al ;comparar si encuentra la primera letra de la cadena jne seguir ;brica si es diferentemov 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 palabraloop comprobar ;bucle para recorrer cadena seguir: mov di,1 inc si ;para seguir recorriendo la palabraloop comienzo ;bucle principal para recorrer palabraresultado: 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,msg4mov ah,9int 21hfin: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.codeinicio:mov cx,10 ;cantidad de veces que repetiramov al,'>' ;caracter inicialLee_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 21hend inicioSi bien, al correr el programa es algo confusa su ejecucion. |
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 .exitend





