DieByte-Reihenfolge (englischbyte order oderendianness) bezeichnet in derInformatik die Speicherorganisation für einfache Zahlenwerte, in erster Linie die Ablageganzzahliger Werte (Integer) imArbeitsspeicher.
Die erstenRechnerarchitekturen haben die Darstellung mehrstelliger Zahlen aus dem Alltag entsprechend derKonvention desStellenwertsystems übernommen, zunächst für dezimal, dann auch für binär dargestellte Zahlen. In dieser Konvention beginnt dieNotation einer Zahl mit derZiffer an der höchstwertigen Stelle. Addition, Subtraktion und Multiplikation beginnen aber mit der niedrigstwertigen Ziffer, derEinerstelle.
Solange man innerhalb ähnlicher Rechnerarchitekturen blieb, musste man sich nicht um die Endianness kümmern, sie entsprach ja der gewohnten. Da die genannten drei mathematischen Grundfunktionen jedoch einenMaschinenzyklus früher starten können, wenn man die Bitreihenfolge umkehrt, haben in der Folge einige Hersteller ein entsprechendes Architekturprinzip erstellt. Das heißt: die Einerstelle wird an die Anfangsadresse gelegt, und die 3 genanntenAlgorithmen schreiten nach rechts in die höheren Stellen und Adressen fort. Diese Abweichung vom Gewohnten machte die BegriffsbildungEndianness erforderlich:
Im Sprachgebrauch werden die beiden Varianten in der Computertechnik oft auch nach den Herstellern vonMikroprozessoren benannt, die die jeweilige Variante in mehrerenProzessorfamilien verwenden bzw. verwendet haben: „Motorola-Format“ steht für big-endian, „Intel-Format“ für little-endian.
Werden Datenbitweise seriell übertragen, so ist zusätzlich dieBit-Reihenfolge festzulegen. Auch hier sind unterschiedliche Varianten anzutreffen:
Folgende Aussagen, über die in der Literatur hochgradigerKonsens besteht, seien als Ausgangsbasis für die Diskussion und Definition der Sachverhalte explizit gemacht:
3A4B5C6Dh
oder0x3A4B5C6D
bezeichnen einen Zahlwert, und zwar die Zahl 978.017.389, und nicht ihre Darstellung im Speicher, es sei denn, man meint die Speicherung3Ah4Bh5Ch6Dh
. Will man eine andere Art der Speicherung derselben Zahl0x3A4B5C6D
angeben, so muss man auf andere Notationen ausweichen, wie auf6Dh5Ch4Bh3Ah
oder0x6D,0x5C,0x4B,0x3A
.Steigt bei einer im Speicher abgelegten Zahl die Wertigkeit einer Stelle mit der wachsenden Adresse, dann ist sie im Little-Endian-Format dargestellt.
Fällt bei einer im Speicher abgelegten Zahl die Wertigkeit einer Stelle mit der wachsenden Adresse, dann ist sie im Big-Endian-Format dargestellt.
Wird bei einem Computersystem eines dieser beiden Formate für die Speicherungnumerischer[4] Felder durchgehalten, so wird das erste alsLittle-Endian-, das zweite alsBig-Endian-System bezeichnet.
Byte- Adresse | Big Endian | Mixed Endian | Little Endian |
---|---|---|---|
10000 | 0A | 0B | 0D |
10001 | 0B | 0A | 0C |
10002 | 0C | 0D | 0B |
10003 | 0D | 0C | 0A |
Das Beispiel in der Grafik stellt die Ganzzahl 168.496.141 als 32-Bit-Integer-Wert dar (hexadezimal:0A0B0C0Dh
), gespeichert in 4 Bytes ab einer angenommenenSpeicheradresse von10000
:
168496141 = 0A0B0C0Dh
in der Reihenfolge0Ah0Bh0Ch0Dh
.168496141 = 0A0B0C0Dh
in der umgekehrten Reihenfolge der Bytes0Dh0Ch0Bh0Ah
.Einige ältere Systeme (z. B.PDP-11) speichern die Bytes auch in der Reihenfolge0Bh0Ah0Dh0Ch
(abernicht als0Ch0Dh0Ah0Bh
). Dies wird alsmixed-endian oder auchmiddle-endian bezeichnet.
Einige Systeme speichern sowohl big-endian als auch little-endian, was alsbi-endian bezeichnet wird.
Auch die gewöhnliche Darstellung von (Dezimal-)Zahlen ist – im Sinne derLeserichtung der meisten europäischen Sprachen von links nach rechts –big-endian. Dies kommt dadurch zustande, dass die Ziffernreihenfolge derindisch-arabischen Zahlen bei den Schriften Mitteleuropas beibehalten wurde. Im Arabischen, das sich von rechts nach links liest, werden die Zahlen gleich geschrieben, d. h. 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 (diese Reihenfolge gibt es auch inanderen Sprachen).
Ein Beispiel für Dezimalzahlen: In der gebräuchlichsten Darstellung(big-endian) wird die Dezimalzahl Eintausend-zweihundert-dreißig dargestellt als „1230“, wobei die „1“ die Wertigkeit 1000 hat, die „2“ die Wertigkeit 100 und die „3“ die Wertigkeit 10. In der „Little-Endian“-Darstellung ist es umgekehrt, so dass die Darstellung der Zahl „0321“ wäre (ausgesprochen vielleicht „Dreißig-Zweihundert-Eintausend“).
Das Problem der Byte-Reihenfolge betrifft solcheDatentypen, die aus mehreren Byte zusammengesetzt sind und vom jeweiligenProzessor direkt unterstützt werden, also hauptsächlich Ganzzahl- undGleitkommatypen, sowie Datentypen, die vom Prozessor effektiv als solche interne Datentypen behandelt werden, z. B.UTF-16.
Um dieses Problem beiUnicode-Zeichen zu umgehen, wird oft eineBytereihenfolge-Markierung (BOM) benutzt.Die Zeichenfolge "Die" (drei Zeichen, 6 Byte) mit BOM (ein Zeichen, 2 Byte) als UTF-16-Kodierung, in der Byte-Darstellung vonHex-Editoren (8 Byte) stellt sich für die beiden unterschiedliche Byte-Reihenfolgen etwa so dar:
Big Endian:
FE FF 00 44 00 69 00 65 | þÿ␣D␣i␣e
Little Endian:
FF FE 44 00 69 00 65 00 | ÿþD␣i␣e␣
Um einen fehlerfreien Datenaustausch zwischen Computern verschiedener Plattformen zu ermöglichen, ist beiNetzwerkprotokollen 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 verbreitetenInternetprotokoll-Satzes entspricht dieNetwork Byte Order demBig-Endian-Format. Es existieren jedoch noch immer Protokolle, die eine andere Byte-Reihenfolge verwenden. Darüber hinaus gibt es Datentypen, die nicht oder nicht nur durch die Endianness charakterisiert sind, wie z. B. Gleitkommazahlen, bei deren Umwandlung auch Genauigkeitsverluste möglich sind.
In der auf den meistenBetriebssystemen angebotenenBSD-IP-Socket-API existieren zur Umwandlung der Byte-Reihenfolge sechs Funktionen:
Datentyp (Wortbreite) | Umwandlung | |
---|---|---|
Host-to-network | Network-to-host | |
double (64 bit) | htond() | ntohd() |
long (32 bit) | htonl() | ntohl() |
short (16 bit) | htons() | ntohs() |
Die korrekte Umwandlung ist garantiert fürvorzeichenlose Ganzzahlen. Negative Ganzzahlen werden korrekt umgewandelt, wenn sie imZweierkomplement dargestellt sind und dieBitbreite übereinstimmt.
Auf Big-Endian-Maschinen sind diese Funktionen trivial, da Host- und Network-Byteorder identisch sind.
Für Programmierer von Netzwerkanwendungen empfiehlt sich die Verwendung dieser Funktionen, da sich derQuellcode dadurch auch auf andere Systeme übertragen lässt.
Die Auswahl der zur laufenden Hardware passendenImplementierung geschieht normalerweise implizit durch das Betriebssystem – im Notfall auch durch den Benutzer beimDownload.
Der Endianness-Typ einer Maschine lässt sich programmtechnisch wie folgt feststellen:
union{uint16_tsixteenBits;uint8_ttwoBytes[2];}test_endianness;test_endianness.sixteenBits=1<<15;// 0x8000, 32768if(test_endianness.twoBytes[0]!=0){// Das Programm läuft auf einer Big-Endian-Maschine.}else{// Das Programm läuft auf einer Little-Endian-Maschine.}
In derBitConverter
-Klasse des.NET Framework
gibt es das FeldIsLittleEndian
,[5] das den Endianness-Typ (der laufenden Hardware) abzufragen gestattet.[6]
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.
Die Problematik der Darstellung von Daten auf unterschiedlichen Systemen und ihres Austauschs wird ganz allgemein adressiert von derDarstellungsschicht des OSI-Modells.
Scherzhaft wird das Problem verschiedenerEndianness 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 Bytes in jedem Wort als „NUXI“ (auf 32-Bit-Systemen stünde dagegen „XINU“ in einem einzelnen 32-Bit-Register).
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.
CLCL
(CompareLogicalCharacterLong) mit zwei (verschieden und beliebig) langen Speicheroperanden, der dielexikographische Ordnung implementiert.[7]memcmp()
[8], ersetzt werden.Beispiel für eine dezimale Little-Endian-Addition:
717 + 0452 ---- 7523 ====
(Probe:717+2540=3257
)
Der Zweck einesDumps ist die eindeutige Darstellung des Speicherinhalts bspw. zur Fehleranalyse. Bei Maschinen, deren Speicherstelle (Byte) aus 8 Bits besteht, wird hierfür die Darstellung imHexadezimalsystem gewählt, bei dem die28 = 256 = 162 verschiedenen Inhalte eines Bytes in 2 Hexadezimalziffern ausgedrückt werden. DieserCodierung, die sowohl Binärwerte wie Maschineninstruktionen wie Dezimalwerte imBCD-Code unmittelbar abdeckt, wird üblicherweise eine Spalte beigegeben, die jedes einzelne Byte sofern möglich als alphabetisches Zeichen darstellt, so dass eventuell im Speicher vorhandene Texte leichter erkannt und lesbar werden.
Das folgende Beispiel zeigt, wie zwei aufeinander folgende Bytes (4 Halbbytes) in einem Hexdump mit dem lesbaren hexadezimalen Inhalta732
zu interpretieren sind.
Hexdump | 2 vorzeichenlose 8-Bit-Binärzahlen | 1 vorzeichenlose 16-Bit-Binärzahl | ||||||||||
Bytes | Text | Byte0: Bits | hex | dez | Byte1: Bits | hex | dez | Bits | hex | dez | ||
Offset | 0 | 1 | 0123 4567 | 0123 4567 | 0123 4567 89ab cdef | |||||||
lesbar | a7 | 32 | §2 | |||||||||
big-endian | ||||||||||||
---|---|---|---|---|---|---|---|---|---|---|---|---|
interne Bitfolge | 1010 0111 | 0011 0010 | 1010 0111 0011 0010 | |||||||||
Interpretation | 1010 01112 | a7h | 16710 | 0011 00102 | 32h | 5010 | 1010 0111 0011 00102 | a732h | 4280210 | |||
little-endian | ||||||||||||
interne Bitfolge | 1110 0101 | 0100 1100 | 1110 0101 0100 1100 | |||||||||
Interpretation | 1010 01112 | a7h | 16710 | 0011 00102 | 32h | 5010 | 0011 0010 1010 01112 | 32a7h | 1296710 |
Besteht das Feld nur aus einem einzelnen Byte (8-Bit-Binärzahl mit oderohne Vorzeichen) oder einer Ansammlung davon (bspw. Text im CodeISO 8859) – in der Tabelle die Spalten „2 vorzeichenlose 8-Bit Binärzahlen“ –, dann unterscheidet sich die Interpretation bei den beiden Formaten big- oder little-endian nicht.Zwar ist zwischen den beiden Formaten dieinterne Reihenfolge der Bits pro Byte genauso gespiegelt wie die der Bytes pro Integer (s.Bitwertigkeit#Adressierung von Bits). Durch die Maßgaben der Hexadezimaldarstellung ist der Hexdump aber Byte für Byte vollkommen festgelegt, so dass sich big- oder little-endian nicht unterscheiden.
Besteht das Feld aus mehr als einem Byte, kommt bei little-endian die sogenannte „Intel-Konvention“[9] zum Zuge. Diese besagt, dass – anders als bei big-endian – das niederwertige Byte auf der niederen Speicheradresse abgelegt wird und die höherwertigen Bytes auf den nachfolgenden Speicheradressen. Im Ergebnis sind bspw. bei ganzzahligen Feldern der Länge 16, 32 oder 64 Bits die beiden Hexdump-Darstellungen byteweise Spiegelungen voneinander. Zur Verdeutlichung ist in der Tabelle bei den Spalten „1 vorzeichenlose 16-Bit Binärzahl“ der Inhalt des ersten der 2 Bytes mit einem Überstrich versehen.
Das Formatbig-endian wurde z. B. eingesetzt bei derMotorola-6800- sowie derMotorola-68000- bzw. -Coldfire-Familie, den Prozessoren derSystem-z- undSun-SPARC-CPUs und demPower (bis Power7) undPowerPC.
Big-endian wird verwendet vonMainframe-Systemen (z. B.IBM-Mainframe) sowieMIPS-,SPARC-,Power-,PowerPC-,Motorola 6800/68k-,Atmel-AVR32-[10] undTMS9900-Prozessoren. Auch Alpha-Prozessoren lassen sich in diesem Modus betreiben, dies ist jedoch unüblich. Mit dem IBM POWER8 wurde die Power-Architektur (PAPR) auf little-endian umgestellt, jedoch kann der POWER8 ebenfalls noch im Big-Endian-Modus betrieben werden.[11]
PowerPC kann bei einigen Modellen auch auflittle-endian umgeschaltet werden sowie POWER8 vomLittle- in denBig-Endian-Modus umgestellt werden – IBM forciert jedoch seit dem POWER8 den Little-Endian-Modus.
DasLittle-Endian-Format wurde ursprünglich beim Prozessor6502, derNEC-V800-Reihe,PICmicro oder den Intel-x86-Prozessoren verwendet.
Auch heutigePC-Systeme (x86-kompatible) verwendenlittle-endian. Weitere sindAlpha,Altera Nios,Atmel AVR,IBM Power abPOWER8,RISC-V, mancheSH3/SH4-Systeme oderVAX. Dies sindTrue-Little-Endian-Systeme. Auch dieArm-Architektur verwendet standardmäßig Little-Endian. Arm-CPUs werden in Mikrokontrollern (beispielsweiseRP2040), Single-Board-Computern (Raspberry Pi) und den allermeisten Mobiltelefonen eingesetzt. Die Smartphone-BetriebssystemeAndroid undIOS[12] verwenden die Arm-Architektur und verwalten den Speicher im Little-Endian-Modus.
Im Gegensatz dazu stehen Architekturen, wie manche PowerPC-Varianten (u. a. 603, 740, 750), die nur 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. Bei der Softwareerstellung für diese Systeme muss dies gegebenenfalls berücksichtigt werden, z. B. bei derTreiber-Programmierung.
Einige Prozessoren, z. B. bestimmte MIPS-Varianten und POWER/PowerPC (PAPR) sowie alle Alpha-Prozessoren, lassen sich zwischenlittle-endian undbig-endian umschalten.
AuchArm-Prozessoren (inkl. des IntelXScales) können bei Datenzugriffen sowohl inlittle- als auch inbig-endian betrieben werden; auf Code wird bei ARM-Prozessoren allerdings immer im Little-Endian-Format zugegriffen.
Die vonHewlett-Packard undIntel gemeinsam entwickelteItanium-Architektur „IA-64“ beherrscht ebenfalls beide Byte-Reihenfolgen, was zur Erleichterung derPortierung vonBetriebssystemen hatte dienen sollen (insbesondere zwischen HP-UX(big-endian) undWindows(little-endian)).
Die typische Verwendung einer Byte-Reihenfolge in einer Prozessorarchitektur zur Ablage von Werten imArbeitsspeicher hat Einfluss auf die Byte-Reihenfolge von Werten imSekundärspeicher (oft Festplatten). Bei der Neuerstellung vonDateiformaten wurde die Byte-Reihenfolge der Zahlenwerte so gelegt, dass sie beim Speichern und Zurückladen vom Sekundärspeicher ohne Wandlung auskommen. MittelsSpeichervirtualisierung können Daten auf dem Sekundärspeicher sogar direkt vom Programm angesprochen werden.
Bedeutsam ist dies fürContainerformate mit einer allgemeinen Strukturdefinition. So wurde dasInterchange File Format (IFF) fürAmiga-Programme entworfen, und entsprechend diesemMotorola-68000-Prozessor wurden die Vier-Byte-Chunk-Längen im Motorola-Format big-endian abgelegt. Auf dem ebenfalls mit Motorola-Prozessoren arbeitendenMacintosh-Rechnern wurde dieses u. a. für das Audioformat AIFF übernommen.
Bei der Übernahme auf die Windows-Plattform mit Intel-Prozessoren wurden die Chunk-Längen umdefiniert auf das Vier-Byte Intel-Format little-endian und das neue allgemeine Containerformat alsResource Interchange File Format (RIFF) bezeichnet. Dieses RIFF-Dateiformat ist die Grundlage verbreiteter Dateiformate wie RIFF WAVE (*.wav-Dateien) für Audio undAudio Video Interleave (*.avi-Dateien) für Video.
Auch bei Dateiformaten ist es möglich, eine Definition zu entwickeln, die beide Byte-Reihenfolgen der Prozessorarchitekturen zulässt. So steht z. B. bei TIFF-Dateien (Tagged Image File Format) in den ersten zwei Bytes der Datei:
II
für Intel-Format (little-endian) oderMM
für Motorola-Format (big-endian).Nachfolgende Längen- und Offset-Werte in der Datei werden dann entsprechend kodiert.
Die Bezeichnungen gehen auf densatirischen RomanGullivers Reisen vonJonathan Swift zurück, in dem die Bewohner des LandesLiliput in zwei verfeindeten Gruppen leben: Die einen schlagen ihre Frühstücks-Eier am dicken, „großen“, englisch „big“, Ende auf und werden deshalb alsBig Ender bezeichnet, während dieLittle Ender die Eier am spitzen, „kleinen“, englisch „little“ Ende öffnen. 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 vonDanny Cohen in demAprilscherz-PaperOn Holy Wars and a Plea for Peace gebracht.[13]
memcmp()
undstrcmp()
startet aufjeder Maschine amAnfangsbuchstaben der Zeichenkette und wertet damit die Stellen niedriger Adresse als höherrangig, agiert also im Big-Endian-Stil. Man nennt diese Übertragung der Ordnung von den einzelnen Bytes auf mehrstellige Felder, wenn sie bei der ersten Stelle beginnt, dielexikographische Ordnung. (strncmp. In:cppreference.com. Abgerufen am 26. März 2015 (englisch). )#define
-Konstante, die den Endianness-Typ abzufragen gestattet.ISO/IEC 14882:2014, auch bekannt alsC++14. iso.org; abgerufen am 21. Mai 2016.