Domanda Cosa rende un sistema little-endian o big-endian?


Sono confuso con l'ordine dei byte di un sistema / CPU / programma.
Quindi devo fare alcune domande per chiarire la mia mente.

Domanda 1

Se uso solo il tipo char nel mio programma C ++:

void main()
{
    char c = 'A';
    char* s = "XYZ";    
}

Quindi compilare questo programma su un file binario eseguibile chiamato a.out.
Può a.out entrambi funzionano su sistemi little-endian e big-endian?

Domanda 2

Se il mio sistema Windows XP è little-endian, posso installare un sistema Linux big-endian in VMWare / VirtualBox? Cosa rende un sistema little-endian o big-endian?

Domanda 3

Se voglio scrivere un programma C ++ indipendente dall'ordine dei byte, cosa devo tenere in considerazione?


11
2018-02-11 02:30


origine


risposte:


A.out può entrambi girare su sistemi little-endian e big-endian?

No, perché praticamente due CPU così diverse da avere endianità diverse non eseguiranno lo stesso set di istruzioni. C ++ non è Java; non si compila in qualcosa che viene compilato o interpretato. Si compila l'assembly per una CPU specifica. E endian-ness fa parte della CPU.

Ma questo è al di fuori dei problemi di endian. È possibile compilare quel programma per diverse CPU e questi eseguibili funzioneranno correttamente sulle rispettive CPU.

Cosa rende un sistema little-endian o big-endian?

Per quanto riguarda C o C ++, la CPU. Diverse unità di elaborazione in un computer possono in realtà avere diversi endian (la GPU potrebbe essere big-endian mentre la CPU è little endian), ma è piuttosto raro.

Se voglio scrivere un programma C ++ indipendente per ordine byte, che cosa devo tenere in considerazione?

Finché giochi secondo le regole di C o C ++, non ti devi preoccupare dei problemi di endian.

Naturalmente, non sarà possibile caricare i file direttamente nelle strutture POD. Oppure leggi una serie di byte, fai finta che sia una serie di cortometraggi senza segno e poi elaborali come una stringa codificata in UTF-16. Tutte queste cose entrano nel regno del comportamento definito dall'implementazione.

C'è una differenza tra comportamento "non definito" e "definito dall'implementazione". Quando le specifiche C e C ++ dicono che qualcosa è "indefinito", in pratica significa che possono derivarne tutti i tipi di rottura. Se continui a farlo, (e il tuo programma non si blocca) potresti ottenere risultati incoerenti. Quando dice che qualcosa è definito dall'implementazione, otterrai risultati coerenti per quella implementazione.

Se compili per x86 in VC2010, cosa succede quando fai finta che un array di byte sia un array corto senza segno (es .: unsigned char *byteArray = ...; unsigned short *usArray = (unsigned short*)byteArray) è definito dall'implementazione. Quando si compila per le CPU big-endian, si otterrà una risposta diversa rispetto alla compilazione per le CPU little-endian.

In generale, i problemi di endian sono cose che puoi localizzare nei sistemi di input / output. Networking, lettura dei file, ecc. Dovrebbero essere presi in considerazione nelle estremità del codice base.


20
2018-02-11 02:39



Domanda 1:

A.out può entrambi girare su sistemi little-endian e big-endian?

No perché a.out è già compilato per qualsiasi architettura che mira. Non funzionerà su un'altra architettura con la quale è incompatibile.

Tuttavia, il codice sorgente per quel semplice programma non ha nulla che possa eventualmente rompersi su macchine endian diverse.

Quindi sì (la fonte) funzionerà correttamente. (beh ... a parte void main(), che dovresti usare int main() anziché)

Domanda 2:

Se il mio sistema WindowsXP è little-endian, posso installare un big-endian   Sistema Linux in VMWare / VirtualBox?

L'endianità è determinata dall'hardware e non dal sistema operativo. Quindi qualsiasi VM (nativa) installata su di essa, sarà la stessa endian dell'host. (dal momento che x86 è tutto little-endian)

Cosa rende un sistema little-endian o big-endian?

Ecco un esempio di qualcosa che si comporterà in modo diverso sul piccolo contro big-endian:

uint64_t a = 0x0123456789abcdefull;
uint32_t b = *(uint32_t*)&a;
printf("b is %x",b)

* Si noti che questo viola il rigoroso aliasing ed è solo a scopo dimostrativo.

Little Endian : b is 89abcdef
Big Endian    : b is 1234567

Su little-endian, i bit più bassi di a sono memorizzati all'indirizzo più basso. Quindi quando accedi a come numero intero a 32 bit, leggerete i 32 bit più bassi di esso. Su big-endian, leggerete i 32 bit superiori.

Domanda 3:

Se voglio scrivere un programma C ++ indipendente per ordine byte, cosa devo fare   bisogno di prendere in considerazione?

Segui semplicemente le regole C ++ standard e non fare nulla di brutto come nell'esempio che ho mostrato sopra. Evita comportamenti indefiniti, evita la punzonatura del tipo ...


8
2018-02-11 02:43



Little-endian / big-endian è una proprietà dell'hardware. In generale, il codice binario compilato per un hardware non può essere eseguito su un altro hardware, tranne che in un ambiente di virtualizzazione interpretare codice macchina ed emulare l'hardware di destinazione per esso. Ci sono CPU bi-endian (ad esempio ARM, IA-64) che dispongono di un interruttore per cambiare endianness.

Per quanto riguarda la programmazione indipendente dall'ordine dei byte, l'unico caso in cui è davvero necessario farlo è occuparsi del networking. Ci sono funzioni come ntohl e htonl per aiutarti a convertire l'ordine dei byte dell'hardware nell'ordine dei byte della rete.


3
2018-02-11 02:41



La prima cosa da chiarire è che endianness è un attributo hardware, non un attributo software / OS, quindi WinXP e Linux non sono big-endian o little endian, ma piuttosto l'hardware su cui eseguono è big-endian o little endian.

Endianness è una descrizione dell'ordine in cui i byte sono memorizzati in un tipo di dati. Un sistema che è big-endian memorizza prima il valore più significativo (letto valore più grande) e un sistema little-endian memorizza prima il byte meno significativo. Non è obbligatorio avere ogni tipo di dati uguale agli altri su un sistema in modo da poter disporre di sistemi mixed-endian.

Un programma che è little endian non funzionerebbe su un sistema big-endian, ma questo ha più a che fare con il set di istruzioni disponibile rispetto al endianness del sistema su cui è stato compilato.

Se si desidera scrivere un programma indipendente per ordine byte, è necessario semplicemente non dipendere dall'ordine dei byte dei dati.


2
2018-02-11 02:41



1: L'output del compilatore dipenderà dalle opzioni fornite e se si utilizza un cross-compiler. Per impostazione predefinita, dovrebbe essere eseguito sul sistema operativo su cui si sta compilando e non su altri (forse nemmeno su altri dello stesso tipo, non tutti i binari di Linux girano su tutte le installazioni di Linux, per esempio). Nei progetti di grandi dimensioni, questa sarà l'ultima delle tue preoccupazioni, dato che le librerie, ecc., Dovranno essere costruite e collegate in modo diverso su ciascun sistema. L'utilizzo di un sistema di costruzione appropriato (come la marca) si prenderà cura della maggior parte di questo senza che tu debba preoccuparti.

2: Le macchine virtuali astraggono l'hardware in modo tale da consentire essenzialmente a qualsiasi cosa di funzionare all'interno di qualsiasi altra cosa. Il modo in cui i sistemi operativi gestiscono la loro memoria non è importante a patto che entrambi funzionino sullo stesso hardware e supportino qualsiasi modello di virtualizzazione sia in uso. Endianità indica l'ordine dei byte; se viene letto sinistra-destra o destra-sinistra (o qualche altro formato). Alcuni hardware supportano entrambi e la virtualizzazione consente a entrambi di coesistere in quel caso (anche se non sono a conoscenza di come sarebbe utile se non fosse possibile in teoria). Tuttavia, Linux funziona su molte architetture diverse (e Windows diverse da Ixxx), quindi la situazione è più complicata.

3: Se ti scimmi con la memoria grezza, come con gli operatori binari, potresti metterti in una posizione di dipendenza da endianness. Tuttavia, la maggior parte della programmazione moderna è ad un livello più alto di questo. Come tale, è probabile che notiate se vi trovate in qualcosa che può imporre limitazioni basate sull'endianismo. Se tale è mai richiesto, è sempre possibile implementare le opzioni per entrambe le endianness utilizzando il preprocessore.


2
2018-02-11 02:46



Il endianness di un sistema determina come vengono interpretati i byte, quindi quale bit è considerato il "primo" e ciò che è considerato l'ultimo.

Devi prenderti cura di questo solo quando carichi o salvi da qualche fonte esterna al tuo programma, come il disco o le reti.


1
2018-02-11 02:39