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 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 vecesEjemplo 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 100hinclude '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