- Bytereihenfolge
-
Die Byte-Reihenfolge (engl.: Byte-Order oder Endianness) bezeichnet die Speicherorganisation für einfache Zahlenwerte, in erster Linie die Ablage von ganzzahligen Werten (Integer) im Arbeitsspeicher. Eine Festlegung des zu verwendenden Speicherungsformats ist dann nötig, wenn zur Codierung der zu speichernden Zahl mehr Bits erforderlich sind, als in der kleinsten adressierbaren Einheit zur Verfügung stehen. Im Regelfall ist die kleinste adressierbare Einheit ein Byte, dies wird im folgenden des Artikels auch so unterstellt. Die Speicherung einer Zahl erfolgt nun, falls hierfür mehr als ein Byte benötigt wird, in mehreren Bytes, deren Speicheradressen direkt aufeinanderfolgen.
Während sich bei vielen anderen Formen der Speicherorganisation herstellerübergreifende Standards herausgebildet haben, so haben sich bei der Byte-Reihenfolge zwei Varianten erhalten.
- Bei Big-Endian (wörtlich „Großes Ende“) wird das Byte mit den höchstwertigen Bits (d. h. die signifikantesten Stellen) zuerst gespeichert, d. h. an der kleinsten Speicheradresse.
- Bei Little-Endian (wörtlich „Kleines Ende“) wird dagegen das Byte mit den niederwertigsten Bits (d. h. die am wenigsten signifikanten Stellen) an der kleinsten Speicheradresse gespeichert.
Im Sprachgebrauch werden die beiden Varianten oft auch nach den Herstellern von Mikroprozessoren benannt, die die jeweilige Variante in mehreren Prozessorfamilien verwenden bzw. verwendet haben: Motorola-Format steht für Big-Endian, während Intel-Format für Little-Endian steht.
Inhaltsverzeichnis
Beispiel: Speicherung eines Integer-Werts
Big Endian Little Endian Middle Endian Adresse Hex Dez Binär Hex Dez Binär Hex Dez Binär 10000 1A
26
00011010
4D
77
01001101
2B
43
00101011
10001 2B
43
00101011
3C
60
00111100
1A
26
00011010
10002 3C
60
00111100
2B
43
00101011
4D
77
01001101
10003 4D
77
01001101
1A
26
00011010
3C
60
00111100
Im folgenden Beispiel wird die Ganzzahl 439.041.101 als 32-Bit-Integer-Wert gespeichert (Binär:
00011010 00101011 00111100 01001101
, hexadezimal:1A 2B 3C 4D
). Die Speicherung erfolgt ab einer hypothetischen Speicheradresse10000
und den darauf folgenden drei Bytes.Wenn die Speicherung in der Reihenfolge
1A 2B 3C 4D
erfolgt, entspricht dies Big Endian. Die Speicherung in der umgekehrten Reihenfolge (4D 3C 2B 1A
), also das am wenigsten signifikante Byte an der niedrigsten Speicheradresse, entspricht dagegen Little Endian. Einige ältere Systeme (z. B. PDP-11) speichern die Daten auch in der Reihenfolge3C 4D 1A 2B
oder auch2B 1A 4D 3C
. Dies wird als Middle Endian bezeichnet.Hardware-Beispiele
Das Format Little Endian wurde ursprünglich bei dem Prozessor 6502, der NEC-V800-Reihe, PICmicro oder den Intel-x86-Prozessoren verwendet. Dagegen wurde das Big-Endian-Format beispielsweise bei der Motorola-6800- sowie der Motorola-68000- bzw. -Coldfire-Familie, den Prozessoren der System z und Sun SPARC CPUs und dem PowerPC eingesetzt. Letzter kann jedoch bei einigen Modellen auch auf Little-Endian umgeschaltet werden. Die von Hewlett-Packard und Intel gemeinsam entwickelte IA-64-Architektur beherrscht ebenfalls beide Byte-Reihenfolgen, wodurch die Portierung von Betriebssystemen, insbesondere HP-UX (Big Endian) und Windows (Little Endian), auf diese Architektur erleichtert wird.
Byte-Reihenfolge in der Umgangssprache
Auch die gewöhnliche Darstellung von (Dezimal-)Zahlen ist – im Sinne der Leserichtung der meisten europäischen Sprachen von links nach rechts – Big Endian. Dies kommt jedoch dadurch zustande, dass die Ziffernreihenfolge der arabischen Zahlen bei den Schriften Mitteleuropas beibehalten wurde. Im Arabischen, das sich von rechts nach links liest, werden die Zahlen gleich geschrieben, das heißt, für Zahlen unter 100 werden sie als „Little Endian“ gelesen. (Für Zahlen ab 100 werden sie Big-Endian gelesen.) Auch im deutschen werden die Zahlen von 13 bis 99 little-endian ausgesprochen: „Ein-und-Zwanzig“. Die Eins als weniger wertige Stelle wird zuerst gesprochen. (auch in anderen Sprachen gibt es diese Reihenfolge)
Ein Beispiel für Dezimalzahlen: In der gebräuchlichsten Darstellung (Big Endian) wird die Dezimalzahl Eintausend-zweihundert-dreißig als „1230“ dargestellt, wobei die „1“ die Wertigkeit 1000, die „2“ die Wertigkeit 100 hat und die „3“ die Wertigkeit 10 erhält. In der „Little-Endian“-Darstellung ist es umgekehrt, so dass die Darstellung der Zahl „0321“ wäre (ausgesprochen vielleicht „Dreißig-Zweihundert-Eintausend“).
Kontexte des Byte-Order-Problems
Das Problem der Byte-Reihenfolge betrifft solche Datentypen, die aus mehreren Byte zusammengesetzt sind und vom jeweiligen Prozessor direkt unterstützt werden, also hauptsächlich Ganzzahl- und Gleitkommatypen, sowie Datentypen, die vom Prozessor effektiv als solche interne Datentypen behandelt werden, z. B. UTF-16. Um dieses Problem bei Unicode-Zeichen zu umgehen wird oft eine Byte-Reihenfolge-Markierung benutzt.
Plattformübergreifende Darstellung von Zahlen
Um einen fehlerfreien Datenaustausch zwischen Computern verschiedener Plattformen zu ermöglichen, ist bei Netzwerkprotokollen immer die Byte-Reihenfolge festgeschrieben. Diese wird als Network Byte Order bezeichnet. Die natürliche Byte-Reihenfolge des Systems wird demgegenüber als Host Byte Order bezeichnet. Arbeitet das System nicht mit dieser Byte-Reihenfolge, so muss diese im Netzwerktreiber bzw. z. T. im Anwendungsprogramm entsprechend umgewandelt werden.
Im Falle des heute vornehmlich verbreiteten Internetprotokoll-Satzes entspricht die Network Byte Order dem Big-Endian-Format. Es existieren jedoch noch immer Protokolle, die eine andere Byte-Reihenfolge verwenden.
In der auf den meisten Betriebssystemen angebotenen BSD-IP-Socket-API existieren zur Umwandlung der Byte-Reihenfolge vier Funktionen:
-
Name Datentyp Bedeutung htonl() long (32 bit) host-to-network Umwandlung htons() short (16 bit) host-to-network Umwandlung ntohl() long (32 bit) network-to-host Umwandlung ntohs() short (16 bit) network-to-host Umwandlung
Auf Big-Endian-Maschinen sind diese Funktionen im Falle des Internetprotokolls wirkungslos, da Host- und Network-Byteorder identisch sind. Es empfiehlt sich jedoch dennoch stets der Gebrauch dieser Funktionen, da sich der Quellcode dadurch auch auf andere Systeme übertragen lässt. Es existieren in dieser API jedoch keine standardisierten Funktionen zur Umwandlung von 64-Bit-Zahlen, da diese bei der Entstehung des Standards noch nicht verbreitet waren.
Byte-Order-Probleme können auch beim Austausch von Dateien sowie zum Teil beim Austausch von Datenträgern zwischen verschiedenen Plattformen auftreten. Hier muss entweder durch eindeutige Definition des entsprechenden Dateiformats bzw. Dateisystems oder durch einen Kompatibilitätsmodus, der während des Ladens eine Erkennung und eventuelle Umwandlung durchführt, Abhilfe geschaffen werden.
Scherzhaft wird das Problem verschiedener Endianness unterschiedlicher Architekturen auch oft als NUXI-Problem bezeichnet: Wenn das Wort UNIX in zwei 2-Byte-Words (zwei 16-Bit-Register für „UN“ und „IX“) gespeichert wird, liegt es in einem Big-Endian-System als „UNIX“ im Speicher, in einem Middle-Endian-System dagegen wegen der Vertauschung der Byte in jedem Wort als „NUXI“. (Auf 32-Bit Systemen würde dagegen „XINU“ in einem einzelnen 32-Bit-Register stehen.)
Vor- und Nachteile der Darstellungen
Grundsätzlich lassen sich nur wenige handfeste Argumente für oder gegen einzelne Byte-Reihenfolgen anbringen. Zusätzlich drängen immer breitere Datenworte und die Möglichkeit der gleichzeitigen Verarbeitung derselben die Bedeutung der Byte-Reihenfolge in den Hintergrund. Dennoch gibt es interessante Implikationen der Byte-Reihenfolgen.
Normalerweise sind Datenbus- und Registerbreite bei den meisten CPUs identisch. Bei den ersten Mikroprozessoren waren dies nur 4 Bit (später dann lange Zeit 8 Bit). Der Adressbus ist aber bei diesen CPUs wesentlich breiter. Damit ergab sich die Notwendigkeit, Daten mit einem Befehl zu laden oder zu speichern, welche auf mindestens zwei gekoppelte Register verteilt waren. Um die Komplexität der CPU zu vereinfachen (jede einzelne Transistorfunktion war noch teuer) war es einfacher, bei jeder Operation automatisch das niederwertige „Datenhäppchen“ zu laden, während dieser Speicheroperation konnte dann der Befehl weiter dekodiert und gegebenenfalls die weiteren Daten im nächsten Zyklus bearbeitet werden. Bei Großrechnern („main frames“) bestand dieses Problem weniger, da sie damals schon mit Datenbus-Breiten von 16 bis 48 Bit arbeiteten, diese also in einem einzigen Speicherzyklus laden konnten und somit die (Byte)-Reihenfolge keine Rolle spielte.
Vorteile des Little-Endian-Formats
Um auf einer Little-Endian-Maschine eine Zwei-Byte-Zahl in eine Vier-Byte-Zahl zu verwandeln, müssen lediglich zwei mit Null gefüllte Byte am Ende angefügt werden, ohne dass sich die Speicheradresse ändert. Auf einer Big-Endian-Maschine muss der Wert zuvor im Speicher um zwei Byte verschoben werden. Auch die umgekehrte Umwandlung gestaltet sich einfacher. Auf einer Little-Endian-Maschine werden einfach die höherwertigen Byte verworfen, ohne dass sich die Speicheradresse ändert.
Vorteile des Big-Endian-Formats
- In vielen Netzwerkprotokollen werden Zahlen im Big-Endian-Format codiert. Wenn ein Prozessor die Daten im Big-Endian-Format erwartet, kann er direkt auf die Daten im Speicher zugreifen und muss sie nicht erst byteweise laden und dann „umdrehen“.
- In Hexdumps sind Zahlen im Big-Endian-Format leichter lesbar, da die Reihenfolge der Ziffern die gleiche ist wie in der üblichen Schreibweise des Stellenwertsystems.
Verwendung
Little
Heutige PC-Systeme (x86-kompatible) verwenden Little-Endian. Weitere sind Alpha, manche SH3/SH4-Systeme oder VAX.
Daneben gibt es auch noch sogenannte true-little-endian Systeme. Diese Bezeichnung dient zur Unterscheidung von Architekturen, wie manche PowerPC-Varianten (u. a. 603, 740, 750), die als Little-Endian-Systeme konfiguriert werden können (s. u. Bi-Endian) und aus der Sicht des laufenden Programms dann Little-Endian verwenden, Werte im Speicher jedoch weiterhin im Big-Endian-Format ablegen. Bei Lade- und Speicheroperationen wird die Darstellung implizit umgewandelt. Diese Systeme sind keine true-little-endian Systeme. Bei der Softwareerstellung für diese Systeme muss dies ggfs. berücksichtigt werden, z. B. bei der Treiber-Programmierung.
Big
Mainframe-Systeme (z. B. IBM Mainframe) sowie MIPS-, SPARC, PowerPC- und Motorola 68k-Prozessoren verwenden Big-Endian.
Die plattformunabhängige Programmiersprache Java verwendet Big-Endian.Mischvarianten (Bi-Endian)
Es existieren Prozessoren, z. B. bestimmte MIPS-Varianten und PowerPC, die zwischen Little Endian und Big Endian umschaltbar sind. Auch ARM-Prozessoren (inkl. des Intel XScales) können sowohl Little als auch Big Endian betrieben werden.
Dateiformate
Die typische Verwendung einer Byte-Reihenfolge in einer Prozessorarchitektur zur Ablage von Werten im Hauptspeicher hat auf die Byte-Reihenfolge von Werten im Sekundärspeicher (oft Festplatten) ausgestrahlt. Bei der Neuerstellung von Dateiformaten wurde die Byte-Reihenfolge der Zahlenwerte so gelegt, dass sie beim Speichern und Zurückladen vom Sekundärspeicher ohne Wandlung auskommen. Mittels Speichervirtualisierung können Daten auf dem Sekundärspeicher sogar direkt vom Programm angesprochen werden.
Bedeutsam ist dies für Containerformate mit einer allgemeinen Strukturdefinition. So wurde das Interchange File Format (IFF) für Amiga-Programme entworfen und entsprechend dessen Motorola 68000 Prozessors wurden die 4-Byte Chunk-Längen im Motorola-Format / Big-Endian abgelegt. Auf dem ebenfalls mit Motorola-Prozessoren arbeitenden Macintosh Rechnern wurde dieses unter anderem für das Audioformat AIFF übernommen.
Bei der Übernahme zur Windows-Plattform auf Intel Prozessoren wurden die Chunk-Längen umdefiniert auf 4-Byte Intel-Format / Little-Endian und das neue allgemeine Containerformat als Resource Interchange File Format (RIFF) bezeichnet. Dieses RIFF-Dateiformat ist die Grundlage verbreiteter Dateiformate wie RIFF WAVE (*.wav Dateien) für Audio und Audio Video Interleave (*.avi Dateien) für Video.
Auch bei Dateiformaten ist es möglich, eine Definition zu entwickeln, die beide Byte-Reihenfolgen der Prozessorarchitekturen einschließt. Bei TIFF-Dateien (Tagged Image File Format) steht in den ersten zwei Bytes der Datei entweder „II“ oder „MM“ und bezieht sich damit auf die typischen Bezeichnungen der Byte-Reihenfolge: „II“ für Intel-Format (Little-Endian) und „MM“ für Motorola-Format (Big-Endian). Nachfolgende Längen- und Offset-Werte in der Datei werden dann entsprechend kodiert.
Etymologie
Die kuriose Bezeichnung lehnt an den satirischen Roman Gullivers Reisen von Jonathan Swift an, in dem der Streit darüber, ob ein Ei am spitzen oder am dicken Ende aufzuschlagen sei, die Bewohner von Liliput in zwei verfeindete Lager spaltet – die „Little-Endians“ und die „Big-Endians“, in der deutschen Übersetzung des Buches „Spitz-Ender“ und „Dick-Ender“. Jonathan Swift spielt damit auf die Abspaltung der englischen Kirche (Spitz-Ender) von der katholischen Kirche (Dick-Ender) an.
Weblinks
- Endian FAQ – mit: Internet Engineering Note 137: On Holy Wars and a Plea for Peace von Danny Cohen (engl.)
- White Paper: Endianness or Where is Byte 0? (PDF, engl.)
- Understanding Big and Little Endian Byte Order (engl.)
Wikimedia Foundation.