Byte-ordning

Den aktuella versionen av sidan har ännu inte granskats av erfarna bidragsgivare och kan skilja sig väsentligt från versionen som granskades den 13 november 2018; kontroller kräver 39 redigeringar .

I moderna datorer och digitala kommunikationssystem representeras information vanligtvis som en sekvens av bytes . I det fall att numret inte kan representeras av en byte spelar det roll i vilken ordning bytena skrivs i datorns minne eller sänds över kommunikationslinjer. Ofta är valet av byteordning godtyckligt och bestäms endast av konventioner.

I allmänhet, för att representera ett tal M som är större än 255 (här  - det maximala heltal som kan skrivas i en byte ), måste du använda flera byte (n). I det här fallet skrivs talet M i positionsnummersystemet i bas 256:

Uppsättningen av heltal , vart och ett mellan 0 och 255, är sekvensen av byte som utgör M . I det här fallet kallas det låg byte , och  - den höga byten för numret M.

Eftersom datorn inte adresserar enskilda bitar (de kan bara erhållas genom bitfält ), är ordningen på bitarna i en byte viktig endast i den fysiska organisationen av datalagring och överföring, kan skilja sig från enhet till enhet och är vanligtvis inte behövs av en applikationsprogrammerare.

Inspelningsalternativ

Ordna från äldst till yngst

Beställ från äldst till yngst ( engelska  big-endian  - from the big end): . Denna ordning liknar den vanliga skrivordningen (till exempel i arabiska siffror ) "från vänster till höger", till exempel skulle siffran etthundratjugotre skrivas i en sådan ordning som 123 . I samma ordning är det vanligt att skriva bytes i teknisk och utbildningslitteratur, om inte en annan ordning uttryckligen anges.

Denna beställning är standard för TCP/IP-protokoll , den används i datapakethuvuden och i många protokoll på högre nivå som är utformade för att användas över TCP/IP. Därför kallas bytesordningen från hög till låg ofta "nätverksbyteordning" ( eng.  nätverksbyteordning ). Denna byteordning används av IBM 360/370/390, SPARC , Motorola 68000-processorer (därav det tredje namnet - Motorola byte order , eng.  Motorola byte order ).

Med denna byteordning är det bekvämt att jämföra strängar (du kan jämföra dem med heltalsfält-delar med större kapacitet, som var och en innehåller flera tecken samtidigt).

Byteordning från hög till låg används också i många filformat  - till exempel PNG , FLV , EBML , JPEG .

Ordna från yngsta till äldsta

Beställ från yngsta till äldsta ( eng.  little-endian  - från den lilla änden):

Detta är den omvända ordningen av att skriva siffror i arabiska siffror , till exempel skulle talet 123 skrivas i en sådan ordning som 321 . Med andra ord, denna ordning liknar skrivregeln från höger till vänster.

Denna skrivordning antas i minnet av persondatorer med x86 - arkitekturprocessorer , och därför kallas den ibland för Intel- byteordning (efter namnet på företaget som skapade x86-arkitekturen). Moderna x86-processorer låter dig arbeta med en-, två-, fyra- och åttabytesoperander. I denna byteordning är det mycket bekvämt att när storleken (antalet byte) på operanden ökar, förblir värdet på dess första byte oförändrat: 3210 → 3210'0000. I ordning från högt till lågt skulle värdet ändras, till exempel: 0123 → 0000'0123;

Förutom x86 används denna byteordning i VAX- arkitekturer (därav ett annat namn för engelska.  VAX-byteordning [1] ), DEC Alpha och många andra.

Ordningen "lägsta till högst" används också i USB , PCI , GUID partitionstabell , den rekommenderas av FidoNet . Men i allmänhet stöder little-endian- konventionen färre plattformsoberoende protokoll och dataformat än big-endian .

Växlingsbar ordning

Många processorer kan fungera i både låg-till-hög ordning och vice versa, som ARM (standard är little endian), PowerPC (förutom PowerPC 970 ), DEC Alpha , MIPS , PA-RISC och IA-64 . Byteordning väljs vanligtvis av programvaran under initiering av operativsystemet , men kan också väljas av hårdvarubyglarna på moderkortet. I det här fallet är det mer korrekt att tala om endianness på operativsystemnivå. Switchable endianness kallas ibland engl.  bi-endian .

Blandad ordning

Blandad (kombinerad, hybrid) byteordning ( engelsk  middle-endian) används ibland när man arbetar med tal vars längd överstiger maskinordet . Numret representeras av en sekvens av maskinord , som är skrivna i ett format som är naturligt för denna arkitektur, men själva maskinorden följer i omvänd ordning.

VAX- och ARM-processorerna använder en blandad representation för långa reella tal.

Exempel

Följande är ett exempel som beskriver placeringen av ett 4-byte-nummer i RAM-minnet på en dator, som kan nås både som ett 32-bitars ord och byte för byte.

Alla tal skrivs i hexadecimalt talsystem.

Antal: 0xA1B2C3D4
Prestanda
Beställ från yngsta till äldsta (lille-endian)
Beställ från äldst till yngst (big-endian)
Ordning antagen i PDP-11 (PDP-endian)

Bestämma endianness

Byteordning (endianness) i en viss maskin kan bestämmas med C -programmet (testbyteorder.c):

#include <stdio.h> #inkludera <stdint.h> int main () { uint16_t x = 0x0001 ; printf ( "%s-endian \n " , * (( uint8_t * ) & x ) ? "lite" : "stor" ); }

Körresultat på en stormaskin ( SPARC ):

$ uname -m sparc64 $ gcc -o testbyteorder testbyteorder.c $ ./testbyteorder big-endian

Kör resultat på en liten endian-maskin ( x86 ):

$ uname -m i386 $ gcc -o testbyteorder testbyteorder.c $ ./testbyteorder liten endian

Reella tal

Lagringen av reella tal kan också bero på endianness. Till exempel på x86 används IEEE 754 -format med tecken och exponent i höga byte.

Unicode

Om Unicode är skrivet i UTF-16- eller UTF-32- format , är endianiteten redan betydande. Ett av sätten att ange ordningen på bytes i Unicode-texter är att prefixet specialtecknet BOM ( byte order mark , byte order mark , U+FEFF) - den "inverterade" versionen av detta tecken (U+FFFE) finns inte och är inte tillåtet i texter.

Tecknet U+FEFF representeras i UTF-16 av bytesekvensen 0xFE 0xFF (big-endian) eller 0xFF 0xFE (little-endian), och i UTF-32 av bytesekvensen 0x00 0x00 0xFE 0xFF (big-endian) eller 0xFF 0xFE 0x00 0x00 (liten -endian).

Kompatibilitets- och konverteringsproblem

Att skriva ett multibytenummer från datorns minne till en fil eller överföra det över ett nätverk kräver konventioner om vilken byte som sänds först. Direktskrivning i den ordning som bytesna är placerade i minnesceller leder till problem både vid överföring av en applikation från plattform till plattform och vid datautbyte mellan systemnätverk.

För att konvertera mellan nätverksbyteordning , som alltid är big-endian, och värdbyteordning , tillhandahåller  POSIX - standarden funktionerna , , , :  htonl()htons()ntohl()ntohs()

  • uint32_t htonl(uint32_t hostlong); - konverterar ett 32-bitars osignerat värde från lokal byteordning till nätverksbyteordning;
  • uint16_t htons(uint16_t hostshort); - konverterar ett 16-bitars osignerat värde från lokal byteordning till nätverksbyteordning;
  • uint32_t ntohl(uint32_t netlong); - konverterar ett 32-bitars osignerat värde från nätverksbyteordning till lokal byteordning;
  • uint16_t ntohs(uint16_t netshort); — konverterar ett 16-bitars osignerat värde från nätverksbyteordning till lokal byteordning.

Om den aktuella byteordningen och nätverksfunktionen matchar kommer de att fungera som "tomma" - det vill säga byteordningen kommer inte att ändras. Standarden tillåter också att dessa funktioner implementeras som makron.

Det finns många språk och bibliotek med möjligheter att konvertera till och från båda större byteordrar.

Linux-kärnan : , le16_to_cpu(), cpu_to_be32(), cpu_to_le16p()och så vidare;

FreeBSD kärna : htobe16(), le32toh(), och så vidare;

Erlang :

<< Antal : 32 / stort - osignerat - heltal , medeltal : 64 / stort - flytande >> = Chunk Meddelande = << Längd : 32 / lite - osignerat - heltal , MTyp : 16 / lite - osignerat - heltal , MessageBody >>

Python :

import struct Count , Average = struct . packa upp ( ">Ld" , Chunk ) Meddelande = struct . pack ( "<LH" , Length , MType ) + MessageBody

Perl :

( $Count , $Average ) = packa upp ( 'L>d>' , $Chunk ); $Message = pack ( '(LS)<' , $Length , $MType ) . $MessageBody ; ( eller samma : $ Message = pack ( 'Vv' , $Length , $MType ) . $MessageBody ;)

dessa exempel för Erlang, Python, Perl innehåller identisk funktionalitet.

Intel x86-64-processorer har en BSWAP-instruktion för att ändra byteordningen.

Etymologi för namnet

Termerna big-endian och little-endian var ursprungligen inte relaterade till datavetenskap. Gullivers resor , ett satiriskt verk av Jonathan Swift , beskriver de fiktiva staterna Lilliputia och Blefuscu, som har varit i krig med varandra i många år på grund av en oenighet om vilken ände kokta ägg ska brytas från . De som tror att de behöver brytas från den trubbiga änden kallas Big-endians (”trubbiga ändar”) i arbetet.

Tvister mellan big-endian och little-endian supportrar inom datavetenskap har också ofta karaktären av den sk. "religiösa krig". [2] Termerna big-endian och little-endian myntades av Danny Cohen 1980 i hans artikel On Holy Wars and a Plea for Peace .  [3] [4]

Se även

Anteckningar

  1. pack() i Perl . Hämtad 20 december 2010. Arkiverad från originalet 13 december 2010.
  2. DAV:s Endian FAQ (nedlänk) . Hämtad 3 augusti 2008. Arkiverad från originalet 10 november 2006. 
  3. Danny Cohen. On Holy Wars and a Plea for Peace  (engelska) (1 april 1980). Datum för åtkomst: 24 januari 2010. Arkiverad från originalet den 15 februari 2012.
  4. Tanenbaum E. Datorarkitektur. - 5:e uppl. - St Petersburg. : Peter, 2007. - 844 sid. - S. 89.

Länkar