PAGE 66,132 TITLE** PROGRAMMA di GESTIONE di programmi ASSEMBLER tipo COM (aprile 2009) SUBTTL** EsA025.ASM - Esercizi PALESTRA ASSEMBLY APPRENDISTI - by ing. G.OBER ;/---------------------------------------------------------------------------\ ;| NOME : EsA025.ASM | ;| AUTORE : Giorgio OBER | ;| VERSIONE : aprile 2009 | ;| DESCRIZIONE : Esercizio nø 0025 | ;| Aspetta la digitazione di una stringa composta da soli| ;| NUMERI, fino ad un massimo di 5 caratteri, e li trasforma in| ;| una DoubleWord esadecimale lasciata DX,AX, il numero a 32bit| ;| corrispondente al valore numerico decimale della stringa. | ;| E' possibile premere per introdurre un numero di| ;| caratteri NUMERICI inferiore al massimo previsto, 5. | ;\---------------------------------------------------------------------------/ ; COSTANTI DEFINITE PER IL PROGRAMMA: Invio EQU 13 ;Codice Ascii del tasto ; MACRO UTILIZZATE DAL PROGRAMMA: include c:\arch-lab\bin\GIOBE.MAC ; LIBRERIA UTILIZZATA DAL PROGRAMMA [opzione WinASM altrimenti non necessaria] includelib c:\arch-lab\bin\GIOBE.LIB ;PROCEDURE ESTERNE UTILIZZATE dal PROGRAMMA [NEAR, dalla LIBRERIA ~GIOBE.LIB~] ;----------------------------------------------------------------------------- EXTRN CambiaCol:NEAR EXTRN SET_cur:NEAR EXTRN VIA_cur:NEAR EXTRN RIP_cur:NEAR EXTRN KEYwait:NEAR EXTRN STAsp:NEAR EXTRN Acapo:NEAR EXTRN BIOScls:NEAR EXTRN BIOchr1:NEAR EXTRN BIObeep:NEAR EXTRN BIOSmsg:NEAR EXTRN Wor2Asc:NEAR EXTRN Wor2Dec:NEAR ; DICHIARAZIONI (VARIABILI) PER I PROGRAMMI ESTERNI: PUBLIC ATTRIB ;Attributo di colore ; DICHIARAZIONI (PROCEDURE) PER I PROGRAMMI ESTERNI: PUBLIC EsA025 ;DEFINIZIONE DEL SEGMENTO DEL CODICE ;----------------------------------------------------------------------------- _prog SEGMENT BYTE PUBLIC 'CODE' ASSUME CS:_prog,DS:_prog ORG 0100H INIZIO: JMP EsA025 ;AREA DESTINATA AI DATI DEL PROGRAMMA ;----------------------------------------------------------------------------- ATTRIB DB 0FH Depo DB "00000",00H Testo01 DB " Premi in sequenza SOLO tasti NUMERICI - Invio per terminare",00H Testo02 DB " Digita il NUMERO (massimo 5 cifre): ",00H Testo03 DB " Il Numero decimale inserito Š ",00H Testo04 DB ", corrispondente a ",00H Testo05 DB "H esadecimale.",00H Testo06 DB " Premi un tasto qualunque per tornare al DOS... ",00H Testo07 DB "; la conversione non Š stata eseguita...",00H ;AREA DESTINATA ALLE PROCEDURE DEL PROGRAMMA ;/---------------------------------------------------------------------------\ ;| PROCEDURA : Dec2Wor.ASM | ;| DESCRIZIONE : Analizza la stringa puntata da CS:SI, contenente rigorosa-| ;| mente al massimo 5 caratteri SOLO Ascii NUMERICI e terminata| ;| con 00H, lasciando in DX,AX il numero a 32bit corrispondente| ;| valore numerico decimale della stringa. | ;| Valori corretti per la stringa puntata da CS:SI sono: | ;| "00000",00H "1",00H "99999",00H "2003",00H | ;| Se la sequenza di caratteri Ascii numerici esprime un numero| ;| inferiore o uguale a "65535", per il risultato basta AX. | ;| Se la stringa Š vuota (cioŠ se contiene solo il terminatore| ;| 00H) la procedura termina immediatamente e lascia in uscita| ;| il valore 00000000H (DX=0000H, AX=0000H) | ;| Se la stringa contiene pi— di 5 caratteri la procedura ter-| ;| mina immediatamente e lascia in uscita il valore FFFF0000H| ;| (DX=FFFFH, AX=0000H), utile per esercitare un eventuale con-| ;| trollo dopo la sua chiamata... | ;\---------------------------------------------------------------------------/ Dec2Wor:PUSH BX PUSH CX PUSH DI PUSH BP PUSH SI ; MOV CX,0000H ; Dec_W0: MOV AL,CS:[SI] ; CMP AL,00H ; Determina in CX l'effettivo numero di caratte- JE Dec_W1 ; ri numerici presenti nella stringa puntata da INC CX ; CS:SI e terminata dal carattere 00H INC SI ; JMP SHORT Dec_W0 ; Dec_W1: POP SI ; MOV AX,0000H ; Se la stringa puntata in ingresso da CS:SI Š CMP CX,0000H ; vuota cioŠ se contiene SOLO il terminatore 00H JE Dec_W8 ; (CX=0) la procedura lascia in uscita AX=0000H MOV DX,0FFFFH ; Se la stringa puntata in ingresso da CS:SI CMP CX,5 ; contiene pi— di 5 caratteri la procedura ter- JG Dec_W8 ; mina immediatamente e lascia in uscita DX=FFFF ; Riporta la stringa dei 5 caratteri Ascii nume- ; rici nella forma ottimale, cioŠ con le cifre ; effettivamente acquisite compattate a destra. MOV AX,5 ; * controlla il numero di cifre presenti nella SUB AX,CX ; | stringa lasciandone il numero in CX (se MOV CX,AX ; 1 sono stati immessi 5 caratteri l'operazione CMP CX,0000H ; | di giustificazione non serve) JE Dec_W4 ; * Dec_W2: PUSH CX ; * MOV BX,5 ; | Sposta CX volte tutti i caratteri della MOV CX,5 ; | stringa di un posto a destra, in modo da ot- Dec_W3: MOV AL,CS:[SI+BX-1]; | timizzarla. Per esempio: MOV CS:[SI+BX],AL ; 2 se la stringa contiene 3 caratteri ("953",T) DEC BX ; | posto per opportunit… T = 00H = terminatore: LOOP Dec_W3 ; | prima dell'acquisizione: 00000T MOV AL,'0' ; | dopo l'acquisizione: 953T0T MOV CS:[SI+BX],AL ; | dopo il 1ø aggiustamento: 0953T0 POP CX ; | dopo il 2ø aggiustamento: 00953T LOOP Dec_W2 ; * Dec_W4: MOV BP,0000H ; Opera la conversione della striga Ascii in MOV DI,0000H ; numero espresso a 32 bit e lasciato in DI,BP MOV CX,5 ; MOV BX,10000 ; * Dec_W5: MOV AL,CS:[SI] ; | Trasforma ciascuna cifra Ascii della stringa SUB AL,'0' ; | in numero e moltiplica quest'ultimo per il MOV AH,00H ; 1 corrispondente moltiplicatore, in sequenza MUL BX ; | 10000, 1000, 100, 10 e 1, lasciando risulta- ; * to in DX,BP (Ricorda: MUL BX = AX*BX =DX,AX) CMP DX,0001H ; * Se la precedente moltiplicazione ha prodotto JNE Dec_W6 ; | riporto (numeri compresi tra 65536 e 99999) INC DI ; * se ne tiene conto per il risultato finale Dec_W6: INC SI ; ADD BP,AX ; JNC Dec_W7 ; * Se la precedente somma ha prodotto riporto INC DI ; | (numeri compresi tra 65536 e 99999) se ne ; * tiene conto per il risultato finale Dec_W7: PUSH DX ; * MOV DX,0000H ; | Prepara il moltiplicatore (di volta in volta MOV AX,BX ; | 10000=2710h, 1000=03e8H, 100=0064h, 10=000ah MOV BX,10 ; 2 e 1) per la successiva moltiplicazione. DIV BX ; | Ricorda: DIV BX = (DX,AX)/BX > quoto in AX MOV BX,AX ; | resto in DX POP DX ; * LOOP Dec_W5 ; MOV DX,DI ; Lascia in uscita in DX,AX il risultato della MOV AX,BP ; conversione di numeri da 0 a 99999 Dec_W8: POP BP POP DI POP CX POP BX RET ;***************************************************************************** ; ---------------------------------------------- EsA025 proc NEAR ; AREA DEDICATA AL MAIN PROGRAM ; ---------------------------------------------- ;----------------------------------------------------------------------------- ; Provvede alla cancellazione del video, CALL BIOScls ; posizionando il cursore alla riga0, colonna0, ; in alto a sinistra CALL VIA_cur ; Rende il cursore invisibile M_msgC Testo01,00,00,0FH; Mette a video il titolo, in posizione r00,c00 ; con colore 0FH (bianco brillante su nero) ; ---------------------------------------------- ; PRIMA FASE : Lettura dei Caratteri da Tastiera ; ---------------------------------------------- M_msgC Testo02,02,00,0FH; Messaggio con la richiesta stringa M_CURSOR 02,38 ; Fissa la posizione di stampa per la stringa M_COLOR 0EH ; Fissa il colore con cui stampare la stringa ; Carica in SI l'indirizzo dell'area di memoria LEA SI,Depo ; in cui salveremo, uno dopo l'altro i caratteri ; che stiamo per leggere dalla tastiera xxx00: CALL KEYwait ; Rimane in attesa della pressione di un tasto ; qualunque (lasciando il suo valore in AL) CMP AL,Invio ; Verifica se il tasto appena premuto Š JE xxx01 ; e in questo caso pone fine all'acquisizione CMP AL,'9' ; Verifica se il carattere letto dal deposito Š JA xxx00 ; un NUMERO; se Š pi— grande di "9" (JA) o pi— CMP AL,'0' ; piccolo di "0" (JB) non ci interessa e si JB xxx00 ; ritorna in attesa di tasti numerici ; Se invece si tratta di un NUMERO salva il co- MOV CS:[SI],AL ; dice appena assunto da tastiera nel deposito INC SI ; ("Depo", puntato da SI) e poi incrementa il ; puntatore per puntare la locazione successiva CALL BIOchr1 ; Pone a video il carattere appena assunto da JMP SHORT xxx00 ; tastiera e torna in attesa di pressione tasti ; xxx01: MOV AL,00H ; Comunque sostituisce il carattere Ascii MOV CS:[SI],AL ; con 00H, con cui termina la stringa acquisita ; ---------------------------------------------- ; SECONDA FASE : Conversione della stringa ; ---------------------------------------------- ; Ricarica il puntatore all'area di memoria in LEA SI,Depo ; cui sono stati salvati, uno dopo l'altro, i ; caratteri appena acquisiti dalla tastiera ; Analizza la stringa puntata da CS:SI, costi- ; tuita rigorosamente da SOLO caretteri Ascii CALL Dec2Wor ; numerici e terminata con il terminatore 00H, ; lasciando in DX,AX il numero a 32 bit corri- ; spondente al valore numerico decimale della ; stringa stessa (DX=FFFFH in caso d'errore) ; ---------------------------------------------- PUSH AX ; TERZA FASE : Stampa dei risultati PUSH DX ; ---------------------------------------------- M_msgC Testo03,05,00,0FH; " Il Numero decimale inserito Š " M_COLOR 0EH ; M_msgN Depo ; <<< stringa acquisita >>>> ;----------------------------------------------- CMP DX,0FFFFH ; JNE xxx02 ; M_COLOR 0FH ; M_msgN Testo07 ; "; la conversione non Š stata eseguita..." JMP SHORT xxx03 ; ;----------------------------------------------- xxx02: M_COLOR 0FH ; M_msgN Testo04 ; ", corrispondente a " M_COLOR 0EH ; POP AX ; CALL WOR2ASC ; Parte alta (DX) del risultato POP AX ; CALL WOR2ASC ; Parte bassa (AX) del risultato M_COLOR 0FH ; M_msgN Testo05 ; "H esadecimale." ;----------------------------------------------- xxx03:M_msgC Testo06,24,01,0FH; Mette a video la frase di commiato CALL KEYwait ; _OUT: PUSH AX ; Torna al DOS con la memoria liberata e con la CALL RIP_cur ; chiusura di tutti i file; cede il controllo MOV DH,23 ; al processo padre (generalmente COMMAND.COM); MOV DL,0 ; il valore posto eventualmente in AL prima di CALL SET_cur ; uscire pu• essere testato in uscita con la POP AX ; funzione 4DH o mediante la lettura della MOV AH,4CH ; variabile DOS "ERRORLEVEL" INT 21H ; EsA025 ENDP ; Chiusura della Procedura "Main Program" _prog ENDS ; Chiusura del Segmento di CODICE END INIZIO ; Indirizzo dell'ultima istruzione da compilare