[Risolto][C] Little-endian vs Big-endian

Linguaggi di programmazione: php, perl, python, C, bash e tutti gli altri.
Scrivi risposta
cuccagna
Scoppiettante Seguace
Scoppiettante Seguace
Messaggi: 423
Iscrizione: giovedì 26 marzo 2009, 15:50

[Risolto][C] Little-endian vs Big-endian

Messaggio da cuccagna »

Salve,
devo implementare una procedura per convertire da un sistema all'altro come da titolo
Ma guardando in rete e non sono un po' confuso e ho letto anche cose contrastanti: vorrei conferma
Mettiamo di avere una macchina con parole di memoria a 32 bit
Si prenda come esempio il valore esadecimale 0xA1B245C7
Big-endian memorizza in memoria A1 poi B2 poi 45 e poi C7
Little-endian memorizza in memoria C7 poi 45 poi B2 poi A1
E' giusto fin qui?
Facciamo finta che questa sia la prima parola di memoria con indirizzo 0 e che questa macchina permetta l'accesso anche al singolo byte
Se come indirizzo metto 1 nei due casi cosa mi verra' tornato?
Big-endian con indirizzo 1 torna B2?
Little-endian con indirizzo 1 torna B2 pure?
E' giusto?

Grazie
Ultima modifica di cuccagna il lunedì 6 ottobre 2014, 11:29, modificato 1 volta in totale.
Avatar utente
Claudio_F
Entusiasta Emergente
Entusiasta Emergente
Messaggi: 1463
Iscrizione: lunedì 28 maggio 2012, 18:49
Desktop: Mate/Gnome
Distribuzione: Ubu22.04

Re: [C]Little-endian vs Big-endian

Messaggio da Claudio_F »

cuccagna [url=http://forum.ubuntu-it.org/viewtopic.php?p=4661861#p4661861][img]http://forum.ubuntu-it.org/images/icons/icona-cita.gif[/img][/url] ha scritto:Se come indirizzo metto 1 nei due casi cosa mi verra' tornato?
Big-endian con indirizzo 1 torna B2?
Little-endian con indirizzo 1 torna B2 pure?
'B2' in big endian
'45' in little endian
:ciao:
cuccagna
Scoppiettante Seguace
Scoppiettante Seguace
Messaggi: 423
Iscrizione: giovedì 26 marzo 2009, 15:50

Re: [C]Little-endian vs Big-endian

Messaggio da cuccagna »

ok capito
ma ho un dubbio ancora
ho un libro tanenbaum che dice
ho il valore 21 in esadecimale è a 32 bit
0x00000015

big endian dovrebbe diventare
0x00000015
little endian
0x15000000

invece tanenbaum dice che in entrambi i casi viene memorizzato
0x00000015

e quest ultima cosa proprio non la capisco
Avatar utente
Claudio_F
Entusiasta Emergente
Entusiasta Emergente
Messaggi: 1463
Iscrizione: lunedì 28 maggio 2012, 18:49
Desktop: Mate/Gnome
Distribuzione: Ubu22.04

Re: [C]Little-endian vs Big-endian

Messaggio da Claudio_F »

Facciamocelo dire da Python:

Codice: Seleziona tutto

>>> import struct

>>> ['%02X'%ord(n) for n in struct.pack('>I', 0x00000015)]  # big-e
['00', '00', '00', '15']

>>> ['%02X'%ord(n) for n in struct.pack('<I', 0x00000015)]  # little-e
['15', '00', '00', '00']
Forse il libro è sbagliato, o sta dicendo qualcos'altro? Non va confuso valore con codifica/rappresentazione. Il valore è una cosa astratta (ventuno), viene codificato in binario con 32 bit, e questi 32 bit vengono raggruppati in quattro bytes ordinabili in due modi diversi.

Se si ragiona a livello di valori, allora in entrambi i casi abbiamo memorizzato il valore ventuno (la codifica è una convenzione), se si lavora a livello di codifica fisica allora abbiamo due diverse sequenze di bytes.


Più o meno la stessa cosa quando si parla di caratteri, i caratteri sono cose astratte, la loro codifica in bytes una convenzione:

Codice: Seleziona tutto

#include <stdio.h>
#include <string.h>
void main(void){
    unsigned char s[] = "coccod€";
    int slen = strlen(s);
    printf("Stringa = %s\n", s);
    printf("Bytes = %d\n", slen);
    int i = 0;
    for (; i<slen; i++) printf("%3d\n", s[i]);
}

Codice: Seleziona tutto

Stringa = coccod€
Bytes = 9
 99
111
 99
 99
111
100
226
130
172
:ciao:
cuccagna
Scoppiettante Seguace
Scoppiettante Seguace
Messaggi: 423
Iscrizione: giovedì 26 marzo 2009, 15:50

Re: [C]Little-endian vs Big-endian

Messaggio da cuccagna »

Credo forse, di avere capito in parte l'inghippo.
Ho il valore 21 e viene rappresentato in Big-endian come
00 00 00 15 in esadecimale
dove il primo 00 sta all'indirizzo generico n
Quindi 15 stara' all'indirizzo n+3
Lo stesso valore in little-endian il testo lo propone rappresentato ancora come
00 00 00 15
ma solo perché 15 sta all'indirizzo n e il primo 00 all'indirizzo n+3
Ma adesso il dubbio e' il seguente:
Il testo proponr anche la rappresentazione di una stringa diciamo SMIT (ogni carattere 1 byte)
In Big-endian e' dice il testo
S M I T
In Little-endian divebta secondo il testo
T I M S
sempre seguendo quanto detto sopra per il valore numerico riguardo gli indirizzi

Ma ragionandoci su SMIT in Little-endian dovrebbe essere T I M S
ma poi rappresentato secondo la convenzione del testo per cui il byte con indirizzo piu' basso
sta a destra anziché a sinistra (solo per la memorizzazione little-endian cio')
la stringa andrebbe memorizzata come S M I T
Quindi proprio non riesco a comprendere :muro:

Spero di essere stato chiaro anche se il ragionamento puo' sembrare molto contorto se non addirittura oscuro
antex
Prode Principiante
Messaggi: 85
Iscrizione: mercoledì 14 marzo 2012, 20:59

Re: [C]Little-endian vs Big-endian

Messaggio da antex »

Quale libro è esattamente? A che pagina?
cuccagna
Scoppiettante Seguace
Scoppiettante Seguace
Messaggi: 423
Iscrizione: giovedì 26 marzo 2009, 15:50

Re: [C]Little-endian vs Big-endian

Messaggio da cuccagna »

architettura dei calcolatori un approccio strutturale
edizione 6
autori tanenbaum e austin
pagine 77-78
Avatar utente
Claudio_F
Entusiasta Emergente
Entusiasta Emergente
Messaggi: 1463
Iscrizione: lunedì 28 maggio 2012, 18:49
Desktop: Mate/Gnome
Distribuzione: Ubu22.04

Re: [C]Little-endian vs Big-endian

Messaggio da Claudio_F »

Il testo proponr anche la rappresentazione di una stringa diciamo SMIT (ogni carattere 1 byte)
In Big-endian e' dice il testo
S M I T
In Little-endian divebta secondo il testo
T I M S
Credo che la distinzione little/big sia applicabile solo a dati multibyte, e i caratteri codificati in ASCII (1 byte per carattere) non lo sono.

Cito da wikipedia: "Questa differenziazione non riguarda né la posizione dei bit all'interno del byte (nel qual caso si parla di ordine dei bit) né le posizioni dei caratteri in una stringa. Ha invece importanza nell'interpretazione (o decodifica) delle codifiche multi-byte di stringhe di caratteri (ad esempio: la codifica UTF-16 dello standard unicode)."

La cosa è evidente anche da questa struttura dati, i singoli bytes sono semplicemente consecutivi, mentre per i dati multibyte (a 16 e 32 bit) la endianness è importante:
Immagine

Nota che anche il concetto "a destra" o "a sinistra" è solo una rappresentazione convenzionale, la realtà fisica è solo quella degli indirizzi di memoria:
- il byte più significativo di un dato multibyte in big-endian viene scritto all'indirizzo inferiore
- il byte più significativo di un dato multibyte in little-endian viene scritto all'indirizzo superiore
:ciao:
cuccagna
Scoppiettante Seguace
Scoppiettante Seguace
Messaggi: 423
Iscrizione: giovedì 26 marzo 2009, 15:50

Re:[RISOLTO] [C]Little-endian vs Big-endian

Messaggio da cuccagna »

Finalmente riesco a capire.
Quindi little o big, endian fa differenza solo per i dati multibyte. Se ho una stringa codificata in ASCII (1 byte per carattere) la rappresentazione in memoria non cambia.
Anche la puntualizzazione fatta sulla memoria e' importante anche se sapevo gia' fosse cosi' .
Il libro suddetto , non so se per via della traduzione dell'originale, su questo particolare argomento e' poco chiaro nonché approssimativo
Grazie mille
Che il Signore te lo renda
antex
Prode Principiante
Messaggi: 85
Iscrizione: mercoledì 14 marzo 2012, 20:59

Re: [C]Little-endian vs Big-endian

Messaggio da antex »

Claudio_F [url=http://forum.ubuntu-it.org/viewtopic.php?p=4662128#p4662128][img]http://forum.ubuntu-it.org/images/icons/icona-cita.gif[/img][/url] ha scritto:
Il testo proponr anche la rappresentazione di una stringa diciamo SMIT (ogni carattere 1 byte)
In Big-endian e' dice il testo
S M I T
In Little-endian divebta secondo il testo
T I M S
Nel testo, se noti, cambia solo il modo in cui la sequenza ti viene rappresentata graficamente: nel primo caso (big endian) il numero d'ordine dei caratteri aumenta verso destra, nel secondo (little endian) verso sinistra. Quindi la rappresentazione in memoria è esattamente la stessa: per prima la 'S' e alla fine la 'T' (anzi, la 'H' finale di SMITH, che continua alla word successiva).

Inoltre, lì si parla di sequenze di caratteri, ma per gli interi il discorso è diverso.

Nella rappresentazione big-endian, la numerazione cresce verso destra perché è la modalità che si usa nelle reti, in cui si immagina un unico flusso di byte che scorre di continuo verso sinistra (nuovi byte aggiunti a destra). Quindi:

Codice: Seleziona tutto

0x00 0x01 0x02 0x03 0x04 0x05 0x06 0x07 0x08 0x09 0x0A eccetera
La little-endian viene invece usata ormai in praticamente tutti i computer di uso comune (se non altro perché è quella della Intel). Puoi immaginarla come una sequenza verticale di word che cresce verso il basso, ciascuna delle quali è una riga di (tipicamente) 4 byte il cui numero d'ordine aumenta verso sinistra. Il risultato è una rappresentazione della memoria in cui gli indirizzi crescono come nella scrittura araba (da destra verso sinistra, e poi si continua alla riga sotto).

Con queste due convenzioni, l'intero 0x1234 lo vedi in entrambi i casi esattamente così (diciamo, nella sua rappresentazione "naturale").

Un'altra cosa a cui fare attenzione è che il discorso big/little-endian vale solo per la rappresentazione dei dati in memoria. Una volta che hai letto un intero dalla memoria e stai lavorando su un registro (per esempio per fare shift a destra o a sinistra) la rappresentazione è sempre quella "naturale": non ci sono più "indirizzi".
Scrivi risposta

Ritorna a “Programmazione”

Chi c’è in linea

Visualizzano questa sezione: UbuNuovo e 10 ospiti