Anno: 1992

Capitolo 3

STRUTTURA DEI FILE SOTTO DOS

Il DOS riconosce due distinte strutture di base per identificare i programmi applicativi che manda in esecuzione:
Una struttura ASSOLUTA per i file .COM e .SYS
Una struttura RILOCABILE per i file .EXE e .SYS

La struttura Assoluta, una volta caricata in memoria, rappresenta la copia fedele del programma cosi' come e' codificata sul disco.
Questa struttura comporta pero' alcune limitazioni:
Non puo' superare i 64Kb nel suo complesso e quindi deve occupare un solo segmento.
La sua partenza avviene sempre all'indirizzo Offset 0100h.

La struttura Rilocabile permette di superare il limite dei 64 Kb ed e' formata da un'intestazione, detta anche Header, lunga non meno di 512 Byte che contiene tutte le informazioni adatte al caricamento in memoria del programma, la quantita' di memoria necessaria, i valori da apporre in alcuni registri ed i dati usati dal DOS per rilocare, con gli opportuni valori, i riferimenti ai segmenti usati dal programma stesso.
Il termine rilocazione si riferisce al fatto che il linker definisce in fase di compilazione gli indirizzi dei segmenti e le locazioni di memoria che verranno usate dal programma una volta caricato.

Vedremo qui di seguito un semplice programma che si limita a scrivere la frase "Ciao a tutti" sullo schermo.
Esso verra' presentato nelle sue strutture: Assoluta (scritta in Assembly) Rilocabile (scritta sempre in Assembly) e Rilocabile (scritta in Basic).

Nota: Le strutture scritte nei linguaggi ad alto livello (C , Pascal , Basic) vengono sempre convertite in una forma Rilocabile con alcune eccezioni per il C ed il Pascal che per alcune particolari versioni e con alcuni accorgimenti possono assumere la forma Assoluta.
Il Basic nella forma compilata assume sempre la forma Rilocabile.
Il linguaggio Assembly consente di scegliere la forma Assoluta o Rilocabile a seconda delle esigenze.
Il passaggio tra la forma Rilocabile e quella Assoluta avviene convertendo il file con estensione .EXE in .COM con l'ausilio del programma EXE2BIN fornito con il S.O. MS-DOS.

Verranno ora esaminate le tre strutture ed i codici presenti in memoria.

Iniziamo con la struttura Assoluta.

Per prima cosa viene scritto il programma in linguaggio Assembly usando le convenzioni definite per il linguaggio stesso.

Per assumere la forma Assoluta il programma cosi' scritto deve passare attraverso 3 fasi ben distinte.
L'assemblaggio per mezzo del programma MASM ( MASM CIAOCOM ) che genere il File CIAOCOM.OBJ
Il Linkaggio o collegamento tramite il LINK ( LINK CIAOCOM ) che genera il File CIAOCOM.EXE.
La conversione in formato .COM per mezzo del programma EXE2BIN ( EXE2BIN CIAOCOM.EXE CIAOCOM.COM ).
A questo punto digitando dalla riga di comando CIAOCOM apparira' sullo schermo la scritta: Ciao a tutti.

Nota: Al termine della fase di linkaggio, il linker genera l'errore No Stack Segment.
Cio' e' normale per i file che dovranno assumere una forma Assoluta in quanto il segmento di Stack non e' definito nel programma.
Il file .EXE generato non puo' essere lanciato in quanto manca della struttura propria dei file rilocabili e deve essere quindi convertito in forma Assoluta .COM

Per comodita' da ora in poi definiremo i programmi in forma Assoluta come File COM e quelli in forma Rilocabile come File EXE.

Esaminiamo ora i codici presenti sul disco ed in memoria.

Il codice del programma inizia alla locazione 2A5B:0100 ed e' perfettamente uguale a quello presente sul disco.

Il P.S.P.

Dopo aver determinato l'indirizzo piu' basso disponibile in memoria, il DOS carica il file eseguibile ed alloca per esso 2 blocchi di memoria.
Il primo contiene, l'Environment o Ambiente, che eredita dal processo o dal programma che ne ha richiesto il caricamento.
Il secondo contiene, nei primi 256 Byte il P.S.P. , detto PREFISSO DI SEGMENTO DEL PROGRAMMA, e nei rimanenti il codice ed i dati presenti nel file.
Il P.S.P. si estende dalla locazione Offset 0000 a 00FF.
Nel caso nostro specifico, il valore 2A5B rappresente l'indirizzo di paragrafo del segmento e puo' cambiare da computer a computer.
Il P.S.P. contiene delle informazioni utili sia al DOS che al programma e verranno esaminate dettagliatamente piu' avanti. ( Chiameremo il P.S.P PSP)

Il blocco di Ambiente inizia da un paragrafo di segmento puntato dall'interno del PSP, esso contiene una serie di stringhe ASCII ognuna delle quali finisce con un byte 0 (00) seguito dalla stringa successiva.
L'ultima stringa finisce con 2 Byte 0 (00 00) e tutto cio' che segue non fa piu' parte dell'Ambiente.

Esamineremo ora in dettaglio come si presenta la memoria nella quale e' stato caricato il programma ciaocom.com.

Come possiamo notare dal listato seguente l'indirizzo 2A4F:0010 contiene le stesse informazioni dell'indirizzo 2A50:0000 e quindi corrispondono allo stesso indirizzo assoluto poiche', come gia visto in precedenza, la somma del segmento + offset corrisponde allo stesso valore: 2A4F x 16h + 0010 = 2A500

Come abbiamo visto in precedenza l'Arena Header e' un paragrafo ( 16 Byte ) che contiene le informazioni relative al blocco di memoria che lo segue.
nel nostro caso l'Arena Header ci dice che :
4D Seguono altri blocchi
5B2A (punta a 2A5B) PSP del proprietario del blocco ciacom.com
0A00 (000A x 16h = 00A0 ) Lunghezza blocco in Byte che comprende quindi quanto contenuto tra 2A50:0000 e 2A50:009F
Il primo byte che si legge in locazione 2A50:00A0 corrisponde a 5A, e' il primo byte del paragrafo che precede il PSP e quindi e' un indicatore di blocco che indica la fine dello stesso.
All'indirizzo 2A50:00B0 che corrisponde a 2A5B:0000 inizia il PSP del programma come da listato completo seguente:

Il PSP inizia all'indirizzo 2A5B:0000 e termina all'indirizzo 2A5B:00FF. Esso contiene informazioni utili sia al programma che al DOS.
Vedremo ora di interpretare i byte e le parole (Word) piu' interessanti .
2A5B:0000 1 Word CD 20 Int. 20h Program exit.
2A5B:0002 1 Word 00 A0 Indirizzo A000:0000 libero. In questo caso siamo all'indirizzo della scheda grafica e quindi tutta la memoria e' stata assegnata al programma.
2A5B:0004 1 byte 00 Riservato al DOS
2A5B:0005 5 byte 9A F0 FE 1D F0 Call Far (9A) ad indirizzo.
2A5B:000A 4 byte 4F 03 83 24 Vettore Int.22
2A5B:000E 4 byte 8A 03 83 24 Vettore Int. 23.<
2A5B:0012 4 byte 17 03 83 24 Vettore Int.24
2A5B:0016 1 Word 72 24 PSP del programma chiamante, di regola Command.com
2A5B:0018 5 byte 01 03 01 00 02 Standard file handlers
2A5B:0018 15 byte Non usati
2A5B:002C 1 Word 50 2A Copia del segmento della variabile di ambiente (2A50)
2A5B:002E 4 byte 4C 01 63 29 Indirizzo SS:PP per Int.21
2A5B:0032 1 Byte 14 Max numero di file apribili
2A5B:0034 4 byte 18 00 5B 2A Puntatore alla tavola dei file
2A5B:0038 1 Byte FF FF FF FF Riservati
2A5B:0050 3 byte CD 21 CB Int. 21 + RETF
2A5B:005C 1 Byte 00 Informazioni su File Control Block
2A5B:005D 6 byte 20 20 20 20 20 20 Informazioni su File Control Block
2A5B:006C 1 Byte 00 Informazioni su File Control Block
2A5B:006D 6 byte 20 20 20 20 20 20 Informazioni su File Control Block
2A5B:0080 1 Byte 00 Num caratteri linea di comando, in questo caso zero
2A5B:0081 127 byte In questo caso non vi sono caratteri e quindi troviamo subito 0Dh che corrisponde alla fine linea

Il file ciaocom.com inzia alla locazione 2A5B:0100 e la sua struttura in memoria e' la seguente:

A seguire il programma in Assembly

Vediamo ora come si presenta lo stesso programma convertito poi in formato EXE

Come gia' accennato i file EXE sono sempre in forma rilocabile, siano essi scritti in Assembly che in linguaggio ad alto livello.
Per essi viene creata una intestazione lunga non meno di 512 Byte.
Per semplicita' non eamineremo tale struttura ma ci limiteremo ad evidenziarne alcuni Byte:

I primi 2 byte che identificano il file EXE contenuti nell' Header sono sempre 4D 5A.
Essi sono poi seguiti da una serie di byte che contengono le informazioni relative al file in esecuzione ed infine dai codici del file stesso.
Esso verra' collocato in memoria nelle stesse posizioni in cui si trovava in fase di compilazione con la differenza del segmento che sara' definito dal DOS nella cosi detta fase di Rilocazione.

E' importante ricordare ora le dimensioni dei file che eseguono tutti lo stesso programma ma che sono stati scritti in linguaggi diversi.
Il file che abbiamo esaminato scrive sullo schermo la frase: Ciao a tutti.
Abbiamo visto sia il listato in Assembly per il file COM e lo stesso per il file EXE.
Il file in basic si limita ad una sola riga:
print"ciao a tutti"

Ebbene il file in forma assoluta ciacom.com occupa 35 byte
ciaoexe.exe occupa 566 byte
ciaobas.exe occupa 12.743 byte
Perche' queste differenze ?
ciaocom.com e' codice puro e non contiene nulla ad di fuori dei codici binari eseguibili e la frase Ciao a tutti.
ciaoexe.exe sempre scritto in Assembly alla lunghezza dei codici deve sommare l' header di 512 byte
ciaobas.exe scritto in linguaggio ad alto livello contiene tutte le informazioni , librerie ecc atte al funzionamento del programma.

I file generati dall'assemblatore sono piu' corti, piu' veloci ma di difficile e lunga scrittura
I programmi scritti in Basic, una volta compilati, occupano molto spazio ma la loro scrittura e' piu' vicina al nostro modo di pensare e consentono di scrivere grandi quantita' di codice in minor tempo senza perdere le prerogative di affidabilita' del programma finito.