PAGE 66,132 TITLE** PROGRAMMA di GESTIONE di programmi ASSEMBLER tipo COM (aprile 2009) SUBTTL** EsA029.ASM - Esercizi PALESTRA ASSEMBLY APPRENDISTI - by ing. G.OBER ;/---------------------------------------------------------------------------\ ;| NOME : EsA029.ASM | ;| AUTORE : Giorgio OBER | ;| VERSIONE : aprile 2009 | ;| DESCRIZIONE : Esercizio n๘ 0029 | ;| Esegue la DIFFERENZA di due numeri decimali a due cifre. | ;| **** VERSIONE OTTIMIZZATA con MACRO dedicate ************* | ;\---------------------------------------------------------------------------/ ; COSTANTI DEFINITE PER IL PROGRAMMA: Invio EQU 13 ;Codice Ascii del tasto ; MACRO UTILIZZATE DAL PROGRAMMA: include c:\arch-lab\bin\GIOBE.MAC ; Organizza la stampa a livello BIOS di un ; carattere passato dal parametro "Carattere", M_Chr_ MACRO Carattere,Colore; nella posizione di stampa corrente e con il M_COLOR Colore ; Colore specificato dal parametro "Colore". MOV AL,Carattere ; Rispetto alla MACRO "M_Chr", gi… disponibile CALL Biochr1 ; nella libreria GIOBE.MAC, non dispone dunque ENDM ; dei parametri "Riga","Colonna" cioŠ non ; consente di fissare la posizione di stampa ; (per altro poco utile nel nostro esempio...) M_BytDec MACRO Dato,Colore ; Organizza la stampa del valore DECIMALE M_COLOR Colore ; del dato a 8 bit (byte) passato dal parametro MOV AL,Dato ; "Dato", nella posizione di stampa corrente e CALL Byt2Dec ; con il colore specificato dal parametro ENDM ; "Colore" M_BytAsc MACRO Dato,Colore ; Organizza la stampa del valore ESADECIMALE M_COLOR Colore ; del dato a 8 bit (byte) passato dal parametro MOV AL,Dato ; "Dato", nella posizione di stampa corrente e CALL Byt2Asc ; con il colore specificato dal parametro ENDM ; "Colore" ; 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 Byt2Dec:NEAR EXTRN Byt2Asc:NEAR EXTRN Dec2Byt:NEAR ; DICHIARAZIONI (VARIABILI) PER I PROGRAMMI ESTERNI: PUBLIC ATTRIB ;Attributo di colore ; DICHIARAZIONI (PROCEDURE) PER I PROGRAMMI ESTERNI: PUBLIC EsA029 ;DEFINIZIONE DEL SEGMENTO DEL CODICE ;----------------------------------------------------------------------------- _prog SEGMENT BYTE PUBLIC 'CODE' ASSUME CS:_prog,DS:_prog ORG 0100H INIZIO: JMP EsA029 ;AREA DESTINATA AI DATI DEL PROGRAMMA ATTRIB DB 0FH Depo1 DB "00",00H Depo2 DB "00",00H Testo01 DB " Differenza di 2 Numeri DECIMALI a 2 cifre ",00H Testo02 DB " Digita il minuendo (massimo 2 cifre, da 0 a 99): ",00H Testo03 DB " Digita il sottraendo (massimo 2 cifre, da 0 a 99): ",00H Testo04 DB " Non posso eseguire.... " DB "Uno o entrambi gli operandi sono fuori range.",00H Testo05 DB " La Differenza dei numeri acquisiti Š: ",00H Testo06 DB " (esadecimale: ",00H Testo07 DB " Premi un tasto qualunque per tornare al DOS... ",00H ;AREA DESTINATA ALLE PROCEDURE DEL PROGRAMMA ;/---------------------------------------------------------------------------\ ;| PROCEDURA : In_dato | ;| DESCRIZIONE : Aspetta caratteri ASCII esclusivamente NUMERICI DECIMALI e | ;| li salva nelle locazioni puntate in ingresso da SI | ;\---------------------------------------------------------------------------/ In_dato: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 In_da1 ; e in questo caso pone fine all'acquisizione CMP AL,'9' ; Verifica se il carattere letto dal deposito Š JA In_dato ; un NUMERO; se Š pi— grande di "9" (JA) o pi— CMP AL,'0' ; piccolo di "0" (JB) non ci interessa e si JB In_dato ; 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 In_dato ; tastiera e torna in attesa di pressione tasti ; In_da1: MOV AL,00H ; Comunque sostituisce il carattere Ascii MOV CS:[SI],AL ; con 00H, con cui termina la stringa acquisita RET ;/---------------------------------------------------------------------------\ ;| PROCEDURA : Diff1 | ;| DESCRIZIONE : Esegue l'operazione di DIFFERENZA e organizza la proposta| ;| dei risultati in notazione DECIMALE | ;\---------------------------------------------------------------------------/ Diff1:M_msgC Testo05,07,02,0FH; M_BytDec BL,0EH ; Proposto il messaggio consuntivo si stampano M_Chr_ '-',0FH ; in sequenza i due operandi e il risultato M_BytDec BH,0EH ; in notazione DECIMALE M_Chr_ '=',0FH ; PUSH BX ; \--------------------------------------------- CMP BL,BH ; | Controllo sugli operandi JGE Dif1_ ; | MOV AL,BL ; | MOV BL,BH ; | Scambia gli operandi se il sottrendo Š MOV BH,AL ; | maggiore del minuendo M_Chr_ '-',0FH ; /--------------------------------------------- Dif1_: SUB BL,BH ; M_BytDec BL,0EH ; POP BX ; RET ; ;/---------------------------------------------------------------------------\ ;| PROCEDURA : Diff2 | ;| DESCRIZIONE : Esegue l'operazione di DIFFERENZA e organizza la proposta| ;| dei risultati in notazione ESADECIMALE | ;\---------------------------------------------------------------------------/ Diff2: M_COLOR 0FH ; M_msgN Testo06 ; Proposto il messaggio consuntivo si stampano M_BytAsc BL,0EH ; in sequenza i due operandi e il risultato M_Chr_ 'H',06H ; in notazione ESADECIMALE M_Chr_ '-',0FH ; M_BytAsc BH,0EH ; M_Chr_ 'H',06H ; M_Chr_ '=',0FH ; CMP BL,BH ; \--------------------------------------------- JGE Dif2_ ; | Controllo sugli operandi MOV AL,BL ; | MOV BL,BH ; | Scambia gli operandi se il sottrendo Š MOV BH,AL ; | maggiore del minuendo M_Chr_ '-',0FH ; /--------------------------------------------- Dif2_: SUB BL,BH ; M_BytAsc BL,0EH ; M_Chr_ 'H',06H ; M_Chr_ ')',0FH ; RET ; ;***************************************************************************** ; ---------------------------------------------- EsA029 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,02,0FH; Mette a video il titolo, in posizione r00,c00 ; con colore 0FH (bianco brillante su nero) M_msgC Testo02,03,02,0FH; ---------------------------------------------- M_CURSOR 03,55 ; PRIMA FASE : Acquisizione degli operandi M_COLOR 0EH ; ---------------------------------------------- LEA SI,Depo1 ; CALL In_dato ; ; Gestione dei 2 operandi, costituiti esclusiva- M_msgC Testo03,04,02,0FH; mente da 2 caratteri Ascii NUMERICI DECIMALI; M_CURSOR 04,55 ; si propone il messaggio di richiesta, si fissa M_COLOR 0EH ; la posizione di stampa e il colore, si defini- LEA SI,Depo2 ; sce la variabile di deposito e si assumono i CALL In_dato ; 2 caratteri da tastiera (per entrambi) LEA SI,Depo1 ; ---------------------------------------------- CALL Dec2Byt ; SECONDA FASE : Conversione degli operandi CMP AL,0FFH ; ---------------------------------------------- JE xxx00 ; Per entrambi la stringa puntata da CS:SI MOV BL,AL ; costituita da 2 caratteri Ascii numerici e ; terminata con il terminatore 00H, Š convertita LEA SI,Depo2 ; nel corrispondente valore esadecimale a 8 bit, CALL Dec2Byt ; lasciato in AL e copiato in BL (1๘ operando) e CMP AL,0FFH ; in BH (2๘ operando); in caso di Operando fuori JE xxx00 ; range AL Š lasciato a FFH, per consentire la MOV BH,AL ; gestione dell'errore (operazione non eseguita) CALL Diff1 ; ---------------------------------------------- CALL Diff2 ; TERZA FASE: Esegue DIFFERENZA e da Risultati JMP SHORT xxx01 ; ---------------------------------------------- xxx00:M_msgC Testo04,07,02,0FH; "..l'operazione non Š stata eseguita..." xxx01:M_msgC Testo07,24,02,0FH; 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 ; EsA029 ENDP ; Chiusura della Procedura "Main Program" _prog ENDS ; Chiusura del Segmento di CODICE END INIZIO ; Indirizzo dell'ultima istruzione da compilare