Endianness

HistoryEdit

Viele historische und aktuelle Prozessoren verwenden eine Big-Endian-Speicherdarstellung, entweder ausschließlich oder als eine Designoption. Die Big-Endian-Speicherdarstellung wird allgemein als Netzwerkordnung bezeichnet, wie sie in der Internet-Protokollsuite verwendet wird. Andere Prozessortypen verwenden die Little-Endian-Speicherdarstellung; andere wiederum verwenden ein anderes Schema, das als „Middle-Endian“, „Mixed-Endian“ oder „PDP-11-Endian“ bezeichnet wird.

Das IBM System/360 verwendet die Big-Endian-Byte-Reihenfolge, ebenso wie seine Nachfolger System/370, ESA/390 und z/Architecture. Die PDP-10 verwendet ebenfalls Big-Endian-Adressierung für byteorientierte Befehle. Der IBM Series/1-Minicomputer verwendet ebenfalls Big-Endian-Byte-Order.

Der Umgang mit Daten unterschiedlicher Endianness wird manchmal als NUXI-Problem bezeichnet. Diese Terminologie spielt auf die Bytereihenfolgekonflikte an, die bei der Anpassung von UNIX, das auf der Mixed-Endian PDP-11 lief, an einen Big-Endian IBM Series/1 Computer auftraten. Unix war eines der ersten Systeme, das es ermöglichte, denselben Code für Plattformen mit unterschiedlichen internen Darstellungen zu kompilieren. Eines der ersten konvertierten Programme sollte Unix ausgeben, aber auf dem Series/1 wurde stattdessen nUxi gedruckt.

Der Datapoint 2200 verwendet einfache bitserielle Logik mit Little-Endian, um die Carry-Propagation zu erleichtern. Als Intel den 8008-Mikroprozessor für Datapoint entwickelte, verwendete man aus Kompatibilitätsgründen Little-Endian. Da Intel jedoch nicht in der Lage war, den 8008 rechtzeitig auszuliefern, verwendete Datapoint ein mittelgroßes Integrationsäquivalent, aber das Little-Endian-Verfahren wurde in den meisten Intel-Designs beibehalten, einschließlich des MCS-48 und des 8086 und seiner x86-Nachfolger. Der DEC Alpha, Atmel AVR, VAX, die MOS Technology 6502-Familie (einschließlich Western Design Center 65802 und 65C816), der Zilog Z80 (einschließlich Z180 und eZ80), der Altera Nios II und viele andere Prozessoren und Prozessorfamilien sind ebenfalls Little-Endian.

Die Motorola 6800 / 6801, der 6809 und die 68000er Prozessorserie verwendeten das Big-Endian-Format.

Der Intel 8051 erwartet im Gegensatz zu anderen Intel-Prozessoren 16-Bit-Adressen für LJMP und LCALL im Big-Endian-Format; die xCALL-Befehle speichern jedoch die Rücksprungadresse im Little-Endian-Format auf dem Stack.

SPARC verwendete historisch gesehen Big-Endian bis zur Version 9, die Bi-Endian ist; ähnlich waren die frühen IBM POWER-Prozessoren Big-Endian, aber die PowerPC- und Power ISA-Nachkommen sind jetzt Bi-Endian. Die ARM-Architektur war vor Version 3 Little-Endian, als sie Bi-Endian wurde.

Aktuelle ArchitekturenEdit

Die Intel x86 und AMD64 / x86-64 Prozessorserien verwenden das Little-Endian-Format. Andere Befehlssatzarchitekturen, die dieser Konvention folgen und nur den Little-Endian-Modus zulassen, sind Nios II, Andes Technology NDS32 und Qualcomm Hexagon.

Einige Befehlssatzarchitekturen erlauben die Ausführung von Software mit beiden Endianness auf einer Bi-Endian-Architektur. Dazu gehören ARM AArch64, C-Sky, Power ISA und RISC-V.

Zu den reinen Big-Endian-Architekturen gehören die IBM z/Architektur, Freescale ColdFire (basierend auf der Motorola 68000-Serie), Atmel AVR32 und OpenRISC. Die Betriebssysteme IBM AIX und Oracle Solaris auf Bi-Endian Power ISA und SPARC laufen im Big-Endian-Modus; einige Linux-Distributionen auf Power sind zum Little-Endian-Modus übergegangen.

Bi-EndiannessEdit

Einige Architekturen (einschließlich ARM Versionen 3 und höher, PowerPC, Alpha, SPARC V9, MIPS, PA-RISC, SuperH SH-4 und IA-64) verfügen über eine Einstellung, die eine umschaltbare Endianness bei Datenfetches und -speichern, Befehlsfetches oder beidem ermöglicht. Diese Funktion kann die Leistung verbessern oder die Logik von Netzwerkgeräten und Software vereinfachen. Das Wort „bi-endian“, wenn es sich auf Hardware bezieht, bezeichnet die Fähigkeit der Maschine, Daten in beiden Endian-Formaten zu berechnen oder weiterzuleiten.

Viele dieser Architekturen können per Software auf ein bestimmtes Endian-Format umgestellt werden (normalerweise beim Hochfahren des Computers); bei einigen Systemen wird die Standard-Endianness jedoch durch die Hardware auf der Hauptplatine ausgewählt und kann nicht per Software geändert werden (z. B. der Alpha, der nur mit Endian-Formaten läuft).z. B. der Alpha, der auf der Cray T3E nur im Big-Endian-Modus läuft).

Beachten Sie, dass sich der Begriff Bi-Endian hauptsächlich darauf bezieht, wie ein Prozessor Datenzugriffe behandelt. Befehlszugriffe (Abrufe von Befehlswörtern) auf einem bestimmten Prozessor können immer noch eine feste Endianness annehmen, selbst wenn Datenzugriffe vollständig bi-endianisch sind, obwohl dies nicht immer der Fall ist, wie z. B. bei Intels IA-64-basierter Itanium-CPU, die beides zulässt.

Beachten Sie auch, dass einige nominell bi-endianische CPUs die Hilfe der Hauptplatine benötigen, um die Endianness vollständig zu wechseln. Die 32-Bit-Desktop-orientierten PowerPC-Prozessoren im Little-Endian-Modus verhalten sich beispielsweise aus der Sicht der ausführenden Programme als Little-Endian, erfordern aber, dass die Hauptplatine einen 64-Bit-Swap über alle 8-Byte-Spuren durchführt, um sicherzustellen, dass die Little-Endian-Sicht der Dinge für E/A-Geräte gilt. Fehlt diese ungewöhnliche Motherboard-Hardware, muss die Gerätetreibersoftware an verschiedene Adressen schreiben, um die unvollständige Umwandlung rückgängig zu machen, und außerdem einen normalen Byte-Swap durchführen.

Einige CPUs, wie z. B. viele PowerPC-Prozessoren, die für den eingebetteten Einsatz bestimmt sind, und fast alle SPARC-Prozessoren, erlauben die Auswahl der Endianness pro Seite.

SPARC-Prozessoren seit den späten 1990er Jahren (SPARC v9-konforme Prozessoren) erlauben die Auswahl der Datenendianness mit jeder einzelnen Anweisung, die aus dem Speicher lädt oder in den Speicher speichert.

Die ARM-Architektur unterstützt zwei Big-Endian-Modi, BE-8 und BE-32 genannt. CPUs bis ARMv5 unterstützen nur BE-32 oder den Word-Invariant-Modus. Hier funktioniert jeder natürlich ausgerichtete 32-Bit-Zugriff wie im Little-Endian-Modus, aber der Zugriff auf ein Byte oder 16-Bit-Wort wird auf die entsprechende Adresse umgeleitet, und ein nicht ausgerichteter Zugriff ist nicht zulässig. ARMv6 führt den BE-8 oder byte-invarianten Modus ein, bei dem der Zugriff auf ein einzelnes Byte wie im Little-Endian-Modus funktioniert, der Zugriff auf ein 16-Bit-, 32-Bit- oder (ab ARMv8) 64-Bit-Wort jedoch zu einem Byte-Swap der Daten führt. Dies vereinfacht den nicht ausgerichteten Speicherzugriff sowie den speicherbezogenen Zugriff auf Register, die nicht 32-Bit sind.

Viele Prozessoren verfügen über Befehle zur Umwandlung eines Wortes in einem Register in die entgegengesetzte Endianness, d.h. sie vertauschen die Reihenfolge der Bytes in einem 16-, 32- oder 64-Bit-Wort. Die einzelnen Bits werden jedoch nicht vertauscht.

Neuere CPUs der Intel x86- und x86-64-Architektur haben einen MOVBE-Befehl (Intel Core seit Generation 4, nach Atom), der ein Wort im Big-Endian-Format aus dem Speicher holt oder ein Wort im Big-Endian-Format in den Speicher schreibt. Ansonsten sind diese Prozessoren durch und durch Little-Endian. Sie verfügten auch bereits über eine Reihe von Swap-Befehlen zur Umkehrung der Byte-Reihenfolge des Registerinhalts, z. B. wenn Wörter bereits von Speicherplätzen geholt wurden, wo sie in der „falschen“ Endianness waren.

FließkommaEdit

Obwohl die heute allgegenwärtigen x86-Prozessoren Little-Endian-Speicher für alle Datentypen (Ganzzahl, Fließkomma) verwenden, gibt es eine Reihe von Hardware-Architekturen, bei denen Fließkommazahlen in Big-Endian-Form dargestellt werden, während Ganzzahlen in Little-Endian-Form dargestellt werden. Es gibt ARM-Prozessoren, die eine halbe Little-Endian- und eine halbe Big-Endian-Gleitkommadarstellung für Double-Precision-Zahlen haben: Beide 32-Bit-Wörter werden wie Integer-Register in Little-Endian gespeichert, aber das höchstwertige Wort zuerst. Da es viele Gleitkommaformate gab, für die es keine „Netzwerk“-Standarddarstellung gab, verwendet der XDR-Standard die Big-Endian-Darstellung nach IEEE 754. Es mag daher seltsam erscheinen, dass der weit verbreitete Gleitkomma-Standard IEEE 754 keine Endianness angibt. Theoretisch bedeutet dies, dass selbst Standard-IEEE-Gleitkommadaten, die von einem Rechner geschrieben wurden, von einem anderen nicht gelesen werden können. Auf modernen Standardcomputern (d. h., die IEEE 754 implementieren) kann man jedoch in der Praxis davon ausgehen, dass die Endianness für Gleitkommazahlen dieselbe ist wie für ganze Zahlen, so dass die Konvertierung unabhängig vom Datentyp einfach ist. (Kleine eingebettete Systeme, die spezielle Fließkommaformate verwenden, können jedoch eine andere Sache sein.)

Daten mit variabler LängeBearbeiten

Die meisten bisher betrachteten Anweisungen enthalten die Größe (Längen) ihrer Operanden innerhalb des Operationscodes. Häufig sind Operandenlängen von 1, 2, 4, 8 oder 16 Byte verfügbar, aber es gibt auch Architekturen, bei denen die Länge eines Operanden in einem separaten Feld der Anweisung oder mit dem Operanden selbst, z. B. mittels einer Wortmarke, festgehalten werden kann. Die Datentypen solcher Operanden sind Zeichenketten oder BCD.

Maschinen, die solche Daten mit einer Anweisung manipulieren können (z. B. Vergleichen, Addieren), sind z. B. IBM 1401, 1410, 1620, System/3×0, ESA/390 und z/Architektur, die alle vom Typ Big-Endian sind.

OptimizationEdit

Das Little-Endian-System hat die Eigenschaft, dass derselbe Wert mit unterschiedlichen Längen aus dem Speicher gelesen werden kann, ohne dass unterschiedliche Adressen verwendet werden müssen (selbst wenn Ausrichtungsbeschränkungen bestehen). Zum Beispiel kann eine 32-Bit-Speicherstelle mit dem Inhalt 4A 00 00 00 an derselben Adresse entweder als 8-Bit (Wert = 4A), 16-Bit (004A), 24-Bit (00004A) oder 32-Bit (0000004A) gelesen werden, wobei alle denselben numerischen Wert behalten. Obwohl diese Little-Endian-Eigenschaft nur selten direkt von High-Level-Programmierern verwendet wird, wird sie häufig von Code-Optimierern sowie von Assembler-Programmierern eingesetzt.

Konkret entsprechen solche Optimierungen dem folgenden C-Code, der auf den meisten Little-Endian-Systemen true zurückgibt:

union { uint8_t u8; uint16_t u16; uint32_t u32; uint64_t u64;} u = { .u64 = 0x4A };puts(u.u8 == u.u16 && u.u8 == u.u32 && u.u8 == u.u64 ? "true" : "false");

Obwohl in C++ nicht zulässig, ist ein solcher Type-Punning-Code als „implementierungsdefiniert“ im C11-Standard erlaubt und wird häufig in Code verwendet, der mit Hardware interagiert.

Andererseits kann es in manchen Situationen nützlich sein, eine Annäherung an einen Multi-Byte- oder Multi-Wort-Wert zu erhalten, indem man nur den höchstwertigen Teil anstelle der vollständigen Darstellung liest; ein Big-Endian-Prozessor kann eine solche Annäherung lesen, indem er die gleiche Basisadresse verwendet, die für den vollständigen Wert verwendet würde.

Optimierungen dieser Art sind nicht auf Systeme mit unterschiedlicher Endianness übertragbar.

RechenreihenfolgeBearbeiten

Einige Operationen in Positionszahlensystemen haben eine natürliche oder bevorzugte Reihenfolge, in der die elementaren Schritte ausgeführt werden müssen.Diese Reihenfolge kann ihre Leistung auf kleinen byteadressierbaren Prozessoren und Mikrocontrollern beeinträchtigen.

Hochleistungsprozessoren holen jedoch typische Multi-Byte-Operanden in der Regel in der gleichen Zeit aus dem Speicher wie ein einzelnes Byte, so dass die Komplexität der Hardware durch die Byte-Reihenfolge nicht beeinflusst wird.

Operationen, die an der niedrigstwertigen Stelle beginnenBearbeiten

Addition, Subtraktion und Multiplikation beginnen an der niedrigstwertigen Stelle und übertragen den Übertrag auf die nachfolgende höherwertige Stelle.Wenn dieses erste Byte die niederwertigste Ziffer enthält – was der Kleinheit entspricht -, dann ist die Implementierung dieser Operationen geringfügig einfacher.

Operationen, die an der höchstwertigen Ziffer beginnenBearbeiten

Vergleich und Division beginnen an der höchstwertigen Ziffer und übertragen einen möglichen Übertrag auf die nachfolgenden niederwertigen Ziffern. Für numerische Werte fester Länge (typischerweise der Länge 1,2,4,8,16) ist die Implementierung dieser Operationen auf Big-Endian-Maschinen geringfügig einfacher.

Operanden unterschiedlicher LängeBearbeiten

Viele Big-Endian-Prozessoren enthalten Hardware-Befehle für den lexikographischen Vergleich unterschiedlich langer Zeichenketten (z. B. das IBM System/360 und seine Nachfolger).

Operationen ohne AuswirkungBearbeiten

Der normale Datentransport durch eine Zuweisungsanweisung ist prinzipiell unabhängig von der Endianness des Prozessors.

Middle-EndianBearbeiten

Zahlreiche andere Anordnungen, allgemein Middle-Endian oder Mixed-Endian genannt, sind möglich. Ein solches Beispiel außerhalb der Informatik ist die standardmäßige amerikanische Datumsformatierung von Monat/Tag/Jahr.

PDP-endianEdit

Die PDP-11 ist im Prinzip ein 16-Bit-Little-Endian-System. Die Anweisungen zur Konvertierung zwischen Gleitkomma- und Ganzzahlwerten im optionalen Gleitkommaprozessor der PDP-11/45, PDP-11/70 und in einigen späteren Prozessoren speicherten 32-Bit-„double precision integer long“-Werte, wobei die 16-Bit-Hälften gegenüber der erwarteten Little-Endian-Reihenfolge vertauscht waren. Der UNIX-C-Compiler verwendete das gleiche Format für 32-Bit-Long-Integer-Werte. Diese Anordnung ist als PDP-Endian bekannt.

Eine Möglichkeit, diese Endianness zu interpretieren, besteht darin, dass eine 32-Bit-Ganzzahl als zwei 16-Bit-Wörter in Big-Endian gespeichert wird, die Wörter selbst aber Little-Endian sind (z.z. B. „jag cog sin“ wäre „gaj goc nis“):

Speicherung einer 32-Bit-Ganzzahl, 0x0A0B0C0D, auf einer PDP-11
steigende Adressen →
0Bh 0Ah 0Dh 0Ch
0A0Bh 0C0Dh

Die 16-Bit-Werte beziehen sich hier auf ihre numerischen Werte, nicht auf ihr tatsächliches Layout.

Honeywell Series 16Edit

Die 16-Bit-Computer der Honeywell Series 16, einschließlich des Honeywell 316, sind das Gegenteil der PDP-11 bei der Speicherung von 32-Bit-Wörtern in C. Er speichert jedes 16-Bit-Wort in Big-Endian-Reihenfolge, fügt sie aber in Little-Endian-Manier zusammen:

Speicherung einer 32-Bit-Ganzzahl, 0x0A0B0C0D, auf einem Honeywell 316
mit steigenden Adressen →
0Ch 0Dh 0Ah 0Bh
0C0Dh 0A0Bh

Intel IA-32-SegmentdeskriptorenBearbeiten

Segmentdeskriptoren von IA-32- und kompatiblen Prozessoren halten eine 32-Bit-Basisadresse des Segments in Little-Endian-Reihenfolge gespeichert, jedoch in vier nicht aufeinanderfolgenden Bytes an den relativen Positionen 2, 3, 4 und 7 des Deskriptoranfangs.