Endianness
- HistoryEdit
- Huidige architecturenEdit
- Bi-endiannessEdit
- Floating pointEdit
- Variabele lengte dataEdit
- OptimizationEdit
- RekenvolgordeEdit
- Bewerkingen die beginnen bij het minst significante cijferEdit
- Bewerkingen die beginnen bij het meest significante cijferEdit
- Operanden van variërende lengteEdit
- Bewerkingen zonder impactEdit
- Middle-endianEdit
- PDP-endianEdit
- Honeywell Series 16Edit
- Intel IA-32 segment descriptorsEdit
HistoryEdit
Vele historische en bestaande processoren gebruiken een big-endian geheugenrepresentatie, hetzij exclusief, hetzij als ontwerpoptie. Big-endian geheugenrepresentatie wordt algemeen aangeduid als netwerkvolgorde, zoals gebruikt in de Internet protocol suite. Andere processortypen gebruiken little-endian geheugenrepresentatie; weer andere gebruiken een ander schema dat “middle-endian”, “mixed-endian” of “PDP-11-endian” wordt genoemd.
Het IBM System/360 gebruikt big-endian byte-volgorde, net als zijn opvolgers System/370, ESA/390, en z/Architecture. De PDP-10 gebruikt ook big-endian adressering voor byte-georiënteerde instructies. De IBM Series/1 minicomputer gebruikt ook big-endian byte-volgorde.
Het omgaan met gegevens van verschillende endianness wordt soms het NUXI probleem genoemd. Deze terminologie verwijst naar de byte-volgorde conflicten die zich voordeden bij het aanpassen van UNIX, dat draaide op de mixed-endian PDP-11, aan een big-endian IBM Series/1 computer. Unix was een van de eerste systemen die het mogelijk maakte dezelfde code te compileren voor platformen met verschillende interne representaties. Een van de eerste geconverteerde programma’s werd verondersteld Unix
af te drukken, maar op de Series/1 drukte het in plaats daarvan nUxi
af.
De Datapoint 2200 gebruikt eenvoudige bit-seriële logica met little-endian om carry propagation te vergemakkelijken. Toen Intel de 8008 microprocessor voor Datapoint ontwikkelde, gebruikten ze little-endian voor compatibiliteit. Aangezien Intel echter niet in staat was de 8008 op tijd te leveren, gebruikte Datapoint een equivalent met medium-schaal integratie, maar het little-endian werd behouden in de meeste Intel ontwerpen, waaronder de MCS-48 en de 8086 en zijn x86 opvolgers. De DEC Alpha, Atmel AVR, VAX, de MOS Technology 6502 familie (inclusief Western Design Center 65802 en 65C816), de Zilog Z80 (inclusief Z180 en eZ80), de Altera Nios II, en vele andere processoren en processorfamilies zijn ook little-endian.
De Motorola 6800 / 6801, de 6809 en de 68000 serie van processoren gebruikten het big-endian formaat.
De Intel 8051 verwacht, in tegenstelling tot andere Intel-processoren, 16-bits adressen voor LJMP en LCALL in big-endian formaat; de xCALL-instructies slaan het retouradres echter op in de stack in little-endian formaat.
SPARC gebruikte historisch gezien big-endian tot versie 9, die bi-endian is; evenzo waren vroege IBM POWER-processoren big-endian, maar de PowerPC- en Power ISA-afstammelingen zijn nu bi-endian. De ARM-architectuur was little-endian vóór versie 3, toen het bi-endian werd.
Huidige architecturenEdit
De Intel x86- en AMD64 / x86-64-serie processoren gebruiken het little-endian formaat. Andere instructieset-architecturen die deze conventie volgen en alleen little-endian modus toestaan, zijn onder andere Nios II, Andes Technology NDS32, en Qualcomm Hexagon.
Sommige instructieset-architecturen staan toe dat software van beide endianness op een bi-endian architectuur wordt uitgevoerd. Hiertoe behoren ARM AArch64, C-Sky, Power ISA en RISC-V.
Alleen big-endian architecturen zijn onder meer de IBM z/Architectuur, Freescale ColdFire (gebaseerd op Motorola 68000 series), Atmel AVR32, en OpenRISC. De IBM AIX en Oracle Solaris besturingssystemen op bi-endian Power ISA en SPARC draaien in big-endian mode; sommige distributies van Linux op Power zijn overgegaan op little-endian mode.
Bi-endiannessEdit
Sommige architecturen (waaronder ARM versies 3 en hoger, PowerPC, Alpha, SPARC V9, MIPS, PA-RISC, SuperH SH-4 en IA-64) hebben een instelling die omschakelbare endianness toestaat in data fetches en stores, instructie fetches, of beide. Deze mogelijkheid kan de prestaties verbeteren of de logica van netwerkapparatuur en software vereenvoudigen. Het woord bi-endian, wanneer het over hardware wordt gesproken, duidt op de mogelijkheid van de machine om gegevens in beide endian formaten te berekenen of door te geven.
Veel van deze architecturen kunnen softwarematig op een specifiek endian formaat worden omgeschakeld (gewoonlijk gebeurt dit bij het opstarten van de computer); op sommige systemen wordt de standaard endianness echter hardwarematig op het moederbord geselecteerd en kan deze niet softwarematig worden gewijzigd (b.v. deb.v. de Alpha, die alleen in big-endian mode draait op de Cray T3E).
Merk op dat de term bi-endian primair verwijst naar hoe een processor omgaat met gegevenstoegang. Instructietoegang (het ophalen van instructiewoorden) op een bepaalde processor kan nog steeds een vaste endianness aannemen, zelfs als gegevenstoegang volledig bi-endian is, hoewel dit niet altijd het geval is, zoals op Intels IA-64-gebaseerde Itanium CPU, die beide toestaat.
Merk ook op dat sommige nominaal bi-endian CPU’s hulp van het moederbord nodig hebben om volledig van endianness te wisselen. Bijvoorbeeld, de 32-bit desktop-georiënteerde PowerPC processoren in little-endian modus gedragen zich als little-endian vanuit het oogpunt van de uitvoerende programma’s, maar ze vereisen dat het moederbord een 64-bit swap uitvoert over alle 8 byte lanes om er zeker van te zijn dat de little-endian kijk op de dingen van toepassing zal zijn op I/O apparaten. Bij afwezigheid van deze ongebruikelijke moederbord hardware, moet apparaatstuurprogramma software naar verschillende adressen schrijven om de onvolledige transformatie ongedaan te maken en moet ook een normale byte swap uitvoeren.
Sommige CPU’s, zoals veel PowerPC processoren bedoeld voor embedded gebruik en bijna alle SPARC processoren, staan per-pagina keuze van endianness toe.
SPARC-processoren sinds eind jaren negentig (SPARC v9 compliant processoren) staan toe dat data endianness wordt gekozen met elke individuele instructie die laadt uit of opslaat naar het geheugen.
De ARM-architectuur ondersteunt twee big-endian modi, BE-8 en BE-32 genoemd. CPU’s tot en met ARMv5 ondersteunen alleen BE-32 of woord-invariante modus. Hier werkt elke natuurlijk uitgelijnde 32-bit toegang zoals in little-endian mode, maar toegang tot een byte of 16-bit woord wordt omgeleid naar het corresponderende adres en niet-uitgelijnde toegang is niet toegestaan. ARMv6 introduceert BE-8 of byte-invariant mode, waarbij toegang tot een enkele byte werkt als in little-endian mode, maar toegang tot een 16-bit, 32-bit of (vanaf ARMv8) 64-bit woord resulteert in een byte-swap van de data. Dit vereenvoudigt unaligned geheugentoegang, evenals in het geheugen gemapte toegang tot registers anders dan 32 bit.
Vele processoren hebben instructies om een woord in een register om te zetten naar de tegenovergestelde endianness, dat wil zeggen, ze verwisselen de volgorde van de bytes in een 16-, 32- of 64-bits woord. Alle individuele bits worden echter niet omgedraaid.
Recente Intel x86 en x86-64 architectuur CPU’s hebben een MOVBE instructie (Intel Core sinds generatie 4, na Atom), die een big-endian formaat woord uit het geheugen haalt of een woord in het geheugen schrijft in big-endian formaat. Deze processoren zijn verder door en door little-endian. Ze hadden ook al een reeks swap instructies om de bytevolgorde van de inhoud van registers om te keren, bijvoorbeeld wanneer woorden al zijn opgehaald van geheugenlocaties waar ze in de “verkeerde” endianness waren.
Floating pointEdit
Hoewel de alomtegenwoordige x86 processoren van vandaag little-endian opslag gebruiken voor alle soorten data (integer, floating point), zijn er een aantal hardware architecturen waar floating-point getallen in big-endian vorm worden gerepresenteerd terwijl integers in little-endian vorm worden gerepresenteerd. Er zijn ARM-processoren die een half little-endian, half big-endian floating-point representatie hebben voor double-precision getallen: beide 32-bits woorden worden in little-endian opgeslagen zoals integer registers, maar de meest significante eerst. Omdat er veel floating-point formaten zijn geweest zonder dat er een “netwerk” standaard representatie voor was, gebruikt de XDR standaard big-endian IEEE 754 als zijn representatie. Het kan daarom vreemd lijken dat de wijdverbreide IEEE 754 floating-point standaard geen endianness specificeert. Theoretisch betekent dit dat zelfs standaard IEEE floating-point gegevens geschreven door de ene machine niet leesbaar zouden kunnen zijn door een andere. Echter, op moderne standaardcomputers (d.w.z. die IEEE 754 implementeren) kan men in de praktijk veilig aannemen dat de endianness hetzelfde is voor drijvende-komma getallen als voor gehele getallen, waardoor de conversie ongecompliceerd is ongeacht het gegevenstype. (Kleine ingebedde systemen die speciale floating-point formaten gebruiken kunnen echter een andere zaak zijn.)
Variabele lengte dataEdit
De meeste instructies die tot nu toe zijn beschouwd bevatten de grootte (lengtes) van zijn operanden binnen de operatiecode. Vaak beschikbare operandlengtes zijn 1, 2, 4, 8, of 16 bytes.Maar er zijn ook architecturen waar de lengte van een operand in een apart veld van de instructie kan worden gehouden of met de operand zelf, b.v. door middel van een woordmarkering. Een dergelijke aanpak maakt operandlengtes tot 256 bytes of zelfs volledige geheugengrootte mogelijk.De gegevenstypen van dergelijke operanden zijn tekenreeksen of BCD.
Machines die in staat zijn dergelijke gegevens met één instructie te manipuleren (b. v. vergelijken, optellen) zijn b. v. IBM 1401, 1410, 1620, System/3×0, ESA/390, en z/Architecture, alle van het type big-endian.
OptimizationEdit
Het little-endian systeem heeft de eigenschap dat dezelfde waarde op verschillende lengtes uit het geheugen kan worden gelezen zonder verschillende adressen te gebruiken (zelfs wanneer uitlijningsbeperkingen worden opgelegd). Bijvoorbeeld, een 32-bit geheugenlokatie met inhoud 4A 00 00 00
kan op hetzelfde adres worden gelezen als 8-bit (waarde = 4A), 16-bit (004A), 24-bit (00004A), of 32-bit (0000004A), die allemaal dezelfde numerieke waarde behouden. Hoewel deze little-endian eigenschap zelden direct wordt gebruikt door high-level programmeurs, wordt het vaak gebruikt door code-optimalisatoren en door assembleertaal programmeurs.
In meer concrete termen, dergelijke optimalisaties zijn het equivalent van de volgende C-code die true retourneert op de meeste little-endian systemen:
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");
Hoewel dit niet is toegestaan in C++, is dergelijke type punning code toegestaan als “implementatie-gedefinieerd” door de C11 standaard en wordt het vaak gebruikt in code die interageert met hardware.
Aan de andere kant, in sommige situaties kan het nuttig zijn om een benadering van een multi-byte of multi-word waarde te verkrijgen door alleen het meest significante gedeelte te lezen in plaats van de volledige representatie; een big-endian processor kan zo’n benadering lezen met behulp van hetzelfde basis-adres dat zou worden gebruikt voor de volledige waarde.
Dergelijke benaderingen zijn niet overdraagbaar tussen systemen met verschillende endianness.
RekenvolgordeEdit
Sommige bewerkingen in positionele getallenstelsels hebben een natuurlijke of voorkeursvolgorde waarin de elementaire stappen dienen te worden uitgevoerd.Deze volgorde kan van invloed zijn op de prestaties van kleine byte-adresseerbare processoren en microcontrollers.
Maar krachtige processoren halen typische operanden van meerdere bytes gewoonlijk uit het geheugen in dezelfde tijd waarin ze een enkele byte zouden hebben opgehaald, dus de complexiteit van de hardware wordt niet beïnvloed door de volgorde van de bytes.
Bewerkingen die beginnen bij het minst significante cijferEdit
Optellen, aftrekken en vermenigvuldigen beginnen bij de positie van het minst significante cijfer en propageren de carry naar de daaropvolgende meer significante positie.Wanneer deze eerste byte het minst significante cijfer bevat – hetgeen overeenkomt met klein-eindigheid – dan is de implementatie van deze bewerkingen marginaal eenvoudiger.
Bewerkingen die beginnen bij het meest significante cijferEdit
Vergelijking en deling beginnen bij het meest significante cijfer en propageren een mogelijke carry naar de daaropvolgende minder significante cijfers. Voor numerieke waarden met een vaste lengte (gewoonlijk van lengte 1,2,4,8,16) is de implementatie van deze operaties marginaal eenvoudiger op big-endian machines.
Operanden van variërende lengteEdit
Veel big-endian processoren bevatten hardware-instructies voor het lexicografisch vergelijken van tekenreeksen van variërende lengte (b.v. het IBM System/360 en zijn opvolgers).
Bewerkingen zonder impactEdit
Het normale datatransport door een assignment statement is in principe onafhankelijk van de endianness van de processor.
Middle-endianEdit
Er zijn talloze andere ordeningen mogelijk, die generiek middle-endian of mixed-endian worden genoemd. Een voorbeeld hiervan buiten de informatica is de standaard Amerikaanse datumnotatie van maand/dag/jaar.
PDP-endianEdit
De PDP-11 is in principe een 16-bit little-endian systeem. De instructies om te converteren tussen floating-point en integer waarden in de optionele floating-point processor van de PDP-11/45, PDP-11/70, en in sommige latere processoren, sloegen 32-bit “double precision integer long” waarden op met de 16-bit helften verwisseld van de verwachte little-endian volgorde. De UNIX C compiler gebruikte hetzelfde formaat voor 32-bit lange gehele getallen. Deze volgorde staat bekend als PDP-endian.
Een manier om deze endianness te interpreteren is dat het een 32-bits geheel getal opslaat als twee 16-bits woorden in big-endian, maar de woorden zelf zijn little-endian (E.b. “jag cog sin” zou zijn “gaj goc nis”):
oplopende adressen → | |||||
0Bh | 0Ah | 0Dh | 0Ch | ||
0A0Bh | 0C0Dh |
De 16-bit waarden hier verwijzen naar hun numerieke waarden, niet naar hun feitelijke indeling.
Honeywell Series 16Edit
De Honeywell Series 16 16-bit computers, inclusief de Honeywell 316, zijn het tegenovergestelde van de PDP-11 in het opslaan van 32-bit woorden in C. Het slaat elk 16-bits woord op in big-endian volgorde, maar voegt ze samen op little-endian wijze:
oplopende adressen → | |||||
0Ch | 0Dh | 0Ah | 0Bh | ||
0C0Dh | 0A0Bh |
Intel IA-32 segment descriptorsEdit
Segment descriptors van IA-32 en compatibele processors houden een 32-bit basisadres van het segment opgeslagen in little-endian volgorde, maar in vier niet-opeenvolgende bytes, op relatieve posities 2, 3, 4 en 7 van het descriptor begin.