Byte-Reihenfolge

aus Wikipedia, der freien Enzyklopädie
Wechseln zu: Navigation, Suche

Die Byte-Reihenfolge (englisch Byte-Order oder Endianness) bezeichnet in der Computertechnik 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 Rest 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 aufeinander folgen.

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ß-Ender“, siehe auch Abschnitt Etymologie) wird das Byte mit den höchstwertigen Bits (d. h. die signifikantesten Stellen) zuerst gespeichert, das heißt an der kleinsten Speicheradresse. Allgemein bedeutet der Begriff, dass Daten mit dem größtwertigen Element zuerst genannt werden, wie etwa bei der deutschen Schreibweise der Uhrzeit: Stunde:Minute:Sekunde.
  • Bei Little-Endian (wörtlich „Klein-Ender“) wird dagegen das Byte mit den niederstwertigen Bits (d. h. die am wenigsten signifikanten Stellen) an der kleinsten Speicheradresse gespeichert beziehungsweise das kleinstwertige Element zuerst genannt, wie bei der herkömmlichen deutschen Datumsschreibweise: Tag.Monat.Jahr.

Die Begriffe Big-Endian und Little-Endian benennen also dasjenige Ende der Zahlendarstellung, das in einer Reihenfolge an erster Stelle steht beziehungsweise an der kleinsten Adresse gespeichert wird.

Im Sprachgebrauch werden die beiden Varianten in der Computertechnik oft auch nach den Herstellern von Mikroprozessoren benannt, die die jeweilige Variante in mehreren Prozessorfamilien verwenden beziehungsweise verwendet haben: „Motorola-Format“ steht für Big-Endian, während „Intel-Format“ für Little-Endian steht.

Werden Daten bitweise seriell übertragen, so ist auch die Bit-Reihenfolge festzulegen. Logisch erscheint Big-Endian-Byte-Reihenfolge, wenn das höchstwertige Bit eines Bytes zuerst übertragen wird (etwa I²C), und entsprechend umgekehrt (etwa RS-232). Bisweilen sieht man auch umgekehrte Zuordnungen, etwa bei Bildwiederholspeichern.

Beispiel: Speicherung eines Integer-Werts[Bearbeiten]

Big Endian Little Endian Mischform „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 (Vierhundertneununddreißig Millionen...) als 32-Bit-Integer-Wert gespeichert (Binär: 00011010 00101011 00111100 01001101, hexadezimal: 1A 2B 3C 4D). Die Speicherung erfolgt in vier Bytes ab der hypothetischen Speicheradresse 10000.

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 Reihenfolge 3C 4D 1A 2B oder auch 2B 1A 4D 3C. Dies wird als Middle Endian bezeichnet.

Diagramm zur Abbildung von Registerwerten auf Speicheradressen[Bearbeiten]

Mapping registers to memory locations

Mit diesem Diagramm lassen sich Registerwerte auf Speicheradressen und Speicheradressen auf Registerwerte abbilden. Zum besseren Verständnis kann man sich vorstellen, dass Big Endian's Koordinatensystem nach rechts wächst, während Little Endian's Koordinatensystem nach links wächst.

Hardware-Beispiele[Bearbeiten]

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- beziehungsweise -Coldfire-Familie, den Prozessoren der System-z- und Sun-SPARC-CPUs und dem PowerPC eingesetzt. Letzterer 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 von Zahlen in der Sprache[Bearbeiten]

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 indisch-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-Reihenfolge-Problems[Bearbeiten]

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, zum Beispiel UTF-16. Um dieses Problem bei Unicode-Zeichen zu umgehen, wird oft eine Bytereihenfolge-Markierung (BOM) benutzt. In einem Hex-Editor sieht ein Text folgendermaßen aus:

44 00 69 00 65 00 |D i e |  = UTF-16LE / UCS-2LE; BOM am Dateianfang = FF FE
00 44 00 69 00 65 | D i e|  = UTF-16BE / UCS-2BE; BOM am Dateianfang = FE FF

Plattformübergreifende Darstellung von Zahlen[Bearbeiten]

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 beziehungsweise zum Teil 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 beziehungsweise 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 Zwei-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 Little-Endian-System dagegen wegen der Vertauschung der Byte in jedem Wort als „NUXI“ (auf 32-Bit Systemen stünde dagegen „XINU“ in einem einzelnen 32-Bit-Register).

Wichtige Eigenschaften der Darstellungen[Bearbeiten]

Dieser Artikel oder Abschnitt bedarf einer Überarbeitung. Näheres ist auf der Diskussionsseite angegeben. Hilf mit, ihn zu verbessern, und entferne anschließend diese Markierung.

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.

Die Registerbreite ist bei den meisten CPUs normalerweise identisch oder doppelt so breit wie der Datenbus. 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 verringern (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.

Little-Endian-Format[Bearbeiten]

Bei dieser Darstellung kann man bei ganzen Zahlen sofort sehen, wo die Einerstelle ist, nämlich am Anfang. Große Zahlen brauchen nicht wie bei der herkömmlichen Big-Endian-Darstellung erst von hinten her gruppiert zu werden, um ihre Größe zu erfassen. Additionen wären einfacher.

Beispiel:

71   +
1402 +
39   +
007
----
1582
====

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 Bytes am Ende angefügt werden, ohne dass sich die Speicheradresse ändert. Auf einer Big-Endian-Maschine muss der Wert zuvor im Speicher um zwei Bytes 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.

Big-Endian-Format[Bearbeiten]

  • Im Big-Endian-Format sind Hexdumps von Zahlen leichter lesbar, da die Reihenfolge der Ziffern die gleiche ist wie in der üblichen Schreibweise des Stellenwertsystems.

Verwendung[Bearbeiten]

Little-Endian[Bearbeiten]

Heutige PC-Systeme (x86-kompatible) verwenden Little-Endian. Weitere sind Alpha, Altera Nios, Atmel AVR, manche SH3/SH4-Systeme oder VAX.

Dies sind 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 gegebenenfalls berücksichtigt werden, zum Beispiel bei der Treiber-Programmierung.

Big-Endian[Bearbeiten]

Big-Endian verwenden Mainframe-Systeme (z. B. IBM-Mainframe) sowie MIPS-, SPARC-, PowerPC-, Motorola 6800/68k-, Atmel AVR32[1]- und TMS9900-Prozessoren. Alpha-Prozessoren lassen sich in diesem Modus betreiben, dies ist jedoch unüblich.

Mischvarianten (Bi-Endian)[Bearbeiten]

Es existieren Prozessoren, zum Beispiel bestimmte MIPS-Varianten und PowerPC, sowie alle Alpha-Prozessoren, die zwischen Little Endian und Big Endian umschaltbar sind. Auch ARM-Prozessoren (inkl. des Intel XScales) können sowohl mit Little, als auch mit Big Endian betrieben werden.

Dateiformate[Bearbeiten]

Die typische Verwendung einer Byte-Reihenfolge in einer Prozessorarchitektur zur Ablage von Werten im Hauptspeicher hat Einfluss auf die Byte-Reihenfolge von Werten im Sekundärspeicher (oft Festplatten). 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 diesem Motorola-68000-Prozessor wurden die Vier-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 Vier-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[Bearbeiten]

Die Bezeichnungen gehen auf den satirischen Roman Gullivers Reisen von Jonathan Swift zurück, in dem die Bewohner des Landes Liliput in zwei verfeindeten Gruppen leben: Die einen schlagen ihre Eier am dicken, „großen“, englisch „big“, Ende auf und werden deshalb als Big Ender bezeichnet, während die Little Ender die Eier am spitzen, „kleinen“, englisch „little“ Ende öffnen.[2] Swift spielte damit auf die Abspaltung der englischen Kirche (Spitz-Ender) von der katholischen Kirche (Dick-Ender) an – in Zusammenhang mit der Byte-Reihenfolge wurde dies erstmals 1980 von Danny Cohen in dem Aprilscherz-Paper On Holy Wars and a Plea for Peace gebracht.[3]

Weblinks[Bearbeiten]

Einzelnachweise[Bearbeiten]

  1. Atmel: AVR32 Architecture Document (PDF; 5,1 MB) Nov. 2007
  2. Jürgen Gärtner: Little/Big Endian.
  3. Danny Cohen: On Holy Wars and a Plea for Peace. IETF, 1. April 1980