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 CR,HT,HT,HT,HT,HT,CR,'Inserire 16 cifre esadecimali: $' BIN_MESS DB CR,LF,HT,HT,'Rappresentazione binaria: $' RUN_MESS DB CR,LF,HT,HT,'Run Lenght: $' TERMINE DB CR,LF,LF,HT,'Un''altra iterazione?(s/n) $' PUNTO DB '.$' CODICE_TASTO DB 16 DUP (?) INDEX DW 0 VALORI DB 64 DUP (?) INDEX_1 DW 0 VALORI_1 DB 64 DUP (?) INDEX_0 DW 0 VALORI_0 DB 64 DUP (?) INDEX_RUN DW 0 VALORI_RUN DB 64 DUP (?) BIT1 DB 64 DUP (?) BIT0 DB 64 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 DEL PROGRAMMA PUSH AX ; CALL INIZIALIZZAZIONE CICLO_PRINCIPALE: CALL PROMPT CALL LETTURA_DATI CALL STAMPA_BIN CALL STAMPA_RUN CALL TEST_FINALE JNZ CICLO_PRINCIPALE RET ;RITORNO AL SISTEMA OPERATIVO MAIN ENDP ;---------------------------------------------------------------------------; ; ; ; ;PROCEDURA DI INIZIALIZZAZIONE ; ; ; ;REGISTRI UTILIZZATI AX,DS,DX ; ; ;---------------------------------------------------------------------------; INIZIALIZZAZIONE PROC NEAR MOV AX,DSEG ;INIZIALIZZAZIONE SEGMENTO MOV DS,AX ;DATI TRAMITE REGISTRO AX MOV AH,SET_VIDEO_MODE MOV AL,MODO_TESTO ; 80X25 A COLORI INT BIOS_VIDEO ; MOV DX,0315h ;IMPOSTA RIGA DH, COLONNA DL CALL SPOSTA_CURSORE MOV DX,OFFSET TITOLO ;SCEGLIE LA STRINGA TITOLO CALL STAMPA_STRINGA ;E LA STAMPA MOV DX,0909h ;IMPOSTA RIGA DH E COLONNA DL CALL SPOSTA_CURSORE RET INIZIALIZZAZIONE ENDP ;--------------------------------------------------------------------------; ; PROCEDURA PER STAMPARE IL MESSAGGIO INIZIALE ; ; REGISTRI UTILIZZATI DX,AH ; ;--------------------------------------------------------------------------; PROMPT PROC NEAR MOV DX,OFFSET ISTRUZIONI CALL STAMPA_STRINGA RET PROMPT ENDP ;--------------------------------------------------------------------------; ; PROCEDURA PER STAMPARE UN NUMERO IN BINARIO ; ; REGISTRI UTILIZZATI AX,BL,CX,DX ; ;--------------------------------------------------------------------------; STAMPA_BIN PROC NEAR MOV DX,OFFSET BIN_MESS CALL STAMPA_STRINGA MOV BX,0 NEW: MOV DL,[CODICE_TASTO+BX] ;LEGGE IL CODICE DEL TASTO PUSH BX MOV BX,[INDEX] MOV [VALORI+BX],DL POP BX INC BX INC INDEX MOV DH,00h ;CONTATORE DI BITS SHL DL,01h SHL DL,01h SHL DL,01h SHL DL,01h CICLO_BINARIO: XOR AL,AL SHL DL,01h ADC AL,AL CALL STAMPA_NUMERO INC DH CMP DH,03h JBE CICLO_BINARIO ;SE NON E' ZERO RICLICLA TEST BX,3 JNZ NOZ TEST BX,16 JNZ NOZ MOV DX,OFFSET PUNTO CALL STAMPA_STRINGA NOZ: CMP BX,16 JB NEW RET STAMPA_BIN ENDP ;-------------------------------------------------------------------------; ; PROCEDURA PER STAMPARE IN DECIMALE ; ; REGISTRI UTILIZZATI AX,CX,DX ; ;-------------------------------------------------------------------------; STAMPA_RUN PROC NEAR MOV DX,OFFSET RUN_MESS CALL STAMPA_STRINGA MOV BX,0 NEW2: MOV DL,[CODICE_TASTO+BX] PUSH BX MOV BX,[INDEX_RUN] MOV [VALORI_RUN+BX],DL POP BX INC BX INC INDEX_RUN MOV CX,16 XOR AX,AX CICLO: SAL DL,1 RCL AH,1 ADC AX,0 LOOP CICLO CALL STAMPA_NUMERO CMP BX,16 JB NEW2 RET STAMPA_RUN ENDP ;---------------------------------------------------------------------; ; Procedura per determinare se serve un'altra iterazione ; ; ; ; REGISTRI UTILIZZATI: AX, DX ; ; CODICI DI RITORN0: ; ; Zero flag = 0 -> un'altra iterazione ; ; Zero flag = 1 -> esci dal programma ; ;---------------------------------------------------------------------; TEST_FINALE PROC NEAR MOV DX, OFFSET TERMINE ;sceglie la stringa (DS:DX) 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 ; ; ; ; REGISTRI UTILIZZATI: AX, BL ; ; PARAMETRI: il numero è memorizzato in AL ; ; VARIABILI: il numero della pagina è salvato in PAGINA ; ; ; ;---------------------------------------------------------------------; STAMPA_NUMERO PROC NEAR ADD AL, '0' ;la base da cui partire è '0' MOV AH,W_CHR_TTY ;servizio BIOS 'Write Char in TTY' INT BIOS_VIDEO RET ;ritorno alla procedura chiamante STAMPA_NUMERO ENDP ;-------------------------------------------------------------------------------------; ; Procedura per stampare un numero da 0 a leggere da tastiera uno dei tasti 'S' o 'N ; ; ritorna solo dopo aver letto 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 ;without Echo' OR AL,00100000b ;converte in minuscolo CMP AL,'n' ;se il tasto premuto è 'N' esce JZ FINE_LETTURA ;dalla procedura CMP AL,'s' ;se non è '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 memorizzate nel ; ; registro DX: DH riga, DL colonna ; ; VARIABILI: il numero della pagina è memorizzato in PAGINA ; ; ; ; REGISTRI UTILIZZATI: AH, BH ; ;-------------------------------------------------------------------------------------; 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 ;-------------------------------------------------------------------------------------; ; Procedura per leggere un tasto e memorizzarlo in CODICE_TASTO ; ; ; ; PARAMETRI: il numero è memorizzato in CODICE_TASTO ; ; REGISTRI UTILIZZATI: AX ; ;-------------------------------------------------------------------------------------; LETTURA_DATI PROC NEAR MOV BX,0 NUOVO: MOV AH,R_KEY_CHR ;servizio DOS 'Read keyboard Char' INT DOS ;Memorizza il carattere CMP AL,'9' JBE NUMERO SUB AL,30h CMP AL,25h OR AL, 00100000b JL SWAP SUB AL,27h SWAP: MOV [CODICE_TASTO+BX],AL INC BX CMP BX,16 JB NUOVO RET NUMERO: SUB AL,30h CMP AL,25h JL SWAP LETTURA_DATI ENDP ;-------------------------------------------------------------------------------------; ; Procedura per stampare una stringa ; ; ; ; PARAMETRI: l'indirizzo della stringa è memorizzato in DS:DX ; ; ; ; REGISTRI UTILIZZATI: AX, BX ; ;-------------------------------------------------------------------------------------; STAMPA_STRINGA PROC NEAR MOV AH,PRINT_STRING ;servizio DOS 'print string' INT DOS ;la stringa è puntata da DS:DX RET ;ritorna alla procedura chiamante STAMPA_STRINGA ENDP CSEG ENDS END MAIN