www.errorediridondanzaciclicodotcom

  • Home
  • Endianness
  • BACK P.P.

  • Gulliver, le uova e i Byte

    C'era una volta il figlio di un re che, nel mangiare un uovo, si tagliò il dito con il guscio. Ciò accadde perché iniziò dalla parte più larga dell'uovo, come era la tradizione di quel paese. Il re, molto ansioso, decise allora di proibire a tutti i sudditi di aprire le uova dalla parte più larga. Ma in una dalle due isole che costituivano questo paese, Blefuscu, si rifugiarono gli oppositori del regime che, volendo mantenere la tradizione, continuarono ad aprire le uova dalla parte più larga. Iniziò cosi una guerra sanguinosa per colpa delle uova tra le due isole.....(I viaggi di Gulliver).

    Le uova hanno due estremità, una più stretta (Little Endian) e una più larga (Big Endian).

    Tutt'oggi sussiste questa contrapposizione, ma non a Lilliput, bensì in informatica.

    Questi due termini si utilizzano per identificare due sistemi contrapposti per memorizzare i Byte secondo un ordine.

    Prendiamo un Byte (8 bit) e, per semplicità, rappresentiamolo in formato esadecimale: A2hex.
    Ricordo che il formato esadecimale utilizza i simboli per identificare quattro bit, quindi

    A = 10dec = 1010bin   e    2 = 2dec = 0010bin

    Se consideriamo il numero A2hex singolarmente, esso rappresenta il numero 162dec (1010 0010) e corrisponde ad un Byte (8 bit).

    Quando il computer compila ad esempio un programma che andrà a scrivere in memoria (si intende la RAM) il numero 162dec, cioè A2hex, troverà una porzione di memoria di un Byte nella quale metterà questo numero tal quale.
    Se invece di un Byte dobbiamo scriverci una stringa più lunga allora le cose si complicano.

    Per semplicità consideriamo un'architettura di un computer basata su 32bit, cioè le informazioni sono immagazzinate nei registri con questo formato e quindi essi devono essere lunghi massimo 32bit (si chiama Word questa stringa di 32bit).

    Questi 32bit sono esattamente 4 Byte (1 Byte = 8bit). L'ordine dei Byte di cui parlo qui è proprio l'ordine in cui ciascuno di questi 4 Byte costituenti la word viene scritto in memoria (si scrive in memoria ad esempio quando portiamo un registro in essa).

    Riprendendo l'esempio di prima, completiamo il Byte fino a una word completa:

    A2 B3 C4 D5 (10100010 10110011 11000100 11010101).


    Come scriverà questa word in memoria il nostro pc?

    Prima di proseguire è utile spiegare cosa sono il MSB e il LSB. Questi acronimi inglesi rappresentano il Byte più (Most) o meno (Less) significativo di una stringa (la nostra word).

    Il Byte più significativo è quello di ordine superiore in senso binario.

    Attenzione, per capire l'ordine dei Byte bisogna osservare come vengono scritte le stringhe in binario, cioè da DESTRA verso SINISTRA.
    Il primo bit (il singolo bit, non il Byte!) a destra varrà 0 o 1, il secondo varrà 0 o 2 (2^1), il terzo 0 o 4 (2^2), e così via.
    Quindi se abbiamo una stringa di 32bit, il bit più significativo, msb (most significant bit), è il 32esimo (2^31). Il bit meno significativo (lsb) sarà invece il primo a destra (2^0).


    Lo stesso vale per i Byte: il BPS (Byte Più Significativo o MSB in inglese) sarà il quarto nella nostra word, quello più a sinistra mentre il BMS (LSB) sarà il primo a destra.


    Quindi nell'esempio sopra il Byte più significativo è quello a sinistra, A2 mentre il Byte meno significativo è quello a destra, D5.

    Vediamo ora come rappresentare una porzione di memoria.

    La memoria di un computer si può paragonare ad un casellario in cui si mettono i dati, con ogni casella delle dimensioni di un Byte. Ogni piano del casellario è fatto da quattro caselle (nel nostro esempio) per mettere 4 Byte, cioè una word di 32bit.
    Questa struttura in cui ogni word è considerata come l'insieme di 4 Byte è spiegata dalla richiesta di allineamento, un termine che non voglio approfondire qui.

    Pensiamo di dover archiviare i documenti contabili di diversi anni. Ogni anno è diviso in 4 scatole (ogni scatola un gruppo di documenti) numerate da 1 a 4.
    Il nostro sistema di archiviazione sarà differente se per ogni anno metteremo la scatola 1 nella casella di destra e la 4 a sinistra oppure viceversa.
    Lo stesso vale per la memoria di un computer. Ogni indirizzo di memoria rappresenta una casella e quattro caselle adiacenti rappresentano una word (4Byte = 32bit, sempre nel nostro esempio!).

    Il computer inserisce in memoria una word dopo l'altra, incrementando gli indirizzi corrispondenti di 4 blocchi alla volta (se avessimo un sistema a 64bit avremmo 8 blocchi alla volta per ogni word).
    Ogni blocco, cioè ogni singolo indirizzo, rappresenta un Byte. Quale dei quattro Byte della word verrà inserito per primo costituisce la tipologia utilizzata, Big Endian o Little Endian.


    Nel disegno sopra ho stilizzato uno spazio di memoria. All'estrema destra vedete gli indirizzi (solo 2 dei tanti) di memoria che possono essere assegnati alle singole word. Nella colonna centrale invece vedete i reali indirizzi di memoria che apparterranno al singolo Byte. Questa numerazione, tipica di quasi tutti i sitemi informatici, viene chiamata Byte addressing e significa appunto indirizzamento per Byte. In sostanza, se vogliamo mettere una word in memoria, ad esempio nel primo spazio libero, non scriveremo tutta la word ma un Byte alla volta (nel nostro esempio di word con 32bit, cioè 4 Byte, avremo bisogno di quattro spazi differenti e consecutivi).
    Quindi il primo indirizzo libero che utilizzeremo, 0x0000, in realtà corrisponde al primo Byte della word memorizzata. La seconda word memorizzata non avrà indirizzo 0x0001 ma 0x0004. Ogni indirizzo di memoria corrisponde quindi ad un Byte della word.

    A questo punto vediamo come entra in gioco l'endianness utilizzato dal compiler.


    Nel disegno sopra vedete una word, D3C2B1A0, scritta in esadecimale. Ricordo che si scrive da destra verso sinistra e il Byte più significativo è D3 mentre quello meno significativo è A0. Il compiler che scriverà in memoria questa word, in caso di un ordine dei Byte di tipo Big Endian, partirà dal Byte più significativo a scrivere e quindi metterà questo Byte (D3) nel primo spazio libero (0x0000).


    Nel disegno sopra invece vedete una scrittura in memoria di tipo Little Endian, per la quale verrà scritto prima il Byte meno significativo (A0).

    Quanto sopra fa riferimento ad una particolare architettura basata su Byte di 8 bit e su word di 32bit ma ci sono e ci sono stati esempi differenti. Anche il concetto di Byte-addressing è specifico di una tipologia perchè esiste anche il word-addressing. Inoltre il Big e Little Endian non sono soli, esiste anche il Middle Endian.