• Non ci sono risultati.

3.2 Formato del file eseguibile (.RXE)

3.2.2 Dataspace

Il segmento Dataspace del file eseguibile include tutte le informazioni necessarie per inizializzare il dataspace durante la fase di attivazione di un programma, nonché le specifiche di tutti i tipi di dati e della loro disposizione, le quali sono poi necessarie durante l'esecuzione del programma stesso. Tale segmento è suddiviso, a sua volta, in tre sotto-segmenti, i quali sono presentati nella tabella seguente.

Sotto-segmento Descrizione

DSTOC Specifica dei tipi di dati e della loro posizione nel dataspace.

Dati di default statici Valori iniziali per i dati di tipo statico. Dati di default dinamici Valori iniziali per i dati di tipo dinamico.

Dataspace Table of Contents (DSTOC)

La DSTOC descrive i tipi di dati utilizzati durante l'esecuzione del programma e la loro collocazione all'interno del dataspace del programma stesso. Tale struttura può essere definita come la “mappa” che viene utilizzata dalla virtual machine del firmware per allocare i dati in RAM, ed i suoi campi sono utilizzati come argomenti delle istruzioni che operano sui dati. Per ulteriori dettagli sulle istruzioni consultare la sottosezione 3.2.4 di questo elaborato.

E' utile ricordare ancora una volta che la DSTOC è costruita al momento della compilazione di un programma e che essa non cambia durante l'esecuzione dello stesso.

La DSTOC è organizzata come un array i cui elementi sono dei record di lunghezza fissa pari a 4 byte ed esemplificati nella tabella seguente.

DSTOC Record

Campo Tipo Flags Data Descriptor

Bit 0..7 8..15 16..31

Tabella 3.6: Struttura di un record della DSTOC

Nella tabella soprastante il campo relativo al Tipo contiene un semplice codice numerico intero; i valori assumibili da tale campo sono i seguenti:

0: TC_VOID - usato per gli elementi non utilizzati nel codice;

1: TC_UBYTE - numero intero di 8 bit senza segno;

2: TC_SBYTE - numero intero di 8 bit con segno;

3: TC_UWORD - numero intero di 16 bit senza segno;

4: TC_SWORD - numero intero di 16 bit con segno;

5: TC_ULONG - numero intero di 32 bit senza segno;

6: TC_SLONG - numero intero di 32 bit con segno;

7: TC_ARRAY - array di elementi di un qualsiasi tipo;

8: TC_CLUSTER - struttura dati composta da sottotipi diversi;

9: TC_MUTEX - dato mutex per la schedulazione dei clump;

10: TC_FLOAT - numero decimale (in virgola mobile) di 32 bit con

Il campo Flags è utilizzato soltanto al momento dell'inizializzazione di un programma, ed il suo scopo è quello di segnalare se il dato a cui il record si riferisce possiede o meno un valore di default da assegnarvi. Se il campo assume il valore '1' il dato in questione è inizializzato al valore nullo; se, invece, esso assume valore '0' significa che è presente tra i dati di default un valore da assegnare a tale dato.

Il campo Data Descriptor può, invece, assumere diversi significati a seconda del tipo di dato descritto dal record della DSTOC.

Grammatica della DSTOC

La DSTOC adotta una specifica “grammatica” con regole ben precise per descrivere tutti i possibili tipi di dati. Tale grammatica segue un approccio top-down, il che significa che i tipi di dati più complessi sono definiti per mezzo di una lista ordinata di diversi record della DSTOC. Di questa categoria di dati fanno parte gli array ed i cluster; per definire ciascuno di essi, infatti, la DSTOC si serve di un primo record per indicare il tipo di dato (TC_ARRAY o TC_CLUSTER) e di altri record per specificare i tipi di dati in esso contenuti.

Le regole che vengono esposte di seguito aiutano a comprendere meglio l'approccio appena citato.

I dati di tipo numerico necessitano di un solo record nella DSTOC. Nel loro caso il campo Data Descriptor contiene un offset utile al fine di recuperare il valore del dato in RAM;

e.g.: record per dato numerico: TC_SWORD 0x00 0x0000

I dati di tipo array hanno bisogno di due (caso di array di numeri) o più record (caso di array di cluster) nella DSTOC. Il campo Data Descriptor del primo record rappresenta un offset utile per reperire il dope vector che descrive l'array medesimo. I record successivi specificano, invece, la tipologia dei dati contenuti nell'array;

e.g.: record per array di byte: TC_ARRAY 0x00 0x0200 TC_BYTE 0x00 0x0000

I dati di tipo cluster necessitano di due o più record nella DSTOC (dipende dal numero di oggetti da cui essi sono composti). Il campo Data Descriptor del primo record comunica il numero di oggetti contenuti nel cluster. I record

successivi illustrano il tipo di ogni oggetto da cui il cluster è composto.

e.g.: record per cluster contenente due numeri ed un array di numeri:

TC_CLUSTER 0x00 0x0300

TC_ULONG 0x00 0x0C00 TC_ULONG 0x00 0x1000 TC_ARRAY 0x00 0x1400 TC_SWORD 0x00 0x0000

Come un lettore perspicace avrà già intuito, le regole appena presentate possono essere impiegate ricorsivamente, così da poter definire, ad esempio, array di cluster, o cluster contenenti array; di quest'ultimo caso ve ne è un'occorrenza nell'esempio allegato all'ultima regola esposta.

E' importante precisare che i Data Descriptor, tanto dei dati numerici quanto degli array, contengono come offset un numero senza segno da 2 byte relativo ai dati presenti in RAM, ma esso viene interpretato in maniera differente nei due casi. Gli offset delle variabili e degli array sono relativi all'inizio del dataspace in RAM, e per questo motivo sono chiamati dataspace offset. Gli offset che, invece, sono successivi al record che definisce un array sono relativi all'inizio dell'array in RAM, e per questa ragione sono detti array data offset. Questa distinzione viene fatta per rendere possibile lo spostamento od il ridimensionamento degli array in RAM.

Dati di default statici

I valori di default per i dati statici sono posizionati subito dopo la DSTOC, e la composizione di questo sotto-segmento dipende interamente dai record contenuti nella DSTOC stessa. Tali valori sono memorizzati nel medesimo ordine in cui i loro record corrispondenti sono elencati nella DSTOC.

E' importante ricordare che, se il valore del campo Flags di un record della DSTOC è pari ad '1', la porzione di RAM riservata all'oggetto descritto da quel record è automaticamente inizializzata al valore '0'. Conseguenza diretta di questo modus

operandi è il fatto che la dimensione del sotto-segmento dei dati di default statici

risulta essere minore, od al massimo uguale, a quella specificata dal campo Static

Dati di default dinamici

I valori di default per i dati dinamici sono gestiti in maniera differente rispetto a quelli per i dati statici. E' utile innanzitutto ricordare che i dati dinamici sono costituiti unicamente da array. Un'altra differenza importante è che i dati di default dinamici sono una copia perfetta di tutti i valori iniziali del pool di dati dinamici del dataspace. In altre parole, i valori di default dinamici devono essere “formattati” in modo tale da poterli copiare direttamente nel segmento di RAM riservato ai dati dinamici, senza dovervi apportare alcuna modifica.

E' importante ricordare che anche il DVA è esso stesso un array, ed è quindi salvato tra i dati dinamici. Ogni dope vector nel DVA ha una valore di default, ed anche questi valori risiedono nello spazio riservato ai dati di default dinamici. Per semplicità i cosiddetti “default dope vector” sono posizionati all'inizio dei dati di default dinamici.