Estados de las Banderas
Carry Flag (CF) - Este indicador se establece en 1 cuando se produce un desbordamiento de acarreo. Por ejemplo cuando se ejecuta el siguiente codigo:
mov al, 255
mov bl, 1
add al, bl
Recordemos que al y bl son registros de 8bits y que por lo tanto, el maximo valor decimal que pueden almacenar es 255
Zero Flag (ZF) - toma el valor 1 cuando el resultado es cero. Cuando el resultado es diferente de 0, entonces el valor de la bandera es 0. Ejemplo:
mov al, 1
mov bl, 1
sub al, bl
Sign Flag (SF) - toma el valor 1 cuando el resultado es negativo. Cuando el resultado es positivo se establece en 0. Ejemplo:
mov al, 1
mov bl, 3
sub al, bl
Overflow Flag (OF) - establece en 1 cuando hay un desbordamiento de signo. Por ejemplo, cuando se agrega hace la operacion 100 + 50 (resultado no está en el rango -128 ... 127)
Funcionamiento de las banderas y la instrucción CMP
La instrucción CMP compara los dos registros, siendo su sintaxis
cmp primero, segundo
Siendo su algoritmo:
primero - segundo.
Las banderas se modifican así:
Si resultado = 0 (primero == segundo):
ZF = 1; CF = 0
Si resultado > 0 (primero > segundo):
ZF = 0; CF = 0
SF = OF
Si resultado < 0 (primero < segundo):
ZF = 0; CF = 1
SF != OF
Ejemplos:
Programas
Programa que realiza una suma:
ORG 100h
CALL Inicializar
CALL SumarAXBX
HLT ;Termina el proceso
Inicializar:
MOV ax,8h
MOV bx,9h
ret
SumarAXBX:
ADD ax,bx
ret
Programa que realiza una resta:
ORG 100h
CALL Inicializar
CALL Restar
HLT ;Termina el proceso
Inicializar:
MOV ax,10
MOV bx,12
ret
Restar:
SUB ax,bx
ret
Programa que realiza una mutiplicación
ORG 100h
CALL Inicializar
CALL Multixbx
HLT ; Termina el proceso
Inicializar:
MOV ax,8
MOV bx,9
ret
Multixbx:
MUL bx
ret
Programa que realiza una división
ORG 100h
CALL Inicializar
CALL Divixbx
HTL ; Termina el proceso
Inicializar:
MOV ax,9
MOV bx,9
ret
Divixbx:
DIV bx
ret
Programa que realiza una suma:
ORG 100h
CALL Inicializar
CALL SumarAXBX
HLT ;Termina el proceso
Inicializar:
MOV ax,8h
MOV bx,9h
ret
SumarAXBX:
ADD ax,bx
ret
Programa que realiza una resta:
ORG 100h
CALL Inicializar
CALL Restar
HLT ;Termina el proceso
Inicializar:
MOV ax,10
MOV bx,12
ret
Restar:
SUB ax,bx
ret
Programa que realiza una mutiplicación
ORG 100h
CALL Inicializar
CALL Multixbx
HLT ; Termina el proceso
Inicializar:
MOV ax,8
MOV bx,9
ret
Multixbx:
MUL bx
ret
Programa que realiza una división
ORG 100h
CALL Inicializar
CALL Divixbx
HTL ; Termina el proceso
Inicializar:
MOV ax,9
MOV bx,9
ret
Divixbx:
DIV bx
ret
Programa que realiza una multiplicacion de 2 digitos por 2 digitos
.model small
.stack
.data ; Aquí se declaran las variables donde se almacenara la información
.stack
.data ; Aquí se declaran las variables donde se almacenara la información
.code
chr1 db ? ; Primer digito de la multiplicacion
chr2 db ? ; Segundo digito de la multiplicacion
chr3 db ? ; Multiplo
chr4 db ?
r1 db ? ; Primer resultado
r2 db ? ; Segundo resultado
r3 db ?
r4 db ?
ac db 0 ; Acarreo
ac1 db 0
.inicio
;cls
MOV ah,00h ; Complemento que se utiliza para poner el modo de video
MOV al,03 ; Modo 80x25 8x8 16
INT 10h ; Interrupcion de video
MOV ah,01h ; Complemento para la interrupcion 21h que se utiliza para leer un caracter del teclado y desplegarlo
INT 21h ; Interrupcion del DOS
SUB al,30h ; Se convierten los valores a decimal
MOV chr1,al ; [chr1].chr2 * chr3 = ac.r1.r2
MOV ah,01h ; Complemento para la interrupcion 21h que se utiliza para leer un caracter del teclado y desplegarlo
INT 21h ; Interrupcion del DOS
SUB al,30h ; Se convierten los valores a decimal
MOV chr2,al ; chr1.[chr2] * chr3 = ac.r1.r2
MOV ah,02h ; Se encarga de posicionar el cursor en pantalla
MOV dl,'*' ; Caracter a mostrar
INT 21h ; Interrupcion del DOS
MOV ah,01h ; Complemento para la interrupcion 21h que se utiliza para leer un caracter del teclado y desplegarlo
INT 21h ; Interrupcion del DOS
SUB al,30h ; Se convierten los valores a decimal
MOV chr3,al ; chr1.chr2 * [chr3] = ac.r1.r2
MOV ah,01h ; Complemento para la interrupcion 21h que se utiliza para leer un caracter del teclado y desplegarlo
INT 21h ; Interrupcion del DOS
SUB al,30h ; Se convierten los valores a decimal
MOV chr4,al ; chr1.chr2 * [chr3] = ac.r1.r2
MOV ah,02h ; Se encarga de posicionar el cursor en pantalla
MOV dl,'=' ; Caracter a mostrar
INT 21h ; Interrupcion del DOS
; A partir de aquí se realiza la operacion
MOV al,chr4 ; Unidad del segundo numero
MOV bl,chr2 ; Unidad del primer numero
MUL bl ; Multiplicacion
MOV ah,0 ; Limpiamos la parte alta del registro AX
AAM ; Separamos de hexadecimal a decimal
MOV ac1,ah ; Decenas de la primer multiplicacion
MOV r4,al ; Unidades de la primer multiplicacion
MOV al,chr4 ; Unidades del segundo numero
MOV bl,chr1 ; Decentas del primer numero
MUL bl ; Multiplicacion
MOV r3,al ; Movemos el resultado de la multiplicacion a nuestra variable r3
MOV bl,ac1 ; Movemos el acarreo a la parte baja de nuestro registro BX
ADD r3,bl ; Sumamos resultado r3 mas el acarreo almacenado previamente en bl
MOV ah,00h ; Limpiamos la parte alta del registro AX
MOV al,r3 ; Movemos el resultado de la suma a la parte baja del registro AX
AAM ; Separamos de hexadecimal a decimal
MOV r3,al ; Guardamos unidades en nuestra variable r3
MOV ac1,ah ; Guardamos las decenas en nuestra variable ac1
MOV al,chr3 ; al = chr3
MOV bl,chr2 ; bl = chr2
MUL bl ; AL = chr3*chr2 (BL*AL)
MOV Ah,0h
AAM ; Separamos de hexadecimal a decimal
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 ; Limpiamos la parte alta del registro AX
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 multiplicacion y no se toma en cuenta ya que se pasa entero
MOV ax,0000h ; Limpiamos el registro AX
MOV al,r3 ; Movemos el segundo resultado de la primera multiplicacion a la parte baja de neustro registro AX
MOV bl,r2 ; Movemos primer resultado de la segunda multiplicacion a la parte baja de nuestro registro BX
ADD al,bl ; Sumamos el registro AL y BL
MOV ah,00h ; Limpiamos el registro AX
AAM ; Separamos de hexadecimal a decimal
MOV r3,al ; r3 guarda las decenas del resultado final
MOV r2,ah ; r2 se utiliza como nuevo acarreo
MOV ax,0000h ; Limpiamos el registro AX
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 hexadecimal a decimal
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
chr1 db ? ; Primer digito de la multiplicacion
chr2 db ? ; Segundo digito de la multiplicacion
chr3 db ? ; Multiplo
chr4 db ?
r1 db ? ; Primer resultado
r2 db ? ; Segundo resultado
r3 db ?
r4 db ?
ac db 0 ; Acarreo
ac1 db 0
.inicio
;cls
MOV ah,00h ; Complemento que se utiliza para poner el modo de video
MOV al,03 ; Modo 80x25 8x8 16
INT 10h ; Interrupcion de video
MOV ah,01h ; Complemento para la interrupcion 21h que se utiliza para leer un caracter del teclado y desplegarlo
INT 21h ; Interrupcion del DOS
SUB al,30h ; Se convierten los valores a decimal
MOV chr1,al ; [chr1].chr2 * chr3 = ac.r1.r2
MOV ah,01h ; Complemento para la interrupcion 21h que se utiliza para leer un caracter del teclado y desplegarlo
INT 21h ; Interrupcion del DOS
SUB al,30h ; Se convierten los valores a decimal
MOV chr2,al ; chr1.[chr2] * chr3 = ac.r1.r2
MOV ah,02h ; Se encarga de posicionar el cursor en pantalla
MOV dl,'*' ; Caracter a mostrar
INT 21h ; Interrupcion del DOS
MOV ah,01h ; Complemento para la interrupcion 21h que se utiliza para leer un caracter del teclado y desplegarlo
INT 21h ; Interrupcion del DOS
SUB al,30h ; Se convierten los valores a decimal
MOV chr3,al ; chr1.chr2 * [chr3] = ac.r1.r2
MOV ah,01h ; Complemento para la interrupcion 21h que se utiliza para leer un caracter del teclado y desplegarlo
INT 21h ; Interrupcion del DOS
SUB al,30h ; Se convierten los valores a decimal
MOV chr4,al ; chr1.chr2 * [chr3] = ac.r1.r2
MOV ah,02h ; Se encarga de posicionar el cursor en pantalla
MOV dl,'=' ; Caracter a mostrar
INT 21h ; Interrupcion del DOS
; A partir de aquí se realiza la operacion
MOV al,chr4 ; Unidad del segundo numero
MOV bl,chr2 ; Unidad del primer numero
MUL bl ; Multiplicacion
MOV ah,0 ; Limpiamos la parte alta del registro AX
AAM ; Separamos de hexadecimal a decimal
MOV ac1,ah ; Decenas de la primer multiplicacion
MOV r4,al ; Unidades de la primer multiplicacion
MOV al,chr4 ; Unidades del segundo numero
MOV bl,chr1 ; Decentas del primer numero
MUL bl ; Multiplicacion
MOV r3,al ; Movemos el resultado de la multiplicacion a nuestra variable r3
MOV bl,ac1 ; Movemos el acarreo a la parte baja de nuestro registro BX
ADD r3,bl ; Sumamos resultado r3 mas el acarreo almacenado previamente en bl
MOV ah,00h ; Limpiamos la parte alta del registro AX
MOV al,r3 ; Movemos el resultado de la suma a la parte baja del registro AX
AAM ; Separamos de hexadecimal a decimal
MOV r3,al ; Guardamos unidades en nuestra variable r3
MOV ac1,ah ; Guardamos las decenas en nuestra variable ac1
MOV al,chr3 ; al = chr3
MOV bl,chr2 ; bl = chr2
MUL bl ; AL = chr3*chr2 (BL*AL)
MOV Ah,0h
AAM ; Separamos de hexadecimal a decimal
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 ; Limpiamos la parte alta del registro AX
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 multiplicacion y no se toma en cuenta ya que se pasa entero
MOV ax,0000h ; Limpiamos el registro AX
MOV al,r3 ; Movemos el segundo resultado de la primera multiplicacion a la parte baja de neustro registro AX
MOV bl,r2 ; Movemos primer resultado de la segunda multiplicacion a la parte baja de nuestro registro BX
ADD al,bl ; Sumamos el registro AL y BL
MOV ah,00h ; Limpiamos el registro AX
AAM ; Separamos de hexadecimal a decimal
MOV r3,al ; r3 guarda las decenas del resultado final
MOV r2,ah ; r2 se utiliza como nuevo acarreo
MOV ax,0000h ; Limpiamos el registro AX
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 hexadecimal a decimal
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
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
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
mov ah,02H
mov dl,r4
add dl,30h
int 21h
;unidad
.exit
end
.exit
end
No hay comentarios.:
Publicar un comentario