.............ESEMPI........
Ora esaminiamo qualche codice più "complesso" che però non dovrebbe essere difficile da capire.Iniziamo con un semplice programma di input e output.
.model tiny
; indica il modello usato, spiegato nella edizione precedente.code
; ecco che troviamo l'inizio del codiceorg 100h
; l'indirizzo dove partono tutti i files con estensione .cominizio:
; qua inizia il codice vero e proprio.E' solamente un nome al quale fa riferimento l'assembler, quindi lo potete chiamare come volete.Visto che tutto quanto inizia là mi sembra piuttosto logico chiamarlo così.Mov dx, offset messaggio
Mov ah,9
Int 21h
; questo serve per visualizzare il messaggio sullo schermo.Ah, come sapete, è il high byte di ax.Potete ricordare che il high byte viene sempre usato per caricare una funzione di un interrupt.Nel nostro caso, verrà eseguita la funzione 09h dell'interrupt 21h.Come vedete una lista degli interrupt e le loro funzioni è indispensabile.Mov dx, offset visualizza
Mov ah, 9
Int 21h
Jmp primo_prompt
; Qui ritroviamo praticamente la stessa cosa come sopra, solamente che qua viene caricato "visualizza", però il principio è sempre lo stesso.Alla fine troviamo un jmp primo_prompt.Questo , come già dovreste sapere, indica all'assembler di "continuare con un'altra parte del codice".I comandi del Jump sono piuttosto tanti, che verrano spiegati nella prossima edizione.Un_altro:
Mov dx, offset altro
Mov ah, 9
Int 21h
; La funzione di questa porzione del codice ormai dovrebbe essere chiara a tutti.Tutto questo viene eseguito sotto il nome Un_altro.Di questo ne avremo bisogno più avanti, visto che l'assembler farà riferimento a Un_altro.Primo_prompt:
Mov dx, offset ancora
Mov ah,9
Int 21h
;Ecco che ritroviamo il Primo_prompt.Non penso che ci sia molto da ;spiegare, per ora non è cambiato molto :-)Xor ah, ah
Int 16h
Mov bl, al
; Xor viene spiegato nella sezione "comandi".Qua lo usiamo per azzerare il register.Ah, Ah corrisponde alla funzione 00h.Ovviamente fa riferimento all'interrupt 16h.L'interrupt 16h è quello della tastiera e la funzione 00h legge semplicemente un valore dalla tastiera.Il valore ASCII verrà caricato in al, mentre il codice vero e proprio si ritroverà in ah.L'ultima riga caricherà il valore di al in bl.Mov dl,al
Mov ah, 02h
Int 21h
; la prima riga carica al in dl, esattamente il valore ASCII come abbiamo ;stabilito prima.Il resto eseguirà la funzione 02h dell'interrupt 21h, per visulizzare il ;carattere premuto con la tastiera.Cmp bl, "s"
Je Un_altro
Cmp bl, "s"
Je Un_altro
; Il comando cmp, come spiegato nella sezione "comandi", effettua un confronto, in questo caso di bl.Questa funzione del comando Jump, il Jump if equal stabilisce se il valore di bl,praticamente il tasto premuto, corrisponde alla lettera "s".In caso positivo, eseguirà nuovamente Un_altro, altrimenti continuerà semplicemente con il codice.Mov dx, offset se_vedemo
Mov ah,9
Int 21h
Mov ah,4ch
Int 21h
; L'unica cosa nuova è il mov ah, 4ch. Come spiegato nella edizione ;precedente, questa funzione termina il programma ritornando al DOS.Cr equ 13
Lf equ 10
Messaggio db "Un semplice programma di input e output$"
Visualizza db cr,lf, "Ecco il primo prompt$"
Ancora db cr,lf, " Gradisce un altro prompt ?$"
altro db cr,lf, "Ecco un altro prompt$"
Se_vedemo db cr,lf, " Alla prossima$"
End inizio
; Il discorso del db e roba varia l'abbiamo fatto gia', quindi non ci ;dovrebbe essere alcuna difficoltà.Ricordate sempre di mettere alla fine un end con ;il nome che avete dato all'inizio.Ecco, questo è tutto per quello che riguarda questo semplice programma.Copiate direttamente tutto il codice in un editor qualsiasi, salvatelo come vi pare e compilatelo con il Tasm.La sintassi è molto facile, Tasm "nomefile".asm.E poi usate il Tlink "nomefile". Ricordate però di aggiungere l'opzione Tlink "nomefile" / t per creare un .com file.Altrimenti il Tasm vi dirà che non è presente alcun stack, visto che il default del Tasm è di creare files .exe.
Il seguente programma crea un file di nome "test.txt"
.model small
.stack
.code
; L'unica cosa nuova che ritroviamo è .stack.Ciò significa che lavoreremo ;con lo stack, quindi il file eseguibile avrà l'estensione .exemov dx, offset inizio
mov ax, seg inizio
mov ds, ax
; Uno scopo molto importante quando programmate virus è quello di rendere il codice il più compatto possibile in modo che il virus abbia una grandezza ancora accettabile.Nel nostro caso questo significa che possiamo cambiare una piccola cosa rendendo le cose più semplici.Avrei potuto scrivere anche anzichè mov dx, offset inizio;mov ax, seg inizio
;mov ds,ax
; semplicemente mov dx, offset nome, aggiungendo all'inizio un mov ax, @data
;Mov ds, ax ; l'indirizzo del data segment
mov ah, 09h
int 21h
; Mi sa che non devo aggiungere molto.Tutto questo serve per visualizzare ;il messaggio "inizio".Mov dx, offset nomefile
Xor cx, cx
Mov ah, 3ch
Int 21h
Jc errore_creando
; La prima riga carica l'offset in dx, xor, ormai lo sapete, azzera ;il registro cx, in modo che venga creato un semplice file, senza attributi o roba ;varia.La funzione 3ch dell'interrupt 21h viene usata per creare un file.Se, mentre il ;tutto verrà eseguito, accadrà un errore, allora sarà eseguito "errore_creando".Mov dx, offset nomefile
Mov al,2
Mov ah,3dh
Int 21h
Jc errore_aprendo
Mov nome, ax
; Usando mov al,2 abiliterete il modo di lettura/scrittura.La funzione ;3dh dell'interrupt 21h serve per aprire un file.Se, aprendo, succederà qualcosa che ;non dovrebbe accadere, verrà eseguito "errore_aprendo".Con mov nome,ax ;salverete il valore di ax in nome, cioè il nome del file.Mov dx, offset scrivi
Mov bx, nome
Mov cx, 71
Mov ah, 40h
Int 21h
Jc errore_scrivendo
; Bene, la prima riga carica l'offset in dx, poi "nome" viene ;caricato in bx, mov cx, 71 segnala la quantità di bytes da scrivere.(ricordate cx è il ;counter register, viene sempre usato per stabilire una certa quantità di qualcosa). ;La funzione 40h scrive sul file, e infine, se ci sarà qualche problema verrà eseguito ;"errore_scrivendo".Cmp ax, cx
Jne errore_scrivendo
; Questo confronta il valore di cx con quello di ax per vedere se tutti i bytes sono stati scritti.In caso contrario verrà eseguito "errore_scrivendo".Mov bx, nome
Mov ah, 3eh
Int 21h
;Carica il valore "nome" in bx e con la funzione 3eh dell'interrupt 21h il file verrà di nuovo chiuso.Mov dx, offset fine_mex
Mov ah, 09h
Int 21h
; questo caricherà il messaggio contenuto in "fine" in dx e con la funzione 09h verrà visualizzato il testo sullo schermo.Mov ax, 4c00h
Int 21h
; E infine la funzione per ritornare al DOS;Adesso dobbiamo definire che cosa "sta dietro" a tutti quei nomi.
Errore_scrivendo: mov dx, offset mex1
Jmp fine
; Questo visualizzerà un messaggio e poi eseguirà "fine"Errore_aprendo: mov dx, offset mex2
Jmp fine
; esattamente la stessa proceduraErrore_creando : mov dx, offset mex3
Jmp fine
; non c'e' niente di nuovo :-)Fine: mov ah,09h
Int 21h
Mov ax,4c01h
Int 21h
; termina il programma ritornando dal DOS usando la funzione 09h dlel'interrupt 21hCr equ 13
Lf equ 10
Inizio db "Adesso verra' creato un file di nome test.txt$"
Fine_mex db cr,lf, " Il file e' stato creato$"
Mex1 db " Errore scrivendo il file$"
Mex2 db " Errore aprendo il file$"
Mex3 db " Errore creando file$"
scrivi db " Se stai leggendo questo, il programma avra' funzionato alla perfezione",0
Nomefile db "test.txt",0
Nome dw ?
End
Mi sembra che per l'ultima parte del codice non ci dovrebbero essere problemi.In caso contrario, mandatemi le vostre domande via e-mail.La procedura è sempre la stessa, copiate tutto il codice in un editor, salvate il file come volete voi, e compilatelo con il Tasm.Questa volta, usando il Tlink non aggiungete l'opzione /t, visto che abbiamo lavorato con lo stack e deve essere compilato in formato .exe.La sintassi da usare è la seguente: Tasm "nomefile" /m2 e poi Tlink "nomefile".
Questo piccolo programma invece cancellerà di nuovo il file test.txt creato.
.model small
.stack
.data
cr equ 13
lf equ 10
Nome_file db "test.txt",0
Cancellato db " Il file test.txt e' stato cancellato$"
Non_mex db "Impossibile eliminare test.txt$"
Non2_mex db"Il file test.txt non esiste$"
;definizioni dei nomi assegnati.code
;ormai avrete capito di che cosa si trattamov ax,@data
mov ds,ax
; dovrebbe essere chiaromov dx, offset nome_file
mov cx, 3fh
mov ah, 4eh
int 21h
; nome_file sarà logicamente il file che verrà cancellato, la funzione 3fh serve per leggere un file, la funzione 4eh indica il tipo di file.In questo il programma cercherà il primo file di nome "test.txt" senza attributi, tipo la protezione in scrittura oppure un file nascosto.Jc non_esiste
; se il file "test.txt" non esiste, verrà eseguito "non_esiste".Nel nostro caso verrà visualizzato un messaggio di errore.Mov dx, offset nome_file
Mov ah, 41h
Int 21h
; offset nome_file indica il file da cancellare, e la funzione 41h dell'interrupt 21h cancellerà il file.Jc non_riuscito
; se il programma non avrà cancellato il file, per esempio se è protetto in scrittura, verrà eseguito "non_riuscito"Jmp fine
; una volta cancellato il file, il programma continuerà con "fine".fine:
Mov dx, offset cancellato
Jmp esci
; In questo modo, prima di uscire, verrà visualizzato un messaggio. L'uscita "vera e propria" sarà contenuta in "esci".Non_riuscito:
Mov dx, offset non_mex
Jmp esci
; se c'e' stato qualche problema nel cancellare il file, il programma visualizzerà un messaggio di errore e terminerà tramite "esci".Non_esiste:
Mov dx, offset non2_mex
Jmp esci
; ecco il messaggio di errore se non è stato trovato il file "test.txt"Esci :
Mov ah,9
Int 21h
Mov ax,4c00h
Int 21h
; la solita procedura di chiusura tramite l'interrupt 21h.End
Ora copiate tutto il codice e compilatelo con il Tasm.
RITORNA......................INDICE