PAGE 66,132 TITLE** PROGRAMMA di GESTIONE di programmi ASSEMBLER tipo COM (aprile 2009) SUBTTL** EsA022.ASM - Esercizi PALESTRA ASSEMBLY APPRENDISTI - by ing. G.OBER ;/---------------------------------------------------------------------------\ ;| NOME : EsA022.ASM | ;| AUTORE : Giorgio OBER | ;| VERSIONE : aprile 2009 | ;| DESCRIZIONE : Esercizio nø 0022 | ;| Stampa 80 numeri, in sequenza casuale, mostrando sia il| ;| valore esadecimale che quello decimale. | ;| Collaudo della procedura che provvede alla conversione di| ;| una Word nei caratteri Ascii decimali corrispondenti. | ;\---------------------------------------------------------------------------/ ; 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 Random:NEAR ; DICHIARAZIONI (VARIABILI) PER I PROGRAMMI ESTERNI: PUBLIC ATTRIB ;Attributo di colore ; DICHIARAZIONI (PROCEDURE) PER I PROGRAMMI ESTERNI: PUBLIC EsA022 ;DEFINIZIONE DEL SEGMENTO DEL CODICE ;----------------------------------------------------------------------------- _prog SEGMENT BYTE PUBLIC 'CODE' ASSUME CS:_prog,DS:_prog ORG 0100H INIZIO: JMP EsA022 ;AREA DESTINATA AI DATI DEL PROGRAMMA ;----------------------------------------------------------------------------- ATTRIB DB 0FH Testo01 DB " Stai vedendo 80 tra i possibili valori di una Word ",00H Testo02 DB " Il programma genera casualmente questi numeri ",00H Testo03 DB " e ne mostra il valore esadecimale e decimale ",00H Testo04 DB " con l'aiuto delle procedure ~Wor2Asc~ e ~Wor2Dec~ ",00H Testo05 DB " Premi un tasto qualunque per tornare al DOS... ",00H ;AREA DESTINATA ALLE PROCEDURE DEL PROGRAMMA ;/---------------------------------------------------------------------------\ ;| PROCEDURA : Wor2Dec.ASM | ;| DESCRIZIONE : Trasforma la Word esadecimale fornita in AX nei caratteri| ;| ASCII corrispondenti, ponendoli a video nella posizione di| ;| stampa corrente con l'attributo di Colore specificato nella| ;| variabile [ATTRIB]; gli "0" non significativi non vengono| ;| stampati. | ;\---------------------------------------------------------------------------/ Wor2Dec:PUSH AX ; Salva i Registri usati dalla Procedura, com- PUSH BX ; preso il valore da convertire, passato in in- PUSH DX ; gresso in AX CMP AX,10000 ; Se il numero esadecimale in ingresso Š minore JC Wor2_0 ; di 10000 la successiva divisione viene evitata MOV DX,0000H ; (DX,AX=0000XXXX):(BX=10000)=AX, resto DX MOV BX,10000 ; Prepara il divisore a 10000 DIV BX ; Esegue la divisione CALL STAasci ; Stampa il valore delle Decine di Migliaia MOV AX,DX ; Sposta in AX il Resto RRRR della divisione JMP SHORT Wor2_1 ; precedente da dividere nella fase successiva Wor2_0: CMP AX,1000 ; Se il numero esadecimale in ingresso Š minore JC Byt2_0 ; di 1000 la successiva divisione viene evitata Wor2_1: MOV DX,0000H ; (DX,AX=0000XXXX):(BX=1000)=AX, resto DX MOV BX,1000 ; Prepara il divisore a 1000 DIV BX ; Esegue la divisione CALL STAasci ; Stampa il valore delle Migliaia MOV AX,DX ; Sposta in AX il Resto RRRR della divisione JMP SHORT Byt2_1 ; precedente da dividere nella fase successiva ;/---------------------------------------------------------------------------\ ;| PROCEDURA : Byt2Dec.ASM | ;| DESCRIZIONE : Trasforma il Byte esadecimale fornito in AL nei caratteri| ;| ASCII corrispondenti, ponendoli a video nella posizione di| ;| stampa corrente con l'attributo di Colore specificato nella| ;| variabile [ATTRIB]; gli "0" non significativi non vengono| ;| stampati. | ;\---------------------------------------------------------------------------/ Byt2Dec:PUSH AX ; Salva i Registri usati dalla Procedura, com- PUSH BX ; preso il valore da convertire, passato in in- PUSH DX ; gresso in AL MOV AH,00H ; Formatta il dividendo al valore AX=00XX Byt2_0: CMP AX,100 ; Se il numero esadecimale in ingresso Š minore JC Byt2_2 ; di 100 la successiva divisione viene evitata Byt2_1: MOV BL,100 ; Prepara il divisore a 100 DIV BL ; Divide AX=00XX per BL=100 (AX:BL=AL, resto AH) CALL STAasci ; Stampa il valore delle Centinaia MOV AL,AH ; Sposta in AL il Resto RR della divisione pre- MOV AH,00H ; cedente da dividere nella fase successiva, JMP SHORT Byt2_3 ; formattando il dividendo al valore AX=00RR Byt2_2: CMP AX,10 ; Se il numero esadecimale in ingresso Š minore JC Byt2_4 ; di 10 la successiva divisione viene evitata Byt2_3: MOV BL,10 ; Prepara il divisore a 10 DIV BL ; Divide AX=00XX per BL=10 (AX:BL=AL, resto AH) CALL STAasci ; Stampa il valore delle Decine MOV AL,AH ; Prepara in AL la cifra delle Unit… Byt2_4: CALL STAasci ; Stampa il valore delle Unit… POP DX POP BX POP AX RET STAasci:PUSH AX ; --------------------------------------------- ADD AL,30H ; Accessorio per la procedura precedente CALL BIOchr1 ; --------------------------------------------- POP AX ; Stampa il valore ASCII del numero in AL RET ; ;***************************************************************************** ; ---------------------------------------------- EsA022 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,10,1FH; M_msgC Testo02,01,10,1FH; M_msgC Testo03,02,10,1FH; Mette a video il titolo M_msgC Testo04,03,10,1FH; M_COLOR 0FH ; Fissa il colore con cui stampare la stringa MOV AL,00H ; Inizializza il registro a 8 bit MOV DH,07 ; Fissa la riga iniziale a 7 MOV CX,16 ; Contatore delle righe da stampare (sono 16) xxx00: PUSH CX ; Ciclo esterno, per gestire le 16 righe di dati MOV DL,05 ; Fissa la colonna iniziale a 5 MOV CX,5 ; Contatore dei dati per ogni riga (sono 5) xxx01: ; Ciclo interno, per gestire i 5 dati per riga ; Genera un numero casuale a 16 bit, lasciato in MOV AX,0FFFFH ; uscita, nel registro AX; il numero Š compreso CALL Random ; tra 0000H e il valore (meno 1) passato in ; ingresso sempre in AX. CALL SET_cur ; Fissa dinamicamente la posizione di stampa ; Ciclo interno, per gestire i 10 dati per riga CALL Wor2Asc ; PUSH AX ; MOV AL,'H' ; Dopo la stampa dei 4 caratteri ascii corri- CALL BIOchr1 ; spondenti ai 4 nibble della word corrente sono MOV AL,'=' ; aggiunti il carattere "H" (per ribadire che si CALL BIOchr1 ; tratta di un valore esadecimale) e il valore POP AX ; decimale, seguito da uno spazio, per staccare CALL Wor2Dec ; la stampa di un valore dal successivo PUSH AX ; MOV AL,' ' ; CALL BIOchr1 ; POP AX ; INC AL ADD DL,15 ; Punta la colonna successiva e provvede alla LOOP xxx01 ; stampa del dato successivo INC DH ; Punta la riga successiva e provvede alla sua POP CX ; stampa LOOP xxx00 ; ; ---------------------------------------------- M_msgC Testo05,24,10,1FH; 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 ; EsA022 ENDP ; Chiusura della Procedura "Main Program" _prog ENDS ; Chiusura del Segmento di CODICE END INIZIO ; Indirizzo dell'ultima istruzione da compilare