codice:
PAGINA EQU 00h
HT EQU 09h
LF EQU 0Ah
CR EQU 0Dh
BIOS_VIDEO EQU 10H
SET_VIDEO_MODE EQU 00h ;in AH
MODO_TESTO EQU 03H ;in AL
SET_CURSOR EQU 02h ;in AH
W_CHR_TTY EQU 0Eh ;in AH
DOS EQU 21H
R_KEY_CHR EQU 01H
PRINT_STRING EQU 09H
R_KEY_CHR_NE EQU 07h
DSEG SEGMENT PARA PUBLIC 'DATA'
NCIFRE EQU 8
ARRAY1 DB NCIFRE DUP(?)
ARRAY2 DB NCIFRE DUP(?)
RIS DB NCIFRE+1 DUP(?),'$'
NUMERO1 DW 00
NUMERO2 DW 00
DSEG ENDS
STACKM SEGMENT PARA STACK 'STACK' ;Viene allocata una zona di
DB 64 DUP('12345678') ; memoria per lo Stack: in
STACKM ENDS ; tutto 64*8 bytes.
ASSUME CS:CSEG,DS:DSEG,SS:STACKM
CSEG SEGMENT PARA PUBLIC 'CODE'
;Procedura per leggere un numero e memorizzarlo in NUMERO1
LETTURA_DATI1 PROC NEAR
XOR CL,CL ;Azzero CL
XOR BX,BX ;Azzero BX
XOR AX,AX ;Azzero AX
MOV SI,0 ;Mi posiziono nella prima locazione dell'array
START1: MOV AH,01H ;Servizio DOS 'Read Keyboard Char'
INT DOS
CMP AL,13 ;Confronto che il numero non sia il tasto "INVIO"
JE FLETTURA ;se sì, salto a FLETTURA
CMP AL, '0' ;Controllo che i caratteri inseriti siano numeri
JB ERRORE
CMP AL, '9' ;e non lettere.
JA ERRORE
MEM1: SUB AL,'0'
MOV BYTE PTR ARRAY1[SI],AL
INC SI ;Incremento l'indice dell'array
INC CL ;Incremento il contatore delle cifre
JMP START1
FLETTURA: MOV ARRAY1[SI+1],'$' ;Inserisco il carattere di fine stringa alla fine
XOR AX,AX ;Azzero i registri
XOR DX,DX
XOR BX,BX
MOV SI, OFFSET ARRAY1
CICLO: MOV AX,[BX+SI]
XOR DX,DX
XOR AH,AH
CMP AX,'$' ;Confronto per verificare se è la fine della stringa
JE FINE ;se sì, salto a FINE
CMP CL, 1 ;Confronto se il contatore di cifre è uguale a 1
JE FINE ;se sì, salto a FINE
ADD AX,[NUMERO1] ;Sommo NUMERO_1 in AX
MOV DX, 10
MUL DX ;Moltiplico NUMERO_1 per 10
DEC CL ;Decremento CL (solo in caso di CL>1)
INC BX ;incremento l'indice dell'array
MOV [NUMERO1],AX ;Sommo il numero moltiplicato in NUMERO_1
JMP CICLO ;Ripeto il ciclo, fino ad avere CL=1
ERRORE: MOV DX,OFFSET MESS_ERR ;Stampa il "messaggio d'errore"
CALL STAMPA_STRINGA
CALL PROMPT_1
XOR CL,CL ;Azzero CL
XOR BX,BX ;Azzero BX
XOR AX,AX ;Azzero AX
MOV SI,0
MOV [NUMERO1],00 ;Azzero NUMERO1
JMP START1
FINE: ADD [NUMERO1],AX ;Sovvrascrivo AX in NUMERO_1
JMP CONTROLLO1 ;Controllo finale
CONTROLLO1: XOR DX,DX
MOV DX, 64000
CMP DX, [NUMERO1] ;Confronto 64000 con NUMERO1
JB ERRORE_1 ;se minore, stampa messaggio d'errore
JMP FINE_FINE
ERRORE_1: MOV DX, OFFSET MEX_ERR
CALL STAMPA_STRINGA ;Stampa "messaggio d'errore" sulle cifre > 64000
CALL PROMPT_1
XOR CL,CL ;Azzero CL
XOR BX,BX ;Azzero BX
XOR AX,AX ;Azzero AX
MOV SI,0
MOV [NUMERO1],00 ;Azzero NUMERO1
JMP START1
FINE_FINE: RET
LETTURA_DATI1 ENDP
;Procedura per leggere un numero e memorizzarlo in NUMERO2
LETTURA_DATI2 PROC NEAR
XOR CL,CL
XOR BX,BX
XOR AX,AX
MOV SI,0
START2: MOV AH,01H ;Servizio DOS 'Read Keyboard Char'
INT DOS
CMP AL,13 ;Confronto che il numero non sia il tasto "INVIO"
JE FLETTURA2
CMP AL, '0' ;Confronto che i caratteri inseriti siano numeri
JB ERRORE2
CMP AL, '9' ;e non lettere.
JA ERRORE2
MEM2: SUB AL,'0'
MOV BYTE PTR ARRAY2[SI],AL
INC SI ;Incremento l'indice dell'array
INC CL ;Incremento il contatore delle cifre
JMP START2
FLETTURA2: MOV ARRAY2[SI+1],'$' ;Inserisco il carattere di fine stringa alla fine
XOR AX,AX
XOR DX,DX
XOR BX,BX
MOV SI, OFFSET ARRAY2
CICLO2: MOV AX,[BX+SI] ;Mi sposto di un posto
XOR AH,AH
XOR DX,DX
CMP AX,'$' ;Confronto per verificare se è la fine della stringa
JE FINE2 ;se sì, salto a FINE2
CMP CL,1 ;Confronto se il contatore delle cifre è uguale a 1
JE FINE2 ;se sì, salto a FINE2
ADD AX,[NUMERO2] ;Sommo NUMERO_2 in AX
MOV DX,10
MUL DX ;Moltiplico NUMERO_2 per 10
DEC CL ;Decremento CL (solo in caso di CL>1)
INC BX ;incremento l'indice dell'array
MOV [NUMERO2],AX ;Sommo il numero moltiplicato in NUMERO_2
JMP CICLO2 ;Ripeto il ciclo, fino ad avere CL=1
ERRORE2: MOV DX,OFFSET MESS_ERR
CALL STAMPA_STRINGA ;Stampa messaggio d'errore
CALL PROMPT_2
XOR CL,CL
XOR BX,BX
XOR AX,AX
MOV SI,0
MOV [NUMERO2],00 ;Azzero NUMERO1
JMP START2
FINE2: ADD [NUMERO2],AX ;Sovrascrivo AX in NUMERO2
JMP CONTROLLO2 ;Controllo finale
CONTROLLO2: XOR DX,DX
MOV DX, 64000
CMP DX, [NUMERO2] ;Confronto 64000 con NUMERO2
JB ERRORE_2 ;stampa messaggio d'errore
JMP FINE_FINE2
ERRORE_2: MOV DX, OFFSET MEX_ERR
CALL STAMPA_STRINGA ;Stampa messaggio d'errore sulle cifre > 64000
CALL PROMPT_2
XOR CL,CL
XOR BX,BX
XOR AX,AX
MOV SI,0
MOV [NUMERO2],00 ;Azzero NUMERO2
JMP START2
FINE_FINE2: RET
LETTURA_DATI2 ENDP
;PROCEDURA PER DETERMINARE LE POTENZE DI 2
POTENZA PROC NEAR
INIZIO: XOR AX, AX ;Azzero i registri
XOR BX, BX
XOR CX, CX
XOR DX, DX
MOV AX, [NUMERO1] ;Sposto NUMERO_1 nel registro AX (16 bit)
MOV BX, [NUMERO2] ;Sposto NUMERO_2 nel registro BX (16 bit)
INC BX ;Incrementando BX, se NUMERO_2 è potenza di 2, viene stampata
CMP AX, BX ;Confronto di ugualianza
JE FINEPOT ;Se i numeri sono uguali, salto a FINEPOT
MOV CX, 2 ;Imposto il divisore
DIVID: DIV CX
CMP DX, 0 ;Confronto il resto con 0
JNE FINEPOT1 ;se non è uguale, salto a FINEPOT1
CMP AX, 0 ;Confronto il risultato con 0
JE FINEPOT1 ;se è uguale, salto a FINEPOT1
CMP AX, 1 ;Confronto il risultato con 1
JA DIVID ;se maggiore, ripeto DIVID
CALL STAMPA_DEC
MOV AL,' ' ;Stampa spazio
MOV AH,W_CHR_TTY ;Servizio BIOS 'Write Char in TTY'
INT BIOS_VIDEO
FINEPOT1: INC NUMERO1 ;Prendo in esame il numero successivo
JMP INIZIO ;Ripeto da INIZIO
FINEPOT: RET
POTENZA ENDP
CSEG ENDS
END MAIN