5.quinto ejercicio emu8086
-
Upload
sebastian-gonzalez -
Category
Devices & Hardware
-
view
200 -
download
1
Transcript of 5.quinto ejercicio emu8086
Practica numero 5
1.
2. ; esta muestra se pone dos números desde el usuario,
; entonces se calcula la suma de estos números,
; e imprime a cabo.
nombre de "calco"
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;; estos Maros se copian de emu8086.inc ;;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
; esta macro imprime una cadena que se da como un parámetro, ejemplo:
; 'Hola mundo!' PRINTN
; lo mismo que PRINT, pero nueva línea se añade automáticamente.
SDAT MACRO PRINTN
LOCAL next_char, s_dcl, impreso, skip_dcl
PUSH AX; almacenar registros ...
SI EMPUJE;
Skip_dcl JMP; omitir declaración.
s_dcl DB SDAT 0Dh, 0Ah, 0
skip_dcl:
LEA SI, s_dcl
next_char:
MOV AL, CS: [SI]
CMP AL, 0
JZ impresa
INC SI
MOV AH, 0Eh; función de teletipo.
INT 10h
JMP next_char
impresa:
POP SI; re-store registros ...
AX POP;
ENDM
; esta macro imprime un char en AL y los avances
; la posición actual del cursor:
Putc carbón MACRO
AX EMPUJE
MOV AL, char
MOV AH, 0Eh
INT 10h
AX POP
ENDM
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;;;;;
org 100h
inicio jmp; omitir datos.
msg1 db 0Dh, 0Ah, 'los números de entrada de esta gama: [-32768..32767]', 0Dh, 0Ah
db 0Dh, 0Ah, 'Introduce primer número: $'
msg2 db 0Dh, 0Ah, 'Introduce segundo número: $'
msg3 db 0Dh, 0Ah, 'la suma es: $'
; declaración de variables:
dw num?
Empezar:
; imprimir primer mensaje
dx mov, msg1 desplazamiento
mov ah, 9
int 21h
scan_num llamada
; mantener primer número:
num mov, cx
; imprimir segundo mensaje
dx mov, msg2 desplazamiento
mov ah, 9
int 21h
scan_num llamada
; añadir números:
añadir num, cx
jo desbordamiento
; imprimir el resultado:
dx mov, msg3 desplazamiento
mov ah, 9
int 21h
mov ax, num
llamar print_num
salida jmp
; proceso de error overlow:
overflow:
printn 'tenemos desbordamiento!'
Salida:
; esperar a que cualquier pulsación de tecla:
mov ah, 0
int 16h
ret; control al sistema operativo volver.
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;
;;; estas funciones se copian de emu8086.inc ;;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;
; obtiene el número de varios dígitos FIRMADO desde el teclado,
; y almacena el resultado en el registro CX:
SCAN_NUM PROC CERCA
EMPUJE DX
AX EMPUJE
EMPUJE SI
MOV CX, 0
; restablecer la bandera:
MOV CS: make_minus, 0
next_digit:
; obtener carbón desde el teclado
; en AL:
MOV AH, 00h
INT 16h
; e imprimirlo:
MOV AH, 0Eh
INT 10h
; comprobar MENOS:
CMP AL, '-'
JE set_minus
; comprobar tecla ENTER:
CMP AL, 0Dh; retorno de carro?
JNE not_cr
JMP stop_input
not_cr:
CMP AL, 8; 'RETROCESO' presionado?
JNE backspace_checked
MOV DX, 0; eliminar el último dígito por
MOV AX, CX; división:
DIV CS: diez; AX = DX: AX / 10 (DX-rem).
MOV CX, AX
Putc ''; posición clara.
Putc 8; retroceso de nuevo.
JMP next_digit
backspace_checked:
; permitir que sólo los dígitos:
CMP AL, '0'
JAE ok_AE_0
JMP remove_not_digit
ok_AE_0:
CMP AL, '9'
JBE ok_digit
remove_not_digit:
Putc 8; retroceso.
Putc ''; clara pasada no entraron dígitos.
Putc 8; retroceso de nuevo.
Next_digit JMP; esperar para la próxima entrada.
ok_digit:
; CX se multiplican por 10 (primera vez el resultado es cero)
AX EMPUJE
MOV AX, CX
MUL CS: diez; DX: AX = AX * 10
MOV CX, AX
AX POP
; comprobar si el número es demasiado grande
; (resultado debe ser de 16 bits)
CMP DX, 0
JNE too_big
; convertir de código ASCII:
SUB AL, 30h
; añadir AL a CX:
MOV AH, 0
MOV DX, CX; copia de seguridad, en caso de que el resultado será demasiado grande.
AÑADIR CX, AX
Too_big2 JC; saltar si el número es demasiado grande.
JMP next_digit
set_minus:
MOV CS: make_minus, 1
JMP next_digit
too_big2:
MOV CX, DX; restaurar el valor backuped antes de añadir.
MOV DX, 0; DX era cero antes de copia de seguridad!
demasiado grande:
MOV AX, CX
DIV CS: diez; revertir última DX: AX = AX * 10, que AX = DX: AX / 10
MOV CX, AX
Putc 8; retroceso.
Putc ''; claro entraron último dígito.
Putc 8; retroceso de nuevo.
Next_digit JMP; esperar a Enter / Retroceso.
stop_input:
; comprobar la bandera:
CMP CS: make_minus, 0
JE not_minus
NEG CX
not_minus:
POP SI
AX POP
POP DX
RET
make_minus DB? ; utilizado como una bandera.
SCAN_NUM ENDP
; este procedimiento imprime número en AX,
; se utiliza con PRINT_NUM_UNS para imprimir números con signo:
PRINT_NUM PROC CERCA
EMPUJE DX
AX EMPUJE
CMP AX, 0
JNZ not_zero
Putc '0'
JMP impresa
not_zero:
; el signo de verificación de AX,
; hacer absoluta si es negativo:
CMP AX, 0
JNS positivo
NEG AX
Putc '-'
positivo:
LLAME PRINT_NUM_UNS
impresa:
AX POP
POP DX
RET
PRINT_NUM ENDP
; este procedimiento imprime un sin firmar
; número en AX (no sólo un solo dígito)
; valores permitidos van de 0 a 65535 (FFFF)
PRINT_NUM_UNS PROC CERCA
AX EMPUJE
PUSH BX
EMPUJE CX
EMPUJE DX
; bandera para evitar la impresión de ceros antes del número:
MOV CX, 1
; (resultado de "/ 10000" es siempre menor o igual a 9).
MOV BX, 10.000; 2710h - divisor.
; AX es cero?
CMP AX, 0
JZ print_zero
begin_print:
; comprobar divisor (si cero ir a END_PRINT):
CMP BX, 0
JZ END_PRINT
; evitar la impresión de ceros antes del número:
CMP CX, 0
JE calc
; si AX <BX continuación, resultado de DIV será cero:
CMP AX, BX
JB salto
Calc:
MOV CX, 0; bandera conjunto.
MOV DX, 0
DIV BX; AX = DX: AX / BX (DX = resto).
; imprimir último dígito
; AH es siempre cero, por lo que se ignora
AÑADIR AL, 30h; convertir en código ASCII.
Putc AL
MOV AX, DX; conseguir resto de última div.
saltar:
; calcular BX = BX / 10
AX EMPUJE
MOV DX, 0
MOV AX, BX
DIV CS: diez; AX = DX: AX / 10 (DX = resto).
MOV BX, AX
AX POP
JMP begin_print
print_zero:
Putc '0'
END_PRINT:
POP DX
POP CX
POP BX
AX POP
RET
PRINT_NUM_UNS ENDP
de diez DW 10; utilizado como multiplicador / divisor por SCAN_NUM y PRINT_NUM_UNS.
3. PUSH: Guarda un valor de 16 bits en la pila AX= Acumulador SI:Registro índice de fuenteLEA: Load Effective Address (Carga dirección efectiva) MOV: Copia el operando 2 al operando1JZ: Short Jump if Zero (equal). Set by CMP, SUB, ADD, TEST, AND, OR, XOR instructions. (Salto corto si cero (igual). Puesto por CMP, SUB, ADD, TEST, AND, OR, XOR instrucciones)INC: IncrementoPOP: Get 16 bit value from the stack. (Adquiere un valor de 16 bits de la pila)ENDM: Imprime una variable en AL y avanza JNE: Short Jump if first operand is Not Equal to second operand (as set by CMP instruction. (Salto corto si el primer operando no es igual al Segundo)DIV: Divsion sin asignar JAE: Short Jump if first operand is Above or Equal to second operand (as set by CMP instruction). (Salto corto si el primer operando es mayor o igual al segundo operando)JBE: Short Jump if first operand is Below or Equal to second operand (as set by CMP instruction). (Salto corto si el primer operando es menor o igual al segundo operando)NEG: Negate. Makes operand negative (Niega. Hace al operando negativo)
6. Al iniciar el programa cada variable se encuentra en 0
Al ingresar un numero incrementa en uno AF
Al tener 3 numeros aumenta en uno PF
Al tener los 5 aumenta en 1 PF y SF
Al pedir la suma aumenta en uno ZF y PF
Descripcion del programa:
Este programa es una calculadora que suma dos datos que se encuentren entre el rango de -32768 y 32767, Si ambos datos superan este rango se producirá un desbordamiento y no nos dara ningún resultado, Si los datos se encuentran dentro del rango establecido dara el resultado de la suma y finalizara el programa.
Recordamos el significado de cada registro de bandera:
Carry Flag (CF) - Este indicador se establece en 1 cuando se produce un desbordamiento de acarreo.
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.
Sign Flag (SF) - toma el valor 1 cuando el resultado es negativo. Cuando el resultado es positivo se establece en 0.
Overflow Flag (OF) - establece en 1 cuando hay un desbordamiento de signo.
Parity flag (PF) - La bandera de paridad se usa para indicar si el resultado, en un registro, de una operación matemática es válido.
Adjust flag (AF) - Bandera de acarreo auxiliar
Direction flag (DF) - La bandera de dirección controla la selección de autoincremento (D=0) o auto decremento (D=1) de los registros %edi o %esi durante las operaciones con cadenas de caracteres. La bandera de dirección sólo se utiliza con las instrucciones para el manejo de cadenas de caracteres.