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$'
ISTRUZIONI DB 'Premere un tasto: $'
BIN_MESS DB 'Rappresentazione Binaria: $'
TERMINE DB 'Un''altra iterazione? [S/N] $'
MSG_ERRORE DB 'Numero inserito non corretto! $'
INDEX_NUM DW 0
NUMERO DW 16 DUP (?)
NO_INSER DB 0 ;Variabile che mi indica se è stato inserito un valore errato
DSEG ENDS
STACKM SEGMENT PARA STACK 'STACK' ;viene allocata una zona di
DB 64 DUP('12345678') ;memoria per lo Stack: in
STACKM ENDS
ASSUME CS:CSEG,DSSEG,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 LEGGI_CIFRA
CALL STAMPA_BIN
CALL TEST_FINALE
JNZ CICLO_PRINCIPALE
RET ;ritorno al Sistema Operativo
MAIN ENDP
;-----------------------------------------------------------------------;
; Procedura di inizializzazione ;
; ;
;REGISTRI UTILIZZATI: AX, DX, DS ;
;-----------------------------------------------------------------------;
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 ;Sceglie la stringa (DSX)
CALL STAMPA_STRINGA ; e la stampa.
MOV DX,0909h ;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 ISTRUZIONI ;Sceglie la stringa (DSX)
CALL STAMPA_STRINGA ; e la stampa.
RET ;Ritorno alla procedura chiamante
PROMPT ENDP
LEGGI_CIFRA PROC NEAR
MOV BX, 0
NUOVO: mov ah,01h ; Legge il carattere e lo stampa
int 21h
cmp al, '0'
jb ERRORE ;Se inferiore a 0 significa che il carattere non è corretto
cmp al, '9'
jbe CORRETTO ;Se non è minore di 9 verifico che sia conpreso tra A ed F
or al, 00100000b ;Converto in minuscolo, aggingo 32 che è la diff. tra ASCII tre maiuscolo e minuscolo
cmp al,'a'
jb ERRORE ;Minore di A non va bene
cmp al,'f'
jbe CORRETTO
ERRORE: call NON_VALIDO ;Se si è verificato un errore avverto l'utente e poi esco dal ciclo di lettura
JMP ESCI
CORRETTO: MOV [NUMERO+BX],AL ;Se tutto è andato a buon fine inserisco il carattere inserito dall'utente
INC BX ;nella variabile di appoggio, ora controllo se è già la 4 cifra, se non lo
CMP BX, 16 ;continuo a ciclare
JB NUOVO
MOV NO_INSER, 0 ;Non si è verificato alcun errore!!!!
ESCI: ret
LEGGI_CIFRA ENDP
NON_VALIDO PROC NEAR
MOV DX, OFFSET MSG_ERRORE
CALL STAMPA_STRINGA
MOV NO_INSER, 1 ;Indichiamo che si è verificato un errore
RET
NON_VALIDO ENDP
;-----------------------------------------------------------------------;
; Procedura per stampare un numero in formato binario ;
; VARIABILI: il numero e' memorizzato nella locazione CODICE_TASTO ;
; REGISTRI UTILIZZATI: AX, BL, CX, DX ;
;-----------------------------------------------------------------------;
STAMPA_BIN PROC NEAR
MOV DX,OFFSET BIN_MESS ;Sceglie la stringa (DSX)
CALL STAMPA_STRINGA ; e la stampa.
MOV DL,[NUMERO] ; Carica il codice del tasto
MOV DH,40h ;Contatore dei bits
CICLO_BINARIO: XOR AL,AL ;Azzera il registro AL
SHL DL,01h ;Shift Logico a Sinistra
ADC AL,AL ;In AL si pone il CARRY
CALL STAMPA_NUMERO ;Stampa la cifra binaria
DEC DH ;Decrementa il contatore del ciclo
JNZ CICLO_BINARIO ;Se non e' 0 itera un'altra volta
CALL SPOSTA_CURSORE
RET ;Ritorna alla procedura chiamante
STAMPA_BIN ENDP
;-----------------------------------------------------------------------;
; Procedura per determinare se occorre un'altra iterazione ;
; ;
; EGISTRI UTILIZZATI: AX, DX ;
; CODICI DI RITORNO: ;
; Zero flg = 0 -> un'altra iterazione ;
; Zero flag = 1 -> esci dal programma ;
;-----------------------------------------------------------------------;
TEST_FINALE PROC NEAR
MOV DX,OFFSET TERMINE ;Sceglie la stringa (DSX)
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
;************************************************* ***********************;
;* Procedure di basso livello di interfaccia *;
;************************************************* ***********************;
;------------------------------------------------------------------------;
; Procedura per stampare un numero da 0 a 9 ;
; ;
; PARAMETRI: il numero e' memorizzato in AL ;
; VARIABILI: il numero della pagina e' memorizzato in PAGINA ;
; REGISTRI UTILIZZATI: AX, BL ;
;------------------------------------------------------------------------;
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 procedure chiamante
STAMPA_NUMERO ENDP
;------------------------------------------------------------------------;
; Procedura per leggere da tastiera uno dei tasti 'S' o 'N' ;
; ritorna solo dopo aver letto almeno uno dei due tasti ;
; ;
; REGISTRI UTILIZZATI: AX ;
; CODICI DI RITORNO: in AL il codice ASCII letto ;
;------------------------------------------------------------------------;
LETTURA_SN PROC NEAR
NUOVA_LETTURA: MOV AH,R_KEY_CHR_NE ;Servizio DOS 'Read Keyboard Char
INT DOS ;Whitout 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
;-----------------------------------------------------------------------;
; Procedura per spostare il cursore ;
; ;
; PARAMETRI: le coordinate della posizione del cursore sono memoriz- ;
; zate nel registro DXH riga, DL colonna ;
; VARIABILI: il numero della pagina e' memorizzato in PAGINA ;
; REGISTRI UTILIZZATI: AH,BH ;
;-----------------------------------------------------------------------;
SPOSTA_CURSORE PROC NEAR ;Pagina video attiva
MOV BH,PAGINA ;Servizio BIOS 'Set Cursor
MOV AH,SET_CURSOR ; Position'
INT BIOS_VIDEO ;Ritorno alla procedura chiamante
RET
SPOSTA_CURSORE ENDP
;-----------------------------------------------------------------------;
; Procedura per stampare una stringa ;
; ;
;PARAMETRI: l'indirizzo della stringa e' memorizzato in DSX ;
;REGISTRI UTILIZZATI: AX, DX ;
;-----------------------------------------------------------------------;
STAMPA_STRINGA PROC NEAR
MOV AH,PRINT_STRING ;Servizio DOS 'Print String'; la
INT DOS ; stringa e' puntata da DSX.
RET ;Ritorno alla procedura chiamante
STAMPA_STRINGA ENDP
CSEG ENDS
END MAIN
in pratica riesco a fare la conversione in binario ma la fa sul codice esadecimale del carattere ASCII che inserisco e non sul numero esadecimale che metto! Dovrei modificare in qualche modo la funzione LEGGI_CIFRA ma non so come