Practica numero5
1.
2. ; estamuestrase pone dosnúmerosdesde el usuario,
; entoncesse calculalasuma de estosnúmeros,
; e imprime acabo.
nombre de "calco"
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;; estosMaros se copiande emu8086.inc ;;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
; esta macro imprime unacadenaque se da como unparámetro,ejemplo:
; 'Hola mundo!'PRINTN
; lo mismoque PRINT,peronuevalínease añade automáticamente.
SDAT MACRO PRINTN
LOCAL next_char,s_dcl,impreso,skip_dcl
PUSH AX; almacenarregistros...
SI EMPUJE;
Skip_dcl JMP;omitirdeclaración.
s_dcl DB SDAT0Dh, 0Ah, 0
skip_dcl:
LEA SI,s_dcl
next_char:
MOV AL, CS: [SI]
CMP AL,0
JZimpresa
INCSI
MOV AH, 0Eh; funciónde teletipo.
INT10h
JMP next_char
impresa:
POPSI; re-store registros...
AXPOP;
ENDM
; esta macro imprime uncharen AL y losavances
; la posiciónactual del cursor:
Putc carbón MACRO
AXEMPUJE
MOV AL, char
MOV AH, 0Eh
INT10h
AXPOP
ENDM
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
org 100h
iniciojmp;omitirdatos.
msg1 db 0Dh, 0Ah, 'losnúmerosde entradade estagama: [-32768..32767]', 0Dh, 0Ah
db 0Dh, 0Ah,'Introduce primernúmero:$'
msg2 db 0Dh, 0Ah, 'Introduce segundonúmero:$'
msg3 db 0Dh, 0Ah, 'la sumaes:$'
; declaraciónde variables:
dw num?
Empezar:
; imprimirprimermensaje
dx mov,msg1 desplazamiento
movah, 9
int21h
scan_numllamada
; mantenerprimernúmero:
nummov, cx
; imprimirsegundomensaje
dx mov,msg2 desplazamiento
movah, 9
int21h
scan_numllamada
; añadir números:
añadirnum, cx
jo desbordamiento
; imprimirel resultado:
dx mov,msg3 desplazamiento
movah, 9
int21h
movax, num
llamarprint_num
salidajmp
; procesode error overlow:
overflow:
printn'tenemosdesbordamiento!'
Salida:
; esperara que cualquierpulsaciónde tecla:
movah, 0
int16h
ret; control al sistemaoperativovolver.
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;; estasfuncionesse copiande emu8086.inc;;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
; obtiene el númerode variosdígitosFIRMADOdesde el teclado,
; y almacenael resultadoenel registroCX:
SCAN_NUMPROCCERCA
EMPUJE DX
AXEMPUJE
EMPUJE SI
MOV CX, 0
; restablecerlabandera:
MOV CS: make_minus,0
next_digit:
; obtenercarbóndesde el teclado
; enAL:
MOV AH, 00h
INT16h
; e imprimirlo:
MOV AH, 0Eh
INT10h
; comprobarMENOS:
CMP AL,'-'
JE set_minus
; comprobarteclaENTER:
CMP AL,0Dh; retornode carro?
JNEnot_cr
JMP stop_input
not_cr:
CMP AL,8; 'RETROCESO' presionado?
JNEbackspace_checked
MOV DX, 0; eliminarel últimodígitopor
MOV AX, CX;división:
DIV CS: diez;AX= DX: AX/ 10 (DX-rem).
MOV CX, AX
Putc''; posiciónclara.
Putc8; retrocesode nuevo.
JMP next_digit
backspace_checked:
; permitirque sólolosdígitos:
CMP AL, '0'
JAEok_AE_0
JMP remove_not_digit
ok_AE_0:
CMP AL,'9'
JBE ok_digit
remove_not_digit:
Putc8; retroceso.
Putc''; clara pasada noentrarondígitos.
Putc8; retrocesode nuevo.
Next_digitJMP;esperarparala próximaentrada.
ok_digit:
; CX se multiplicanpor10 (primeravezel resultadoescero)
AXEMPUJE
MOV AX, CX
MUL CS: diez;DX:AX = AX * 10
MOV CX, AX
AXPOP
; comprobarsi el númeroesdemasiadogrande
; (resultadodebe serde 16 bits)
CMP DX,0
JNEtoo_big
; convertirde códigoASCII:
SUB AL, 30h
; añadirAL a CX:
MOV AH, 0
MOV DX, CX; copiade seguridad,encasode que el resultadoserádemasiadogrande.
AÑADIRCX,AX
Too_big2JC; saltarsi el númeroesdemasiadogrande.
JMP next_digit
set_minus:
MOV CS: make_minus,1
JMP next_digit
too_big2:
MOV CX, DX; restaurarel valorbackupedantesde añadir.
MOV DX, 0; DX eracero antesde copia de seguridad!
demasiadogrande:
MOV AX, CX
DIV CS: diez;revertirúltimaDX:AX= AX* 10, que AX= DX: AX/ 10
MOV CX, AX
Putc8; retroceso.
Putc''; claro entraronúltimodígito.
Putc8; retrocesode nuevo.
Next_digitJMP;esperaraEnter / Retroceso.
stop_input:
; comprobarla bandera:
CMP CS: make_minus, 0
JE not_minus
NEG CX
not_minus:
POPSI
AXPOP
POPDX
RET
make_minusDB?; utilizadocomounabandera.
SCAN_NUMENDP
; este procedimientoimprime númeroenAX,
; se utilizaconPRINT_NUM_UNSpara imprimirnúmerosconsigno:
PRINT_NUMPROCCERCA
EMPUJE DX
AXEMPUJE
CMP AX,0
JNZnot_zero
Putc'0'
JMP impresa
not_zero:
; el signode verificaciónde AX,
; hacerabsolutasi es negativo:
CMP AX,0
JNSpositivo
NEG AX
Putc'-'
positivo:
LLAME PRINT_NUM_UNS
impresa:
AXPOP
POPDX
RET
PRINT_NUMENDP
; este procedimientoimprime unsinfirmar
; número enAX (nosólounsolodígito)
; valorespermitidosvande 0 a 65535 (FFFF)
PRINT_NUM_UNS PROCCERCA
AXEMPUJE
PUSH BX
EMPUJE CX
EMPUJE DX
; banderapara evitarlaimpresiónde cerosantesdel número:
MOV CX, 1
; (resultadode "/10000" essiempre menoroigual a 9).
MOV BX, 10.000; 2710h - divisor.
; AXes cero?
CMP AX,0
JZprint_zero
begin_print:
; comprobardivisor(si ceroir a END_PRINT):
CMP BX,0
JZEND_PRINT
; evitarlaimpresiónde cerosantesdel número:
CMP CX,0
JE calc
; si AX <BX continuación,resultadode DIV serácero:
CMP AX,BX
JB salto
Calc:
MOV CX, 0; banderaconjunto.
MOV DX, 0
DIV BX; AX= DX: AX/ BX (DX= resto).
; imprimirúltimodígito
; AH essiempre cero,porloque se ignora
AÑADIRAL,30h; convertirencódigoASCII.
PutcAL
MOV AX, DX;conseguirrestode últimadiv.
saltar:
; calcularBX = BX / 10
AXEMPUJE
MOV DX, 0
MOV AX, BX
DIV CS: diez;AX= DX: AX/ 10 (DX= resto).
MOV BX, AX
AXPOP
JMP begin_print
print_zero:
Putc'0'
END_PRINT:
POPDX
POPCX
POPBX
AXPOP
RET
PRINT_NUM_UNS ENDP
de diezDW 10; utilizadocomomultiplicador/divisorporSCAN_NUMyPRINT_NUM_UNS.
3. PUSH: Guarda unvalor de 16 bitsen lapila
AX= Acumulador
SI:Registroíndice de fuente
LEA: Load Effective Address (Cargadirecciónefectiva)
MOV: Copiael operando2 al operando1
JZ: ShortJumpif Zero(equal). SetbyCMP,SUB, ADD, TEST, AND,OR, XOR instructions. (Salto
corto si cero (igual). PuestoporCMP,SUB, ADD,TEST, AND,OR, XOR instrucciones)
INC:Incremento
POP: Get 16 bitvalue fromthe stack. (Adquiereunvalorde 16 bitsde la pila)
ENDM: Imprime unavariable enALy avanza
JNE: ShortJumpif firstoperandisNot Equal to secondoperand(assetby CMP instruction.
(Saltocorto si el primeroperandonoesigual al Segundo)
DIV:Divsionsinasignar
JAE: ShortJumpif firstoperandisAbove or Equal to secondoperand(assetby CMP
instruction). (Saltocortosi el primeroperandoesmayoro igual al segundooperando)
JBE: Short Jumpif firstoperandisBelow orEqual to secondoperand(assetbyCMP
instruction). (Saltocortosi el primeroperandoesmenoroigual al segundooperando)
NEG: Negate.Makesoperandnegative (Niega.Hace al operandonegativo)
6. Al iniciarel programacada variable se encuentraen0
Al ingresarun numeroincrementaenunoAF
Al tener3 numerosaumentaenunoPF
Al tenerlos5 aumentaen1 PFy SF
Al pedirlasuma aumentaenunoZF y PF
Descripciondel programa:
Este programa esuna calculadoraque suma dosdatos que se encuentrenentre el rangode
-32768 y 32767, Si ambosdatossuperaneste rangose produciráundesbordamientoynonos
dara ningúnresultado,Si losdatosse encuentrandentrodel rangoestablecidodarael
resultadode lasuma yfinalizarael programa.
Recordamosel significadode cadaregistrode 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.
Parityflag(PF) - La banderade paridadse usapara indicarsi el resultado,enunregistro,de
una operaciónmatemáticaesválido.
Adjustflag(AF) - Banderade acarreo auxiliar
Directionflag(DF) - La banderade direccióncontrolalaselecciónde autoincremento(D=0) o
auto decremento(D=1) de losregistros%edi o%esi durante lasoperacionesconcadenasde
caracteres.La banderade direcciónsólose utilizaconlasinstruccionesparael manejode
cadenasde caracteres.
5.quinto ejercicio emu8086

5.quinto ejercicio emu8086

  • 1.
    Practica numero5 1. 2. ;estamuestrase pone dosnúmerosdesde el usuario, ; entoncesse calculalasuma de estosnúmeros, ; e imprime acabo. nombre de "calco" ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;;; estosMaros se copiande emu8086.inc ;;; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ; esta macro imprime unacadenaque se da como unparámetro,ejemplo: ; 'Hola mundo!'PRINTN ; lo mismoque PRINT,peronuevalínease añade automáticamente. SDAT MACRO PRINTN LOCAL next_char,s_dcl,impreso,skip_dcl PUSH AX; almacenarregistros... SI EMPUJE; Skip_dcl JMP;omitirdeclaración. s_dcl DB SDAT0Dh, 0Ah, 0 skip_dcl: LEA SI,s_dcl next_char: MOV AL, CS: [SI] CMP AL,0 JZimpresa
  • 2.
    INCSI MOV AH, 0Eh;funciónde teletipo. INT10h JMP next_char impresa: POPSI; re-store registros... AXPOP; ENDM ; esta macro imprime uncharen AL y losavances ; la posiciónactual del cursor: Putc carbón MACRO AXEMPUJE MOV AL, char MOV AH, 0Eh INT10h AXPOP ENDM ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; org 100h
  • 3.
    iniciojmp;omitirdatos. msg1 db 0Dh,0Ah, 'losnúmerosde entradade estagama: [-32768..32767]', 0Dh, 0Ah db 0Dh, 0Ah,'Introduce primernúmero:$' msg2 db 0Dh, 0Ah, 'Introduce segundonúmero:$' msg3 db 0Dh, 0Ah, 'la sumaes:$' ; declaraciónde variables: dw num? Empezar: ; imprimirprimermensaje dx mov,msg1 desplazamiento movah, 9 int21h scan_numllamada ; mantenerprimernúmero: nummov, cx ; imprimirsegundomensaje dx mov,msg2 desplazamiento movah, 9
  • 4.
    int21h scan_numllamada ; añadir números: añadirnum,cx jo desbordamiento ; imprimirel resultado: dx mov,msg3 desplazamiento movah, 9 int21h movax, num llamarprint_num salidajmp ; procesode error overlow: overflow: printn'tenemosdesbordamiento!' Salida: ; esperara que cualquierpulsaciónde tecla:
  • 5.
    movah, 0 int16h ret; controlal sistemaoperativovolver. ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;;; estasfuncionesse copiande emu8086.inc;;; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ; obtiene el númerode variosdígitosFIRMADOdesde el teclado, ; y almacenael resultadoenel registroCX: SCAN_NUMPROCCERCA EMPUJE DX AXEMPUJE EMPUJE SI MOV CX, 0 ; restablecerlabandera: MOV CS: make_minus,0 next_digit: ; obtenercarbóndesde el teclado ; enAL:
  • 6.
    MOV AH, 00h INT16h ;e imprimirlo: MOV AH, 0Eh INT10h ; comprobarMENOS: CMP AL,'-' JE set_minus ; comprobarteclaENTER: CMP AL,0Dh; retornode carro? JNEnot_cr JMP stop_input not_cr: CMP AL,8; 'RETROCESO' presionado? JNEbackspace_checked MOV DX, 0; eliminarel últimodígitopor MOV AX, CX;división: DIV CS: diez;AX= DX: AX/ 10 (DX-rem). MOV CX, AX Putc''; posiciónclara. Putc8; retrocesode nuevo. JMP next_digit backspace_checked: ; permitirque sólolosdígitos: CMP AL, '0'
  • 7.
    JAEok_AE_0 JMP remove_not_digit ok_AE_0: CMP AL,'9' JBEok_digit remove_not_digit: Putc8; retroceso. Putc''; clara pasada noentrarondígitos. Putc8; retrocesode nuevo. Next_digitJMP;esperarparala próximaentrada. ok_digit: ; CX se multiplicanpor10 (primeravezel resultadoescero) AXEMPUJE MOV AX, CX MUL CS: diez;DX:AX = AX * 10 MOV CX, AX AXPOP ; comprobarsi el númeroesdemasiadogrande ; (resultadodebe serde 16 bits) CMP DX,0 JNEtoo_big ; convertirde códigoASCII: SUB AL, 30h ; añadirAL a CX: MOV AH, 0 MOV DX, CX; copiade seguridad,encasode que el resultadoserádemasiadogrande.
  • 8.
    AÑADIRCX,AX Too_big2JC; saltarsi elnúmeroesdemasiadogrande. JMP next_digit set_minus: MOV CS: make_minus,1 JMP next_digit too_big2: MOV CX, DX; restaurarel valorbackupedantesde añadir. MOV DX, 0; DX eracero antesde copia de seguridad! demasiadogrande: MOV AX, CX DIV CS: diez;revertirúltimaDX:AX= AX* 10, que AX= DX: AX/ 10 MOV CX, AX Putc8; retroceso. Putc''; claro entraronúltimodígito. Putc8; retrocesode nuevo. Next_digitJMP;esperaraEnter / Retroceso. stop_input: ; comprobarla bandera: CMP CS: make_minus, 0 JE not_minus NEG CX not_minus: POPSI AXPOP
  • 9.
    POPDX RET make_minusDB?; utilizadocomounabandera. SCAN_NUMENDP ; esteprocedimientoimprime númeroenAX, ; se utilizaconPRINT_NUM_UNSpara imprimirnúmerosconsigno: PRINT_NUMPROCCERCA EMPUJE DX AXEMPUJE CMP AX,0 JNZnot_zero Putc'0' JMP impresa not_zero: ; el signode verificaciónde AX, ; hacerabsolutasi es negativo: CMP AX,0 JNSpositivo NEG AX Putc'-' positivo:
  • 10.
    LLAME PRINT_NUM_UNS impresa: AXPOP POPDX RET PRINT_NUMENDP ; esteprocedimientoimprime unsinfirmar ; número enAX (nosólounsolodígito) ; valorespermitidosvande 0 a 65535 (FFFF) PRINT_NUM_UNS PROCCERCA AXEMPUJE PUSH BX EMPUJE CX EMPUJE DX ; banderapara evitarlaimpresiónde cerosantesdel número: MOV CX, 1 ; (resultadode "/10000" essiempre menoroigual a 9). MOV BX, 10.000; 2710h - divisor. ; AXes cero? CMP AX,0 JZprint_zero begin_print: ; comprobardivisor(si ceroir a END_PRINT):
  • 11.
    CMP BX,0 JZEND_PRINT ; evitarlaimpresióndecerosantesdel número: CMP CX,0 JE calc ; si AX <BX continuación,resultadode DIV serácero: CMP AX,BX JB salto Calc: MOV CX, 0; banderaconjunto. MOV DX, 0 DIV BX; AX= DX: AX/ BX (DX= resto). ; imprimirúltimodígito ; AH essiempre cero,porloque se ignora AÑADIRAL,30h; convertirencódigoASCII. PutcAL MOV AX, DX;conseguirrestode últimadiv. saltar: ; calcularBX = BX / 10 AXEMPUJE MOV DX, 0 MOV AX, BX DIV CS: diez;AX= DX: AX/ 10 (DX= resto). MOV BX, AX AXPOP
  • 12.
    JMP begin_print print_zero: Putc'0' END_PRINT: POPDX POPCX POPBX AXPOP RET PRINT_NUM_UNS ENDP dediezDW 10; utilizadocomomultiplicador/divisorporSCAN_NUMyPRINT_NUM_UNS. 3. PUSH: Guarda unvalor de 16 bitsen lapila AX= Acumulador SI:Registroíndice de fuente LEA: Load Effective Address (Cargadirecciónefectiva) MOV: Copiael operando2 al operando1 JZ: ShortJumpif Zero(equal). SetbyCMP,SUB, ADD, TEST, AND,OR, XOR instructions. (Salto corto si cero (igual). PuestoporCMP,SUB, ADD,TEST, AND,OR, XOR instrucciones) INC:Incremento POP: Get 16 bitvalue fromthe stack. (Adquiereunvalorde 16 bitsde la pila) ENDM: Imprime unavariable enALy avanza JNE: ShortJumpif firstoperandisNot Equal to secondoperand(assetby CMP instruction. (Saltocorto si el primeroperandonoesigual al Segundo) DIV:Divsionsinasignar JAE: ShortJumpif firstoperandisAbove or Equal to secondoperand(assetby CMP instruction). (Saltocortosi el primeroperandoesmayoro igual al segundooperando) JBE: Short Jumpif firstoperandisBelow orEqual to secondoperand(assetbyCMP instruction). (Saltocortosi el primeroperandoesmenoroigual al segundooperando) NEG: Negate.Makesoperandnegative (Niega.Hace al operandonegativo)
  • 13.
    6. Al iniciarelprogramacada variable se encuentraen0 Al ingresarun numeroincrementaenunoAF
  • 14.
    Al tener3 numerosaumentaenunoPF Altenerlos5 aumentaen1 PFy SF
  • 15.
    Al pedirlasuma aumentaenunoZFy PF Descripciondel programa: Este programa esuna calculadoraque suma dosdatos que se encuentrenentre el rangode -32768 y 32767, Si ambosdatossuperaneste rangose produciráundesbordamientoynonos dara ningúnresultado,Si losdatosse encuentrandentrodel rangoestablecidodarael resultadode lasuma yfinalizarael programa. Recordamosel significadode cadaregistrode 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. Parityflag(PF) - La banderade paridadse usapara indicarsi el resultado,enunregistro,de una operaciónmatemáticaesválido. Adjustflag(AF) - Banderade acarreo auxiliar Directionflag(DF) - La banderade direccióncontrolalaselecciónde autoincremento(D=0) o auto decremento(D=1) de losregistros%edi o%esi durante lasoperacionesconcadenasde caracteres.La banderade direcciónsólose utilizaconlasinstruccionesparael manejode cadenasde caracteres.