Capitolo 1: Strumenti necessari per la sezione Win32 Assembly
Nella sezione Win32 Assembly vengono illustrate le tecniche generali che si
utilizzano per lo sviluppo dei programmi Assembly destinati a "girare" in
ambiente Windows; il termine Win32 indica tutte le versioni a 32
bit del sistema operativo Windows, come Windows 95, Windows 98,
Windows ME, Windows NT, Windows 2000, Windows XP (che
esiste anche in versione a 64 bit).
Naturalmente si da' per scontato il fatto che chi legge questa sezione abbia una
buona conoscenza generale della programmazione in Assembly; in particolare,
e' importante avere una certa dimestichezza con il set di istruzioni a 32
bit e soprattutto con gli indirizzamenti a 32 bit. Bisogna osservare inoltre
che il sistema operativo Win32 sfrutta la modalita' protetta delle CPU
80386 e superiori; e' importante quindi avere anche una conoscenza generale
dei concetti che stanno alla base di questa modalita' operativa delle CPU. Ricordiamo
le principali novita' che caratterizzano la modalita' operativa protetta a 32 bit:
* I segmenti di programma possono avere l'attributo SIZE di tipo
USE32. * Gli indirizzamenti predefiniti sono di tipo NEAR a 32
bit. * E' possibile utilizzare qualsiasi registro generale a 32 bit
come registro puntatore. * Lo stack viene gestito dalla CPU attraverso ESP, e dal programmatore
attraverso EBP. * La dimensione predefinita per gli operandi immediati e' di 32 bit.
Ulteriori dettagli vengono esposti nel capitolo successivo.
In ogni caso, per scrivere programmi Assembly in ambiente Win32 non e'
necessario destreggiarsi tra descrittori di segmento, selettori, task switching,
etc; tutti questi aspetti vengono infatti gestiti dal sistema operativo e non dal
programmatore. E' chiaro pero' che se si e' interessati agli aspetti piu' nascosti di
Windows e' necessaria una conoscenza piuttosto approfondita della programmazione
in modalita' protetta e dei concetti che stanno alla base della progettazione dei
sistemi operativi (da ora in poi chiamati SO); le sezioni Assembly Base,
Assembly Avanzato e Modalita' Protetta rappresentano una buona base di
partenza per chi fosse interessato a questi argomenti.
1.1 Strumenti di sviluppo
Per poter sviluppare programmi Windows in Assembly e' necessario dotarsi di una
serie di adeguati strumenti; la dotazione minima comprende:
* un editor di testo
* un assembler a 32 bit
* un linker a 32 bit
* un compilatore di risorse
* un editor di icone
* il Windows SDK
L'editor di testo ci serve per creare, modificare, salvare su disco o leggere dal disco i
files contenenti il codice sorgente dei nostri programmi Assembly; come al solito,
questi files devono essere rigorosamente in formato
ASCII
perche questo e' cio' che viene richiesto dall'assembler. Per motivi di chiarezza e di stile,
si consiglia di rispettare tutte le convenzioni per le estensioni dei files contenenti
programmi Assembly; i files contenenti il codice sorgente dovrebbero utilizzare
l'estensione ASM, i files contenenti direttive, dichiarazioni, prototipi di procedure,
etc, dovrebbero utilizzare l'estensione INC, i files contenenti macro dovrebbero
utilizzare l'estensione MAC, e cosi' via.
L'assembler ha il compito di convertire il codice sorgente del nostro programma in codice
oggetto; come al solito, se il codice sorgente e' distribuito su piu' files, verranno
generati altrettanti files con estensione OBJ contenenti il codice macchina del
nostro programma. E' chiaro che per poter sviluppare programmi per Win32 e'
necessario un assembler in grado di supportare il set di istruzioni a 32 bit; se
poi si vogliono utilizzare istruzioni disponibili solo in modalita' protetta (come
LLDT), e' necessario un assembler che accetti direttive del tipo .386p (set
di istruzioni a 32 bit in modalita' protetta).
Il linker ha il compito di collegare tra loro i vari moduli oggetto e di generare il
programma finale in formato eseguibile (estensione EXE); il linker deve essere
capace di generare eseguibili a 32 bit compatibili con Windows. Infatti,
il formato EXE utilizzato da Windows e' differente dall'analogo formato
utilizzato in ambiente DOS; la struttura degli eseguibili per Windows
viene analizzata in un apposito capitolo della sezione Win32 Assembly.
Il compilatore di risorse e' uno strumento di sviluppo tipico dell'ambiente Windows;
questo particolare compilatore opera sui cosiddetti Resource Files (files di risorse)
di Windows. Come si intuisce dal nome, un file di risorse e' destinato a contenere
una serie di risorse che verranno utilizzate da una applicazione Windows; tra le
risorse piu' conosciute possiamo citare i menu, le icone, le immagini in formato
bitmap, etc. I files di risorse utilizzano l'estensione predefinita RC e anche
in questo caso devono essere in formato ASCII; il compilatore di risorse compila il
FILE.RC e lo converte in un FILE.RES che e' compatibile con il formato oggetto
(OBJ). A questo punto il FILE.RES viene passato al linker che provvede a
collegarlo ai vari moduli OBJ per poter ottenere il programma finale in versione
EXE.
L'editor di icone e' un'altro strumento di sviluppo tipico dei SO o ambienti operativi
che utilizzano interfacce grafiche; uno degli oggetti piu' caratteristici delle interfacce
grafiche e' rappresentato proprio dall'icona che e' una sorta di bitmap formata in
genere da 16 x 16 o 32 x 32 pixel. Nell'interfaccia grafica di Windows,
di Linux, di OS/2, etc, ad ogni programma viene associata un'icona chiamata icona
del programma; l'editor di icone ci permette proprio di creare o modificare icone, e di salvarle
su disco nel tipico formato di immagine ICO utilizzato da Windows. A rigore bisogna
dire che l'editor di icone non e' uno strumento indispensabile; infatti, se il programmatore non
specifica una icona personalizzata, Windows provvedera' ad assegnare al programma una
icona predefinita. Su Internet sono reperibili numerosi editor di icone, dai piu' semplici
ai piu' sofisticati; per trovarli ci si puo' servire di un motore di ricerca e utilizzare un
criterio di ricerca del tipo windows AND iconedit.
Il Windows SDK rappresenta uno strumento senza il quale non sarebbe possibile sviluppare
programmi per Windows; la sigla SDK sta per Software Development Kit e cioe'
kit software per lo sviluppo dei programmi Windows. L'SDK rappresenta una collezione
di librerie contenenti tutti gli strumenti che Windows mette a disposizione dei
programmatori per la gestione dei files, gestione della memoria, gestione della grafica,
multimedia, telecomunicazioni, etc; l'SDK occupa su disco diversi Mb, ed e' importante
procurarsi la versione piu' aggiornata possibile per poter usufruire di tutte le nuove
funzionalita' messe a disposizione dalle versioni piu' recenti di Windows. L'SDK
di Windows e' scritto principalmente in linguaggio C standard (ANSI C),
mentre le parti piu' critiche, strettamente legate alla piattaforma hardware utilizzata, sono
state scritte guarda caso in Assembly; queste considerazioni ci fanno capire che i
programmi Windows scritti in C o Assembly risultano piu' semplici, compatti
e veloci degli analoghi programmi scritti con qualunque altro linguaggio di programmazione.
1.2 Assembler disponibili
L'assembler che offre il supporto piu' completo per lo sviluppo di applicazioni Windows
e' sicuramente il Microsoft Macro Assembler (MASM); l'aspetto piu' interessante
e' dato dal fatto che la Microsoft da un po' di tempo ha deciso di distribuirlo "gratis"
via Internet (con la solita chilometrica licenza d'uso che tutti evitano di leggere
premendo direttamente il pulsante [Accept]). Grazie ad un rapporto di collaborazione tra
la Microsoft e un gruppo di programmatori, e' nato il progetto MASM32 che ha lo
scopo di promuovere l'uso dell'Assembly per lo sviluppo di applicazioni Win32;
MASM32 fornisce ai programmatori interessati un vasto insieme di strumenti di sviluppo
che comprende tra l'altro: l'assembler, il linker, il compilatore di risorse, l'SDK, un
ottimo editor di testo (Quick Editor), etc. Nella sezione Links Utili e' presente
un link al sito ufficiale del progetto MASM32; accedendo a questo sito e' possibile
scaricare MASM32 (circa 4 Mb) insieme a diversi esempi di applicazioni Windows
scritte in Assembly. Tra l'altro, lo stesso MASM32 contiene una notevole quantita'
di eccezionali esempi pratici scritti dagli stessi programmatori della Microsoft; nella
sezione Downloads, premendo il pulsante [Info] si ottengono le informazioni
necessarie per installare MASM32.
Un'altro assembler professionale che permette di sviluppare applicazioni Windows e' il
Borland Turbo Assembler (TASM) che a differenza del MASM e' pero' a
pagamento; si tratta comunque di un assembler nettamente piu' affidabile del MASM, tanto
che la stragrande maggioranza dei programmatori Assembly lo considera il miglior assembler
disponibile nel mondo dei PC. Del resto la Borland e' una software house resa celebre da
mitici compilatori e interpreti come il Turbo Basic, il Turbo Pascal, il
C/C++, Delphi, etc, che si differenziano dagli analoghi prodotti Microsoft
per la quasi totale assenza di bugs; si puo' dire che grazie alla Borland, milioni di
programmatori in tutto il mondo hanno appreso l'arte della programmazione.
La versione piu' aggiornata del TASM e' la 5.0 che mette a disposizione
l'assembler a 32 bit (TASM32.EXE), il linker a 32 bit (TLINK32.EXE)
in grado di generare eseguibili per Windows, il compilatore di risorse e numerosi
altri strumenti. Per i fortunati possessori del TASM, si presenta un problema legato
al fatto che l'SDK fornito con la versione 5.0 dell'assembler risale all'era
paleozoica di Windows 95; si tratta quindi di un SDK molto vecchio e pressoche'
inutilizzabile. Un vero programmatore Assembly pero' non puo' certo fermarsi davanti
a questi ostacoli; vediamo allora come puo' essere risolto il problema in modo da poter
utilizzare non solo TASM 5.0 ma persino le versioni precedenti. La prima idea che
viene in mente puo' essere quella di installare MASM32 per utilizzare poi il relativo
SDK con TASM; questa idea pero' non funziona in quanto le librerie usate dal
MASM contengono codice oggetto in formato COFF, mentre il TASM e tutti
i vari compilatori Borland, accettano solo codice oggetto in formato standard
OMF (vedere la sezione Downloads per la documentazione ufficiale su questi due
formati). La strada che dobbiamo seguire consiste allora nel procurarci la versione piu'
recente possibile dell'SDK che la Borland distribuisce insieme ai suoi
compilatori; questa opportunita' ci viene offerta dal fatto che da tempo la Borland
distribuisce gratuitamente le versioni a linea di comando dei suoi potentissimi compilatori
C/C++ come il Borland C/C++ compiler 5.x e il Borland C++ Builder 5.x
(o versioni superiori). Si possono seguire due strade in quanto questi prodotti sono disponibili
sia sui CD allegati alle varie riviste di programmazione, sia via Internet nel sito della
Borland (vedere la sezione Links Utili); in entrambi i casi, bisogna registrarsi
gratuitamente on-line. Una volta installato il compilatore C/C++ abbiamo finalmente a
disposizione l'SDK, che generalmente viene sistemato in una sottocartella chiamata
Lib; se lo si desidera si puo' anche copiare l'SDK nella cartella dove abbiamo
installato il TASM (creando un'analoga sottocartella Lib). Osserviamo che il
compilatore C/C++ ci mette a disposizione anche il linker e il compilatore di risorse;
tutti questi strumenti possono essere utilizzati al posto degli analoghi strumenti forniti con
il Turbo Assembler. A questo punto siamo "quasi" pronti per utilizzare TASM nello
sviluppo di applicazioni Win32; l'ultimo passo da compiere viene descritto nel seguito
del capitolo.
Tra i vari assembler che si possono utilizzare per lo sviluppo di applicazioni Windows,
una menzione speciale spetta al prodotto freeware NASM; la versione a 32 bit di
NASM supporta il formato oggetto COFF e puo' essere quindi usata in combinazione
con l'SDK fornito con MASM32. Chi volesse usare NASM per sviluppare
applicazioni Windows, puo' reperire tutta la documentazione necessaria via Internet;
tutti gli esempi proposti nella sezione Win32 Assembly si riferiscono esclusivamente a
MASM e TASM.
1.3 Gli include files
Dopo aver installato MASM32 sul disco fisso (generalmente nella cartella masm32), si
nota la presenza di due sottocartelle chiamate Lib e Include; la sottocartella
Lib contiene ovviamente la collezione di librerie dell'SDK, mentre la sottocartella
Include contiene gli include files. Come gia' sappiamo, gli include files
dell'Assembly equivalgono agli header files del C/C++ e sono destinati a
contenere prototipi di procedure, dichiarazioni di strutture, di union, di costanti simboliche,
etc; in questo caso tutti questi prototipi e dichiarazioni servono per poter interfacciare i
nostri programmi Assembly con l'SDK di Windows.
Nel caso del TASM, dobbiamo tener presente che stiamo utilizzando l'SDK fornito
in dotazione ai compilatori C/C++ della Borland; nella sottocartella Include
del compilatore troveremo quindi non gli include files ma gli header files necessari per
interfacciare i programmi C/C++ con l'SDK. Fortunatamente, le versioni piu' recenti
del TASM, supportano la sintassi avanzata imposta dalla Microsoft per le
dichiarazioni presenti negli include files del MASM32 (vedere il Capitolo 28 della sezione
Assembly Base); questo significa che nella gran parte dei casi, gli include files di
MASM32 possono essere utilizzati con il TASM. Possiamo allora copiare gli include
files di MASM32 in una apposita sottocartella Include di TASM. Purtroppo,
come abbiamo visto nella sezione Assembly Base, esistono delle differenze tra MASM
e TASM per quanto riguarda in particolare la visibilita' dei membri di strutture e union;
tanto per citare un esempio, in MASM il nome di un membro di una struttura e' locale
alla struttura stessa e puo' essere quindi riutilizzato per identificare un membro di un'altra
struttura, un parametro di una procedura, una variabile locale, etc. In TASM invece il
nome di un membro di una struttura e' visibile anche all'esterno della struttura stessa e non
puo' quindi essere ridefinito; in caso contrario TASM genera un errore. Nei vari esempi
che vengono presentati nella sezione Win32 Assembly, vengono illustrati i rimedi che
bisogna adottare per eliminare queste situazioni di errore.
1.4 L'include file Windows.inc
Tra tutti gli include files, il piu' importante di tutti e' sicuramente Windows.inc che
equivale all'header file Windows.h usato dai programmi C/C++ per Windows
e viene chiamato include file principale; il file Windows.inc contiene al suo
interno una autentica marea di dichiarazioni di procedure, di strutture, di union, di costanti,
di tipi di dati (typedef), etc. Queste dichiarazioni sono indispensabili per poter
sviluppare qualunque applicazione per Windows; se si osserva il codice sorgente del modulo
principale di un programma per Windows, si nota che all'inizio e' sempre presente una direttiva
del tipo: INCLUDE ..\Include\Windows.inc
All'interno di Windows.inc si possono trovare ad esempio dichiarazioni del tipo: UINT TYPEDEF DWORD
Questa dichiarazione crea un nuovo tipo di dato UINT che rappresenta il tipo intero senza
segno a 32 bit. E' importantissimo che il programmatore dia un'occhiata a questo include
file per farsi un'idea precisa del suo contenuto; si tenga presente infatti che in fase di
sviluppo dei programmi Assembly per Windows, la consultazione di Windows.inc
diventa una pratica frequentissima.
Il file Windows.inc relativo a MASM32 viene tenuto costantemente aggiornato da
diversi programmatori; nella sezione Downloads e' possibile scaricare l'aggiornamento
piu' recente curato da Iczelion. Purtroppo questo file e' inutilizzabile con TASM
a causa delle incompatibilita' descritte in precedenza; per questo motivo, chi utilizza
TASM e' tenuto a scaricare un apposito include file Windows.inc. Nella sezione
Downloads e' presente oltre ad un generico file Windows.inc per TASM,
anche un analogo file Win32.inc; il file Win32.inc viene costantemente aggiornato
da Ra.M. Software.
1.5 Documentazione
Per poter utilizzare l'SDK il programmatore deve conoscere i nomi con i quali vengono
chiamate le funzioni, procedure, macro, strutture, union, costanti simboliche, etc, presenti
nell'SDK stesso; tutte queste dichiarazioni utilizzano la classica sintassi del linguaggio
C, e nel loro insieme formano la cosiddetta Windows API. La sigla API sta
per Application Programming Interface (interfaccia per la programmazione delle applicazioni)
e indica appunto l'interfaccia che bisogna utilizzare per accedere agli strumenti dell'SDK;
si tratta di centinaia e centinaia di nomi che un programmatore non puo' certo ricordare a memoria.
E' molto importante quindi procurarsi un manuale di riferimento sull'API di Windows,
che deve essere il piu' possibile aggiornato; fortunatamente grazie a Internet e' possibile
scaricare un file generalmente chiamato win32.zip e contenente un documento chiamato
Win32 Programmer's Reference in formato HLP (Help File di Windows). Questo
file, una volta decompresso occupa su disco oltre 24 Mb, ma nonostante le dimensioni
consistenti, contiene una versione dell'API aggiornata al 1996; in ogni caso si
tratta di un documento che si rivela di estrema utilita' per il programmatore. La documentazione
completa dell'API di Windows occupa diversi CD-ROM ed e' ottenibile a pagamento
dalla Microsoft; in alternativa, la versione completa ed aggiornata dell'API e'
consultabile gratuitamente via Internet nel sito della stessa Microsoft. Nella
sezione Links Utili e' presente un link al sito web di MrCrimson che oltre al file
win32.zip contiene anche una eccezionale collezione di ducumenti sull'API di
Windows sempre in formato HLP.
Nota importante
Si tenga presente che diversi siti web citati nella sezione Links Utili vengono gestiti da
programmatori e appassionati; la sopravvivenza di tali siti (e quindi anche di questo) e' legata
spesso alle decisioni di chi li ospita o di chi li gestisce. E' del tutto normale quindi che
questi siti possano scomparire improvvisamente per poi riapparire magari ad un altro indirizzo
Internet; nei limiti del possibile la sezione Links Utili viene costantemente
aggiornata in modo da garantire il corretto funzionamento dei vari links.