ECL Format: differenze tra le versioni

Da Zulu Hotel Italia - Time Warp.
(Fine Istruzioni -codice 00 0F)
(Istruzioni - codice 02 00)
Riga 42: Riga 42:
  
 
==Istruzioni - codice 02 00==
 
==Istruzioni - codice 02 00==
Il blocco segue la struttura sopra citata: nell'intestazione è indicata la lunghezza del blocco in bytes. Segue un intero che indica nuovamente la lunghezza del blocco meno i 4 bytes che compongono l'intero stesso, per un totale di 10 bytes di intestazione.
+
ATTENZIONE!!! È probabile che questa sezione contenga ancora molti errori o imprecisioni
 +
Il blocco segue la struttura sopra citata: nell'intestazione è indicata la lunghezza del blocco in byte. Segue un intero che indica nuovamente la lunghezza del blocco meno i 4 byte che compongono l'intero stesso, per un totale di 10 byte di intestazione.
  
I successivi bytes rappresentano le istruzioni stesse.
+
I successivi byte rappresentano le istruzioni stesse.
  
Un'istruzione è composta da un numero variabile di bytes:
+
Un'istruzione è composta da un numero variabile di byte. Il 1° byte, indica il codice istruzione.
* Il 1° byte, indica '''forse''' il codice istruzione (01 per la chiamata ad una funzione interna?)
+
 
* 5 bytes ripetuti per ogni argomento passato all'istruzione. Ad ogni istruzione viene passato almeno un argomento: se l'istruzione non accetta argomenti, viene comunque passata una NULL string:
+
===elementi===
** byte 1/5: Il tipo di argomento passato: 00 = intero, 01 = float, 02 = stringa
+
All'interno di una istruzione, si possono trovare uno o più dei seguenti elementi che si ripetono, tutti a lunghezza fissa:
** byte 2-4/5: Puntatore all'interno del blocco delle costanti (intestazione esclusa): indica l'offset in byte dell'argomento da leggere. È da notare che le stringhe possono non essere lette dall'inizio: ad esempio, una stringa "abc" può essere usata come stringa "bc" semplicemente puntando al secondo carattere anziché all'inizio della stringa. Rappresentato come intero con soli 3 byte.
+
* intero3 (3 byte): Si tratta di un intero che ha lo stesso formato dell'intero definito precedentemente, ma manca del byte più significativo, che si assume essere sempre 00.
** byte 5/5: il significato è ancora da decifrare; 00, 01, 02
+
* puntatore (4 byte):
* 3 bytes: indica a quale funzione all'interno del blocco usage si sta facendo riferimento. Non è ancora chiaro perché venga ripetuto per ogni argomento: nel caso siano presenti più argomenti, il valore corretto sembra essere quello riportato nell'ultimo di questi.
+
** byte 1: Il tipo di argomento: 00 = intero, 01 = float, 02 = stringa, aggiungendo 32 se si tratta di una variabile
 +
** byte 2-4: Se il byte precedente indica una costante, è l'offset all'interno del blocco delle costanti (intestazione esclusa): indica la posizione in byte dell'argomento da leggere. È da notare che le stringhe possono non essere lette dall'inizio: ad esempio, una stringa "abc" può essere usata come stringa "bc" semplicemente puntando al secondo carattere anziché all'inizio della stringa. Se il byte precedente indica invece una variabile, è l'ID univoco della variabile. Rappresentato come intero3.
 +
 
 +
===istruzione 01: chiamata a una funzione interna===
 +
* 5 byte ripetuti per ogni argomento passato all'istruzione. Ad ogni istruzione viene passato almeno un argomento: se l'istruzione non accetta argomenti, viene comunque passata una NULL string come costante:
 +
** byte 1-4: puntatore
 +
** byte 5: indica a quale funzione all'interno del blocco usage si sta facendo riferimento. Non è ancora chiaro perché venga ripetuto per ogni argomento: nel caso siano presenti più argomenti, il valore corretto sembra essere quello riportato nell'ultimo di questi.
 +
* 3 byte: 2F 00 00
 
* 1 byte: indica a quale blocco usage fa riferimento l'istruzione (00 solitamente è ''basic'', 01 ''basicio'' e 02 quello indicato dalla prima direttiva "use" del sorgente)
 
* 1 byte: indica a quale blocco usage fa riferimento l'istruzione (00 solitamente è ''basic'', 01 ''basicio'' e 02 quello indicato dalla prima direttiva "use" del sorgente)
* 5 bytes: 03 19 00 00 00
+
* 5 byte: 03 19 00 00 00
 +
 
 +
===istruzione 08: assegnazione di un valore ad una variabile===
 +
* 1 byte: 2B
 +
* 3 byte: ID variabile univoco, rappresentato come intero3.
 +
* 4 byte: puntatore alla costante da cui assegnare il valore
 +
* 5 byte: 02 08 00 00 00
 +
* 5 byte: 03 19 00 00 00
  
===terminatore===
+
===istruzione 0F: terminatore===
I 5 bytes 0F 20 00 00 00 sembrano chiudere sempre il blocco istruzioni
+
I 5 byte 0F 20 00 00 00 sembrano chiudere sempre il blocco istruzioni
  
 
==Costanti - codice 03 00==
 
==Costanti - codice 03 00==

Versione delle 03:55, 23 feb 2015

Codifica dei tipi

All'interno del file, sono condificati dati di più tipi primitivi a cui si farà riferimento successivamente. Le codifiche finora individuate sono:

  • stringa a lunghezza fissa: La lunghezza è indicata preventivamente all'interno del blocco che ne fa uso o altrove. È rappresentata da un numero fisso di bytes, dove quelli non utilizzati sono impostati a NULL.
  • stringa a lunghezza variabile: Si tratta di un numero variabile di bytes stringa di cui l'ultimo è sempre NULL e rappresenta la fine della stringa stessa
  • numero intero: gli interi sono codificati sempre come 4 bytes, ordinati dal meno al più significativo (quindi invertiti, da un punto di vista algebrico). Sono sempre signed: il valore massimo per un intero è 0x7FFFFFFF, rappresentato come FF FF FF 7F. I valori negativi sono rappresentati partendo da FF FF FF FF che significa -1 e poi sottraendo la rappresentazione del valore come se fosse (intero - 1); ad esempio -255 è rappresentato come 01 FF FF FF.
  • numeri a virgola mobile (float): i numeri a virgola mobile sono codificati sempre come 8 bytes (da chiarire in che formato, probabilmente 4 bytes base + 4 bytes esponente)

Header

L'header sembra essere fisso: 43 45 02 00 00 00, e sono i primi 6 bytes di ogni file.

I primi due bytes rappresentano il magic number del formato ("CE").

Il terzo byte probabilmente è il numero di versione (02 per POL093).

Struttura

Successivamente all'header, il file ECL sembra avere una struttura a blocchi. Di seguito sono elencati quelli noti, riportati nello stesso ordine in cui compariranno all'interno del file.

Ciascun blocco inizia con 6 (2+4) bytes. Di questi 6 bytes, i primi 2 rappresentano il codice del blocco, mentre i successivi 4 rappresentano, sotto forma di intero, la lunghezza del blocco, in bytes, non conteggiando i 6 bytes dell'intestazione stessa.

Fa eccezione il codice 01 00 per cui la lunghezza viene indicata sempre come 0.

Program - codice 04 00

Questo blocco definisce la direttiva program.

Non è sempre presente: ad esempio, non è usato nello script generale di startup start.ecl.

I primi 6 bytes sono 04 00 - 10 00 00 00, seguono 16 bytes di cui solo il primo sembra essere usato ed indica il numero di argomenti accettati dal blocco program (01, 02, etc...).

Gli altri bytes sono sempre lasciati a NULL.

Usages - codice 01 00

I file .em contenenti le funzioni di sistema importati con la direttiva use sono specificate immediatamente dopo l'header. Ogni blocco use ha una dimensione variabile.

I primi 6 bytes sono 01 00 00 00 00 00, segue un blocco di 13 bytes così suddiviso:

  • bytes 1-9: contengono il nome dell'usage sotto forma di stringa a lunghezza fissa
  • byte 10: indica il numero di funzioni utilizzate da questo file
  • bytes 11-13: sempre NULL

Segue la lista delle funzioni utilizzate da questo file, sotto forma 34 bytes ripetuti per il numero di volte indicato dal byte 10. Di questi 34 bytes, i primi 33 rappresentano una stringa a lunghezza fissa contenente il nome della funzione, mentre l'ultimo byte indica il numero di parametri accettati dalla funzione stessa.

"basic" e "basicio" sembrano essere sempre i primi due usages e sono inclusi implicitamente, e ribaditi quindi nel file ECL, anche se non dichiarati nello script sorgente.

Istruzioni - codice 02 00

ATTENZIONE!!! È probabile che questa sezione contenga ancora molti errori o imprecisioni

Il blocco segue la struttura sopra citata: nell'intestazione è indicata la lunghezza del blocco in byte. Segue un intero che indica nuovamente la lunghezza del blocco meno i 4 byte che compongono l'intero stesso, per un totale di 10 byte di intestazione.

I successivi byte rappresentano le istruzioni stesse.

Un'istruzione è composta da un numero variabile di byte. Il 1° byte, indica il codice istruzione.

elementi

All'interno di una istruzione, si possono trovare uno o più dei seguenti elementi che si ripetono, tutti a lunghezza fissa:

  • intero3 (3 byte): Si tratta di un intero che ha lo stesso formato dell'intero definito precedentemente, ma manca del byte più significativo, che si assume essere sempre 00.
  • puntatore (4 byte):
    • byte 1: Il tipo di argomento: 00 = intero, 01 = float, 02 = stringa, aggiungendo 32 se si tratta di una variabile
    • byte 2-4: Se il byte precedente indica una costante, è l'offset all'interno del blocco delle costanti (intestazione esclusa): indica la posizione in byte dell'argomento da leggere. È da notare che le stringhe possono non essere lette dall'inizio: ad esempio, una stringa "abc" può essere usata come stringa "bc" semplicemente puntando al secondo carattere anziché all'inizio della stringa. Se il byte precedente indica invece una variabile, è l'ID univoco della variabile. Rappresentato come intero3.

istruzione 01: chiamata a una funzione interna

  • 5 byte ripetuti per ogni argomento passato all'istruzione. Ad ogni istruzione viene passato almeno un argomento: se l'istruzione non accetta argomenti, viene comunque passata una NULL string come costante:
    • byte 1-4: puntatore
    • byte 5: indica a quale funzione all'interno del blocco usage si sta facendo riferimento. Non è ancora chiaro perché venga ripetuto per ogni argomento: nel caso siano presenti più argomenti, il valore corretto sembra essere quello riportato nell'ultimo di questi.
  • 3 byte: 2F 00 00
  • 1 byte: indica a quale blocco usage fa riferimento l'istruzione (00 solitamente è basic, 01 basicio e 02 quello indicato dalla prima direttiva "use" del sorgente)
  • 5 byte: 03 19 00 00 00

istruzione 08: assegnazione di un valore ad una variabile

  • 1 byte: 2B
  • 3 byte: ID variabile univoco, rappresentato come intero3.
  • 4 byte: puntatore alla costante da cui assegnare il valore
  • 5 byte: 02 08 00 00 00
  • 5 byte: 03 19 00 00 00

istruzione 0F: terminatore

I 5 byte 0F 20 00 00 00 sembrano chiudere sempre il blocco istruzioni

Costanti - codice 03 00

In questo blocco, l'ultimo del file, sono contenute le costanti usate all'interno del file stesso.

L'inizio del blocco è indicato dai 6 bytes 03 00 XX XX XX XX: dove XX rappresenta la lunghezza del blocco, in formato intero: sembra sempre uguale all'intero indicato dai successivi 4 bytes + 4.

I successivi 4 bytes rappresentano un intero che indica il numero di bytes da cui è composta la sezione delle costanti + 1 (ovvero indica 1 per 0 bytes, 2 per 1 byte, etc...).

Ad esempio, un blocco costanti contenente 4 bytes di dati puri inizierà con: 03 00 - 09 00 00 00 - 05 00 00 00.

Possono essere presenti i seguenti tipi di dati:

  • stringhe a lunghezza variabile
  • interi
  • float