Little vs. Big Endian: Auswirkungen von Shift Operationen etc. ?



  • Hallo Forum,

    ich möchte um Info bitten bzgl. der Auswirkungen der Umstellung von Big Endian auf Little Endian (aufgrund Prozessor/Compilerwechsel)

    Was passiert etwa bei Shift Operationen, z.B.

    unsigned short int b, a = 0x80;  /* Variablen mit 2 Bytes */
    b = (a << 1);
    

    Was steht dann in variable b ?

    Bei Big Endian ist es (binär) 0000000100000000
    Bei Litte Endian vermute ich:
    Vor der << Operation: 1000000000000000, nach der << Operation: 0000000000000001

    Ist meine Vermutung richtig?

    D.h. doch auch, dass Operationen wie z.B. das Ausblenden des high bytes bei Big Endian mit a & 0x00ff dann entsprechen für Little Endian angepasst werden müssen (a & 0xff00) !?
    Es müssen also alle Operationen angepasst werden, die das high byte an einer bestimmten Stelle erwarten !?

    Danke für jede Aufschlauung!

    Gruß
    Sergeant



  • Big/Little Endian betreffen hauptsächlich die Byte-Reihenfolge beim Speichern (RAM/Festplatte etc.).
    In den CPU Registern ist das wiederum wegabstrahiert...
    Das heißt <<, >>, &, | etc. machen das richtige, egal welche Endianess vorliegt.

    Unterschiede musst du nur machen, wenn du z.B. einen int* in einen char* castest und damit auf die einzelnen Bytes zugreifen möchtest.
    Mit & 0xFF bekommst du quasi immer das Least Significant Byte, während bytes[0] von der Architektur abhängig ist.



  • Hallo DrakoXP,

    ist die Sortierung in einer mehrbyte-Variablen dann nicht auch anderst?

    Habe im Internet folgenden Code gefunden:

    bool isLittleEndian()
    {
        short int number = 0x1;
        char *numPtr = (char*)&number;
        return (numPtr[0] == 1);
    }
    

    Der Code setzt doch voraus, das die 'Sortierung' in den Variablen auch eine andere ist zwischen Little und Big Endian !?
    Ich nehme an, im obigen Beispiel wäre bei Big Endian numPtr[1] == 1)!?

    Oder anderst gefragt: Was steht am Ende in b bei Big Endian, was bei Little Endian:

    short int b, a=0x1122;
    b=a&0xff00;
    

    Danke
    MfG
    Sergeant



  • tecranovis schrieb:

    Ich nehme an, im obigen Beispiel wäre bei Big Endian numPtr[1] == 1)!?

    Korrekt. Wie ich bereits schrieb, ist das nur relevant, wenn du per Byte-Zeiger auf die einzelnen Bytes zugreifst.

    BE: 0000000000000001
    LE: 0000000100000000

    Beides entspricht einer 1.
    Wenn ich jetzt allerdings mit den shorts shifte, odere, unde, etc. so ist das Ergebnis unabhängig von der zugrundeliegenden Architektur mathematisch korrekt.
    Ein << 8 würde also ergeben:

    BE: 0000000100000000
    LE: 0000000000000001

    Beide entsprechen wiederum einer 256, was nunmal 1 << 8 ist.

    PS:

    In b steht in beiden Fällen 0x1100 wie erwartet.
    Auch bei Literalen ist eben die Bytereihenwolge Wurst.
    Lediglich als Byte-Array betrachtet bekommt man LE { 0x11, 0x00 } und BE { 0x00, 0x11 }.



  • Hallo DrakoXP,

    danke für deine informativen Antworten.

    Ich hatte die Endian Order bislang immer als irgendwie C inhärent betrachtet, was sie aber nicht ist.
    Bis auf Spezialfälle ist die Byte Order demnach für den Programmierer belanglos.

    Scheint letztlich auch logisch, sonst könnte man C-Sourcecode oder Übungsaufgaben nicht in 'Trockenübung' analysieren/lösen, sondern nur mit Kenntnis der Prozessoreigenschaft (Endian Order).


Anmelden zum Antworten