Intel-Prozessoren (und möglicherweise einige andere) verwenden das Little-Endian-Format für die Speicherung.
Ich frage mich immer, warum jemand die Bytes in umgekehrter Reihenfolge speichern möchte. Hat dieses Format irgendwelche Vorteile gegenüber dem Big-Endian-Format?
architecture
storage
advantages
endianness
Cracker
quelle
quelle
Antworten:
So oder so gibt es Argumente, aber ein Punkt ist, dass in einem Little-Endian-System die Adresse eines bestimmten Wertes im Speicher, der als 32, 16 oder 8 Bit Breite angenommen wird, dieselbe ist.
Mit anderen Worten, wenn Sie einen Zwei-Byte-Wert im Speicher haben:
Wenn Sie diese '16' als 16-Bit-Wert (c 'short' auf den meisten 32-Bit-Systemen) oder als 8-Bit-Wert (im Allgemeinen c 'char') annehmen, wird nur der von Ihnen verwendete Abrufbefehl geändert, nicht die Adresse, die Sie abrufen von.
Auf einem Big-Endian-System mit den folgenden Angaben:
Sie müssten den Zeiger inkrementieren und dann den engeren Abrufvorgang für den neuen Wert ausführen.
Kurz gesagt: Auf Little-Endian-Systemen sind Casts ein No-Op.
quelle
Big-Endian und Little-Endian sind aus menschlicher Sicht nur "normale Ordnung" und "umgekehrte Ordnung" und nur dann, wenn all dies wahr ist ...
Das sind alles menschliche Konventionen, die für eine CPU überhaupt keine Rolle spielen. Wenn Sie Nr. 1 und Nr. 2 beibehalten und Nr. 3 umblättern, erscheint Little-Endian Leuten, die Arabisch oder Hebräisch lesen und von rechts nach links geschrieben sind, als "vollkommen natürlich".
Und es gibt andere menschliche Konventionen, die Big-Endian unnatürlich erscheinen lassen, wie ...
Damals, als ich hauptsächlich 68K und PowerPC programmierte, hielt ich Big-Endian für "richtig" und Little-Endian für "falsch". Aber seit ich mehr mit ARM und Intel arbeite, habe ich mich an Little Endian gewöhnt. Es ist wirklich egal.
quelle
OK, hier ist der Grund, wie ich ihn mir erklärt habe: Addition und Subtraktion
Wenn Sie Mehrbyte-Zahlen addieren oder subtrahieren, müssen Sie mit dem niedrigstwertigen Byte beginnen. Wenn Sie beispielsweise zwei 16-Bit-Zahlen hinzufügen, ist möglicherweise ein Übertrag vom niedrigstwertigen Byte zum höchstwertigen Byte vorhanden. Beginnen Sie also mit dem niedrigstwertigen Byte, um festzustellen, ob ein Übertrag vorliegt. Dies ist der gleiche Grund, warum Sie bei der Longhand-Addition mit der ganz rechten Ziffer beginnen. Sie können nicht von links beginnen.
Stellen Sie sich ein 8-Bit-System vor, das nacheinander Bytes aus dem Speicher abruft. Wenn das niedrigstwertige Byte zuerst abgerufen wird , kann die Addition gestartet werden, während das höchstwertige Byte aus dem Speicher abgerufen wird. Diese Parallelität ist der Grund, warum die Leistung in Little Endian auf einem solchen System besser ist. Wenn es warten müsste, bis beide Bytes aus dem Speicher abgerufen wurden, oder in umgekehrter Reihenfolge, würde es länger dauern.
Dies ist auf alten 8-Bit-Systemen der Fall. Auf einer modernen CPU bezweifle ich, dass die Bytereihenfolge einen Unterschied macht, und wir verwenden Little Endian nur aus historischen Gründen.
quelle
Mit 8-Bit-Prozessoren war es sicherlich effizienter. Sie konnten eine 8- oder 16-Bit-Operation ausführen, ohne dass ein anderer Code benötigt wurde und ohne dass zusätzliche Werte gepuffert werden mussten.
Für einige Additionsoperationen ist es immer noch besser, wenn Sie jeweils ein Byte ausgeben.
Aber es gibt keinen Grund, warum Big-Endian natürlicher ist - im Englischen verwenden Sie dreizehn (Little Endian) und dreiundzwanzig (Big Endian).
quelle
0x12345678
gespeichert, wie78 56 34 12
auf einem BE-System12 34 56 78
(Byte 0 ist links, Byte 3 ist rechts). Beachten Sie, dass je größer die Zahl (in Bit) ist, desto mehr Austausch erforderlich ist. ein WORT würde einen Tausch erfordern; ein DWORD, zwei Pässe (drei Total Swaps); ein QWORD drei Durchgänge (insgesamt 7) und so weiter. Das heißt,(bits/8)-1
Swaps. Eine andere Option ist das Vorwärts- und Rückwärtslesen (jedes Byte vorwärts lesen, aber das ganze # rückwärts scannen).Die japanische Datumskonvention lautet "Big Endian" - JJJJ / MM / TT. Dies ist praktisch für Sortieralgorithmen, bei denen ein einfacher Zeichenfolgenvergleich mit der üblichen Regel verwendet werden kann, dass das erste Zeichen am höchsten ist.
Ähnliches gilt für Big-Endian-Zahlen, die in einem höchstwertigen Feld-zuerst-Datensatz gespeichert sind. Die Signifikanzreihenfolge der Bytes in den Feldern stimmt mit der Signifikanz der Felder im Datensatz überein, sodass Sie a
memcmp
zum Vergleichen von Datensätzen verwenden können. Dabei spielt es keine Rolle, ob Sie zwei Langwörter, vier Wörter oder acht separate Bytes vergleichen.Wenn Sie die Reihenfolge der Felder ändern, erhalten Sie den gleichen Vorteil, jedoch nicht für Big-Endian, sondern für Little-Endian-Zahlen.
Dies hat natürlich nur eine sehr geringe praktische Bedeutung. Unabhängig davon, ob Ihre Plattform ein Big-Endian- oder ein Little-Endian-System ist, können Sie bei Bedarf Datensatzfelder bestellen, um diesen Trick auszunutzen. Es ist nur eine Qual, wenn Sie tragbaren Code schreiben müssen.
Ich kann auch einen Link zum klassischen Aufruf einfügen ...
http://tools.ietf.org/rfcmarkup?url=ftp://ftp.rfc-editor.org/in-notes/ien/ien137.txt
BEARBEITEN
Ein zusätzlicher Gedanke. Ich habe einmal eine große Integer-Bibliothek geschrieben (um zu sehen, ob ich das könnte), und dafür werden die 32-Bit-breiten Chunks in Little-Endian-Reihenfolge gespeichert, unabhängig davon, wie die Plattform die Bits in diesen Chunks anordnet. Die Gründe waren ...
Viele Algorithmen beginnen auf natürliche Weise am niedrigstwertigen Ende zu arbeiten und möchten, dass diese Enden übereinstimmen. Beispielsweise propagieren die Überträge zusätzlich immer wichtigere Ziffern, so dass es sinnvoll ist, am niedrigstwertigen Ende zu beginnen.
Ein Wert zu vergrößern oder zu verkleinern bedeutet lediglich, dass am Ende Teile hinzugefügt oder entfernt werden müssen, ohne dass Teile nach oben oder unten verschoben werden müssen. Möglicherweise ist aufgrund der Neuzuweisung des Speichers noch Kopieren erforderlich, jedoch nicht häufig.
Dies hat natürlich keine offensichtliche Bedeutung für Prozessoren - bis CPUs mit Hardware-Big-Integer-Unterstützung hergestellt werden, handelt es sich nur um eine Bibliothekssache.
quelle
Niemand hat geantwortet, WARUM dies getan werden könnte, viele Dinge über die Konsequenzen.
Stellen Sie sich einen 8-Bit-Prozessor vor, der in einem bestimmten Taktzyklus ein einzelnes Byte aus dem Speicher laden kann.
Wenn Sie nun einen 16-Bit-Wert in das einzige 16-Bit-Register, dh den Programmzähler, laden möchten, ist dies auf einfache Weise möglich:
das Ergebnis: Sie erhöhen immer nur den Abrufort, laden immer nur in den unteren Bereich Ihres breiteren Registers und müssen nur nach links verschieben können. (Natürlich ist das Verschieben nach rechts für andere Operationen hilfreich, so dass dies eine kleine Nebenschau ist.)
Dies hat zur Folge, dass die 16-Bit-Daten (Doppelbyte) in der Reihenfolge Most..Least gespeichert werden. Dh die kleinere Adresse hat das höchstwertige Byte - also Big Endian.
Wenn Sie stattdessen versuchen würden, mit Little Endian zu laden, müssten Sie ein Byte in den unteren Teil Ihres Wide-Registers laden, dann das nächste Byte in einen Staging-Bereich laden, es verschieben und dann in den oberen Teil Ihres Wide-Registers einfügen . Oder verwenden Sie eine komplexere Anordnung von Gattern, um selektiv in das obere oder untere Byte zu laden.
Das Ergebnis von Little Endian ist, dass Sie entweder mehr Silizium (Switches und Gates) oder mehr Operationen benötigen.
Mit anderen Worten, in Bezug auf das Geldverdienen in den alten Zeiten hat man mehr Geld für die meiste Leistung und die kleinste Siliziumfläche.
Heutzutage sind diese Überlegungen so gut wie irrelevant, aber Dinge wie das Füllen von Pipelines können immer noch eine große Sache sein.
Wenn es um das Schreiben von S / W geht, ist das Leben häufig einfacher, wenn Little-Endian-Adressen verwendet werden.
(Und die Big-Endian-Prozessoren sind in der Regel Big-Endian in Bezug auf die Bytereihenfolge und Little-Endian in Bezug auf die Bits in Bytes. Einige Prozessoren sind jedoch seltsam und verwenden sowohl die Big-Endian-Bitreihenfolge als auch die Bytereihenfolge. Dies macht das Leben sehr kompliziert Interessant für den H / W-Designer, der speicherabgebildete Peripheriegeräte hinzufügt, aber für den Programmierer keine andere Konsequenz hat.)
quelle
Jimwise machte einen guten Punkt. Es gibt ein anderes Problem, in Little Endian können Sie Folgendes tun:
Einfacher für Programmierer, die nicht vom offensichtlichen Nachteil vertauschter Speicherstellen betroffen sind. Ich persönlich finde, dass Big Endian umgekehrt zu dem ist, was natürlich ist :). 12 sollte als 21 gespeichert und geschrieben werden :)
quelle
for(i=0; i<4; i++) { num += data[i] << (24 - i * 8); }
entsprichtmove.l data, num
auf einem Big - Endian - CPU.Dezimalzahlen sind Big Endian geschrieben. Es ist auch so, wie Sie es auf Englisch schreiben. Sie beginnen mit der höchstwertigen Ziffer und der nächsthöheren bis niedrigstwertigen. z.B
ist eintausend, zweihundert und vierunddreißig.
Auf diese Weise wird Big Endian manchmal als natürliche Ordnung bezeichnet.
In Little Endian wäre diese Zahl eins, zwanzig, dreihundertviertausend.
Wenn Sie jedoch arithmetische Operationen wie Addition oder Subtraktion ausführen, beginnen Sie mit dem Ende.
Sie beginnen mit 4 und 7, schreiben die niedrigste Ziffer und merken sich den Übertrag. Dann addieren Sie 3 und 6 usw. Für Addition, Subtraktion oder Vergleich ist es einfacher zu implementieren, wenn Sie bereits Logik haben, um den Speicher in der richtigen Reihenfolge zu lesen, wenn die Zahlen umgekehrt sind.
Um Big Endian auf diese Weise zu unterstützen, benötigen Sie eine Logik, um den Speicher rückwärts zu lesen, oder Sie haben einen RISC-Prozess, der nur mit Registern arbeitet. ;)
Ein Großteil des Intel x86 / Amd x64-Designs ist historisch.
quelle
Big-Endian ist nützlich für einige Operationen (Vergleiche von "Bignums" von Federn gleicher Oktettlänge). Little-Endian für andere (eventuell mit zwei "Bignums"). Am Ende hängt es davon ab, für was die CPU-Hardware eingerichtet wurde, normalerweise ist es das eine oder andere (einige MIPS-Chips waren, IIRC, beim Booten umschaltbar, um LE oder BE zu sein).
quelle
Wenn nur Speicherung und Übertragung mit variablen Längen erforderlich sind, aber keine Arithmetik mit mehreren Werten, ist LE in der Regel einfacher zu schreiben und BE leichter zu lesen.
Nehmen wir eine Int-to-String-Konvertierung (und zurück) als spezifisches Beispiel.
Wenn das int in die Zeichenfolge konvertiert wird, ist die niedrigstwertige Ziffer leichter zu extrahieren als die höchstwertige Ziffer. Dies kann alles in einer einfachen Schleife mit einer einfachen Endbedingung erfolgen.
Versuchen Sie es jetzt gleich in BE-Reihenfolge. Normalerweise benötigen Sie einen anderen Divisor, der die größte Potenz von 10 für die bestimmte Zahl enthält (hier 100). Das müssen Sie natürlich erst finden. Viel mehr zu tun.
Die Konvertierung von String in Int ist in BE einfacher, wenn sie als umgekehrte Schreiboperation ausgeführt wird. Write speichert die höchstwertige Ziffer zuletzt, daher sollte sie zuerst gelesen werden.
Machen Sie jetzt dasselbe in LE-Reihenfolge. Auch hier benötigen Sie einen zusätzlichen Faktor, der mit 1 beginnt und für jede Ziffer mit 10 multipliziert wird.
Daher bevorzuge ich normalerweise die Speicherung mit BE, da ein Wert genau einmal geschrieben wird, aber mindestens einmal und möglicherweise mehrmals gelesen wird. Wegen seiner einfacheren Struktur gehe ich normalerweise auch den Weg, um nach LE zu konvertieren, und kehre dann das Ergebnis um, selbst wenn der Wert ein zweites Mal geschrieben wird.
Ein weiteres Beispiel für die Speicherung in BE wäre die UTF-8-Codierung und vieles mehr.
quelle