codice:
;Definizione costanti
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'
TITOLO DB 'CORSO di CALCOLATORI ELETTRONICI$'
ISTRUZIONE_1 DB CR,LF,LF,HT,'Digita il primo numero (max 5 cifre): $'
BIN_MESS DB CR,LF,HT,HT,'Rappresentazione Binaria: $'
TERMINE DB CR,LF,LF,HT,'Un''altra iterazione? [S/N]$'
MSG_ERRORE DB CR,LF,LF,HT,'Sono permessi solo caratteri numerici! Pertanto...$'
MSG_EMPTY DB CR,LF,LF,HT,'Non hai scritto nessun numero$'
RIS DB CR,LF,LF,HT,'IL RISULTATO E $'
NUM_1 DB 5 DUP(?)
NUM_B Db 16 DUP (?)
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'
;---------------------------------------------------------------------;
; Corpo principale del programma ;
;---------------------------------------------------------------------;
MAIN PROC FAR
PUSH DS ;Istruzioni da lasciare SEMPRE
MOV AX,00h ; al principio dei programmi!
PUSH AX ;
CALL INIZIALIZZAZIONE
CICLO_PRINCIPALE: CALL PROMPT
CALL ACQUISIZIONE_1
CALL CONVERSIONE
CALL STAMPA_BIN
CALL CONTROLLO
CALL STAMPA_RIS
CALL TEST_FINALE
JNZ CICLO_PRINCIPALE
RET ;Ritorno al Sistema Operativo
MAIN ENDP
INIZIALIZZAZIONE PROC NEAR
MOV AX,DSEG ;Inizializzazione segmento dati
MOV DS,AX ; tramite il registro AX.
MOV AH,SET_VIDEO_MODE ;Servizio BIOS 'Set Video Mode':
MOV AL,MODO_TESTO ; modo testo 80 x 25, colori
INT BIOS_VIDEO ;
MOV DX,0315h ;Imposta riga (DH) e colonna (DL)
CALL SPOSTA_CURSORE ;Muove il cursore nella pos scelta
MOV DX,OFFSET TITOLO
CALL STAMPA_STRINGA ; e la stampa.
MOV DX,0606h ;Imposta riga (DH) e colonna (DL)
CALL SPOSTA_CURSORE ;Muove il cursore nella pos scelta
RET ;Ritorno alla procedura chiamante
INIZIALIZZAZIONE ENDP
;---------------------------------------------------------------------;
; Procedura per stampare il messaggio iniziale ;
; ;
; REGISTRI UTILIZZATI: DX, AH ;
;---------------------------------------------------------------------;
PROMPT PROC NEAR
MOV DX,OFFSET ISTRUZIONE_1
CALL STAMPA_STRINGA ; e la stampa.
RET ;Ritorno alla procedura chiamante
PROMPT ENDP
;------------------------------------------------------------------------;
; Procedura per l'acquisione del primo numero;
;------------------------------------------------------------------------;
ACQUISIZIONE_1 PROC NEAR
INIZIO_1: LEA SI,NUM_1
MOV CL,05d
MOV CH,0
CICLO_1: MOV AH,R_KEY_CHR
INT DOS
CMP AL,CR
JE FINE_1
CMP AL,'9'
JG ERRORE_1
CMP AL,'0'
JL ERRORE_1
MOV CS:[SI],AL
INC SI
LOOP CICLO_1
JMP FINE_1
ERRORE_1: LEA DX,MSG_ERRORE
CALL STAMPA_STRINGA
LEA DX,ISTRUZIONE_1
CALL STAMPA_STRINGA
JMP INIZIO_1
FINE_1: MOV AL,00H
MOV CS:[SI],AL
RET
ACQUISIZIONE_1 ENDP
;-----------------------------------------------------------------;
CONVERSIONE PROC NEAR
LEA SI,NUM_1
PUSH BX
PUSH CX
PUSH BP
PUSH SI
MOV CX,0000H
START: MOV AL,CS:[SI]
CMP AL,00H
JE EMPTY
INC CX
INC SI
JMP START
EMPTY: POP SI
MOV AX,0000H
CMP CX,0000H
JE W1
MOV AX,5
SUB AX,CX
MOV CX,AX
CMP CX,0000H
JE W5
W2: PUSH CX
MOV BX,5
MOV CX,5
W3: MOV AL,CS:[SI+BX-1]
MOV CS:[SI+BX],AL
DEC BX
LOOP W3
MOV AL,'0'
MOV CS:[SI+BX],AL
POP CX
LOOP W2
W5: MOV BP,0000H
MOV CX,5
MOV BX,10000
W4: MOV AL,CS:[SI]
SUB AL,'0'
MOV AH,00H
MUL BX
INC SI
ADD BP,AX
MOV AX,BX
MOV BX,10
DIV BX
MOV BX,AX
LOOP W4
MOV AX,BP
JMP FINE_CONV
W1: LEA DX,MSG_EMPTY
CALL STAMPA_STRINGA
JMP FINE_CONV
FINE_CONV: POP BP
POP CX
POP BX
RET
CONVERSIONE ENDP
;---------------------------------------------------------------;
STAMPA_BIN PROC NEAR
LEA SI,NUM_B
MOV DX,AX
MOV CL,10H
CICLO_BINARIO: XOR AL,AL ;Azzera il registro AL
SHL DX,01h ;Shift Logico a Sinistra
ADC AL,AL ;In AL si pone il CARRY
MOV CS:[SI],AL
INC SI
DEC CL ;Decrementa il contatore del ciclo
JNZ CICLO_BINARIO ;Se non e' 0 itera un'altra volta
RET ;Ritorno alla procedura chiamante
STAMPA_BIN ENDP
CONTROLLO PROC NEAR
MOV BX,0000H
MOV CL,00H
LEA SI,NUM_B
BO_0: MOV AL,CS:[SI]
BO_X: CMP CL,16
JE FINE_CO
BO_Z: CMP AL,0
JE BO_1
INC SI
INC CL
JMP BO_0
BO_1: INC SI
INC CL
CMP CL,16
JE FINE_CO
MOV AL,CS:[SI]
CMP AL,1
JE BO_2
JMP BO_0
BO_2: INC SI
INC CL
CMP CL,16
JE FINE_CO
MOV AL,CS:[SI]
CMP AL,1
JE BO_3
JMP BO_0
BO_3: INC SI
INC CL
MOV AL,CS:[SI]
CMP AL,0
JE CO5
JMP BO_X
CO5: INC BX
CMP CL,16
JE FINE_CO
JMP BO_Z
FINE_CO: RET
CONTROLLO ENDP
STAMPA_RIS PROC NEAR
MOV DX,OFFSET RIS
CALL STAMPA_STRINGA
MOV AX,BX
CMP AX,10000
JC SRW_0
MOV DX,0000H
MOV BX,10000
DIV BX
CALL STAMPA_NUMERO
MOV AX,DX
JMP SRW_1
SRW_0: CMP AX,1000
JC SRB_0
SRW_1: MOV DX,0000H
MOV BX,1000
DIV BX
CALL STAMPA_NUMERO
MOV AX,DX
JMP SRB_1
SRB_0: CMP AX,100
JC SRB_2
SRB_1: MOV BL,100
DIV BL
CALL STAMPA_NUMERO
MOV AL,AH
MOV AH,00H
JMP SRB_3
SRB_2: CMP AX,10
JC SRB_4
SRB_3: MOV BL,10
DIV BL
CALL STAMPA_NUMERO
MOV AL,AH
SRB_4: CALL STAMPA_NUMERO
RET
STAMPA_RIS ENDP
TEST_FINALE PROC NEAR
MOV DX,OFFSET TERMINE
CALL STAMPA_STRINGA ; e la stampa.
CALL LETTURA_SN ;Legge da tastiera senza echo.
CMP AL,'n' ;Modifica il FLAG 'Z'
RET ;Ritorno alla procedura chiamante
TEST_FINALE ENDP
STAMPA_NUMERO PROC NEAR
ADD AL,'0' ;La base da cui partire e' '0'
MOV AH,W_CHR_TTY ;Servizio BIOS 'Write Char in TTY'
INT BIOS_VIDEO
RET ;Ritorno alla procedura chiamante
STAMPA_NUMERO ENDP
LETTURA_SN PROC NEAR
NUOVA_LETTURA: MOV AH,R_KEY_CHR_NE ;Servizio DOS 'Read Keyboard Char
INT DOS ; Without Echo'
OR AL,00100000b ;Converte in minuscolo
CMP AL,'n' ;Se il tasto premuto e' 'N' esce
JZ FINE_LETTURA ; dalla procedura
CMP AL,'s' ;Se non e' 'S', ne legge
JNZ NUOVA_LETTURA ; un altro
FINE_LETTURA: RET ;Ritorno alla procedura chiamante
LETTURA_SN ENDP
SPOSTA_CURSORE PROC NEAR
MOV BH,PAGINA ;Pagina video attiva.
MOV AH,SET_CURSOR ;Servizio BIOS 'Set Cursor
INT BIOS_VIDEO ; Position'
RET ;Ritorno alla procedura chiamante
SPOSTA_CURSORE ENDP
STAMPA_STRINGA PROC NEAR
MOV AH,PRINT_STRING ;Servizio DOS 'Print String'; la
INT DOS
RET ;Ritorno alla procedura chiamante
STAMPA_STRINGA ENDP
CSEG ENDS
END MAIN