5.quinto ejercicio emu8086

17
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:

Transcript of 5.quinto ejercicio emu8086

Page 1: 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

Page 2: 5.quinto ejercicio emu8086

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

Page 3: 5.quinto ejercicio emu8086

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

Page 4: 5.quinto ejercicio emu8086

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:

Page 5: 5.quinto ejercicio emu8086

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:

Page 6: 5.quinto ejercicio emu8086

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'

Page 7: 5.quinto ejercicio emu8086

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.

Page 8: 5.quinto ejercicio emu8086

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

Page 9: 5.quinto ejercicio emu8086

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:

Page 10: 5.quinto ejercicio emu8086

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):

Page 11: 5.quinto ejercicio emu8086

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

Page 12: 5.quinto ejercicio emu8086

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)

Page 13: 5.quinto ejercicio emu8086

6. Al iniciar el programa cada variable se encuentra en 0

Al ingresar un numero incrementa en uno AF

Page 14: 5.quinto ejercicio emu8086

Al tener 3 numeros aumenta en uno PF

Al tener los 5 aumenta en 1 PF y SF

Page 15: 5.quinto ejercicio emu8086

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.

Page 16: 5.quinto ejercicio emu8086