Byte rækkefølge

Den aktuelle version af siden er endnu ikke blevet gennemgået af erfarne bidragydere og kan afvige væsentligt fra den version , der blev gennemgået den 13. november 2018; checks kræver 39 redigeringer .

I moderne computer- og digitale kommunikationssystemer er information normalt repræsenteret som en sekvens af bytes . I tilfælde af at tallet ikke kan repræsenteres af én byte, har det betydning, i hvilken rækkefølge bytene skrives i computerens hukommelse eller sendes over kommunikationslinjer. Ofte er valget af byterækkefølge vilkårligt og kun bestemt af konventioner.

Generelt, for at repræsentere et tal M større end 255 (her  - det maksimale heltal, der kan skrives i en byte ), skal du bruge flere bytes (n). I dette tilfælde skrives tallet M i positionstalsystemet i base 256:

Sættet af heltal , hver mellem 0 og 255, er sekvensen af ​​bytes , der udgør M. I dette tilfælde kaldes det den lave byte , og  - den høje byte af tallet M.

Da computeren ikke adresserer individuelle bits (de kan kun opnås gennem bitfelter ), er rækkefølgen af ​​bits i en byte kun vigtig i den fysiske organisering af datalagring og -transmission, kan variere fra enhed til enhed og er normalt ikke behov for en applikationsprogrammør.

Optagelsesmuligheder

Rækkefølge fra ældste til yngste

Bestil fra ældste til yngste ( engelsk  big-endian  - fra den store ende): . Denne rækkefølge ligner den sædvanlige skriverækkefølge (f.eks . i arabiske tal ) "fra venstre mod højre", for eksempel ville tallet hundrede og treogtyve blive skrevet i sådan en rækkefølge som 123 . I samme rækkefølge er det sædvanligt at skrive bytes i teknisk og pædagogisk litteratur, medmindre en anden rækkefølge udtrykkeligt er angivet.

Denne ordre er standard for TCP/IP-protokoller , den bruges i datapakkeheadere og i mange højere niveau-protokoller designet til at blive brugt over TCP/IP. Derfor kaldes rækkefølgen af ​​bytes fra høj til lav ofte "netværksbyteorden" ( eng.  netværksbyteorden ). Denne byte-rækkefølge bruges af IBM 360/370/390, SPARC , Motorola 68000-processorer (deraf det tredje navn - Motorola byte order , eng.  Motorola byte order ).

Med denne byte-rækkefølge er det praktisk at sammenligne strenge (du kan sammenligne dem med heltalsfelter-dele med større kapacitet, som hver indeholder flere tegn på én gang).

Byterækkefølge fra høj til lav bruges også i mange filformater  - for eksempel PNG , FLV , EBML , JPEG .

Rækkefølge fra yngste til ældste

Bestil fra yngste til ældste ( eng.  little-endian  - fra den lille ende):

Dette er omvendt af den sædvanlige rækkefølge for at skrive tal i arabiske tal , for eksempel ville tallet hundrede og treogtyve blive skrevet i sådan en rækkefølge som 321 . Med andre ord ligner denne rækkefølge skrivereglen fra højre mod venstre.

Denne skriverækkefølge er overtaget i hukommelsen på personlige computere med x86 - arkitekturprocessorer , og derfor kaldes den nogle gange Intel byte-rækkefølge (efter navnet på det firma, der skabte x86-arkitekturen). Moderne x86-processorer giver dig mulighed for at arbejde med en-, to-, fire- og otte-byte operander. I denne byte-rækkefølge er det meget bekvemt, at når størrelsen (antal bytes) af operanden stiger, forbliver værdien af ​​dens første byte uændret: 3210 → 3210'0000. I rækkefølge fra høj til lav vil værdien ændre sig, for eksempel: 0123 → 0000'0123;

Ud over x86 bruges denne byte-rækkefølge i VAX- arkitekturer (deraf et andet navn for engelsk.  VAX-byte-rækkefølge [1] ), DEC Alpha og mange andre.

Også rækkefølgen "laveste til højeste" bruges i USB , PCI , GUID partitionstabel , det anbefales af FidoNet . Men generelt understøtter little-endian- konventionen færre cross-platform-protokoller og dataformater end big-endian .

Skiftbar rækkefølge

Mange processorer kan arbejde i både lav-til-høj rækkefølge og omvendt, såsom ARM (standard er little endian), PowerPC (undtagen PowerPC 970 ), DEC Alpha , MIPS , PA-RISC og IA-64 . Byte-rækkefølgen vælges normalt af software under initialisering af operativsystemet , men kan også vælges af hardwarejumpere på bundkortet. I dette tilfælde er det mere korrekt at tale om endianness på operativsystemniveau. Skiftbar endianness kaldes undertiden engl.  bi-endian .

Blandet rækkefølge

Blandet (kombineret, hybrid) byte-rækkefølge ( engelsk  middle-endian) bruges nogle gange, når der arbejdes med tal, hvis længde overstiger maskinordet . Tallet er repræsenteret af en sekvens af maskinord , som er skrevet i et format, der er naturligt for denne arkitektur, men selve maskinordene følger i omvendt rækkefølge.

VAX- og ARM -processorerne bruger en blandet repræsentation for lange reelle tal.

Eksempel

Det følgende er et eksempel, der beskriver placeringen af ​​et 4-byte tal i RAM på en computer, som kan tilgås både som et 32-bit ord og byte for byte.

Alle tal er skrevet i et hexadecimalt talsystem.

Antal: 0xA1B2C3D4
Ydeevne
Bestil fra yngste til ældste (lille-endian)
Bestil fra ældste til yngste (big-endian)
Bekendtgørelse vedtaget i PDP-11 (PDP-endian)

Bestemmelse af endianness

Byte-rækkefølge (endianness) i en bestemt maskine kan bestemmes ved hjælp af C -programmet (testbyteorder.c):

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

Kørselsresultater på en big-endian-maskine ( SPARC ):

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

Kør resultater på en lille endian-maskine ( x86 ):

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

Reelle tal

Lagringen af ​​reelle tal kan også afhænge af endianness. På x86 bruges f.eks. IEEE 754- formater med fortegn og eksponent i høje bytes.

Unicode

Hvis Unicode er skrevet i UTF-16- eller UTF-32- format , er endianiteten allerede betydelig. En af måderne til at angive rækkefølgen af ​​bytes i Unicode-tekster er at præfikse specialtegnet BOM ( byte order mark , byte order mark , U+FEFF) - den "inverterede" version af dette tegn (U+FFFE) findes ikke og er ikke tilladt i tekster.

U+FEFF-tegnet er repræsenteret i UTF-16 af bytesekvensen 0xFE 0xFF (big-endian) eller 0xFF 0xFE (little-endian), og i UTF-32 af bytesekvensen 0x00 0x00 0xFE 0xFF (big-endian) eller 0xFF 0xFE 0x00 0x00 (lille -endian).

Problemer med kompatibilitet og konvertering

At skrive et multibytenummer fra computerhukommelsen til en fil eller overføre det over et netværk kræver konventioner om, hvilken byte der transmitteres først. Direkte skrivning i den rækkefølge, som bytes er placeret i hukommelsesceller, fører til problemer både ved overførsel af en applikation fra platform til platform og ved intersystem-netværks dataudveksling.

For at konvertere mellem netværksbyterækkefølge , som altid er big-endian, og værtsbyterækkefølge , giver  POSIX - standarden funktionerne , , , : htonl()htons()ntohl()ntohs()

  • uint32_t htonl(uint32_t hostlong); - konverterer en 32-bit usigneret værdi fra lokal byte-rækkefølge til netværksbyte-rækkefølge;
  • uint16_t htons(uint16_t hostshort); - konverterer en 16-bit usigneret værdi fra lokal byte-rækkefølge til netværksbyte-rækkefølge;
  • uint32_t ntohl(uint32_t netlong); - konverterer en 32-bit usigneret værdi fra netværksbyterækkefølge til lokal byterækkefølge;
  • uint16_t ntohs(uint16_t netshort); — konverterer en 16-bit usigneret værdi fra netværksbyterækkefølge til lokal byterækkefølge.

Hvis den aktuelle byte-rækkefølge og netværksfunktionen matcher, vil de fungere som "tomme" - det vil sige, at byte-rækkefølgen ikke ændres. Standarden tillader også, at disse funktioner implementeres som makroer.

Der er mange sprog og biblioteker med faciliteter til at konvertere til og fra begge større byte-ordrer.

Linux-kerne : , le16_to_cpu(), cpu_to_be32(), cpu_to_le16p()og så videre;

FreeBSD -kerne : htobe16(), le32toh(), og så videre;

Erlang :

<< Antal : 32 / stort - usigneret - heltal , Gennemsnit : 64 / stort - flydende >> = Chunk Besked = << Længde : 32 / lille - usigneret - heltal , MType : 16 / lille - usigneret - heltal , MessageBody >>

Python :

import struct Antal , Gennemsnit = struct . unpack ( ">Ld" , Chunk ) Message = struct . pack ( "<LH" , Length , MType ) + MessageBody

Perl :

( $Count , $Average ) = pak ud ( 'L>d>' , $Chunk ); $Message = pack ( '(LS)<' , $Length , $MType ) . $MessageBody ; ( eller det samme : $Message = pack ( 'Vv' , $Length , $MType ) . $MessageBody ;)

disse eksempler for Erlang, Python, Perl indeholder identisk funktionalitet.

Intel x86-64-processorer har en BSWAP-instruktion til at ændre byterækkefølgen.

Etymologi af navnet

Udtrykkene big-endian og little-endian var ikke oprindeligt relateret til datalogi. Gulliver 's Travels , et satirisk værk af Jonathan Swift , beskriver de fiktive stater Lilliputia og Blefuscu, som har været i krig med hinanden i mange år på grund af en uenighed om, hvilken ende kogte æg skal brydes fra . De, der mener, at de skal brydes fra den stumpe ende, kaldes Big-endians ("stumpe ender") i arbejdet.

Tvister mellem big-endian og little-endian-tilhængere inden for datalogi har også ofte karakter af de såkaldte. "religiøse krige". [2] Udtrykkene big-endian og little-endian blev opfundet af Danny Cohen i 1980 i hans artikel On Holy Wars and a Plea for Peace .  [3] [4]

Se også

Noter

  1. pack() i Perl . Hentet 20. december 2010. Arkiveret fra originalen 13. december 2010.
  2. DAV's Endian FAQ (downlink) . Hentet 3. august 2008. Arkiveret fra originalen 10. november 2006. 
  3. Danny Cohen. On Holy Wars and a Plea for Peace  (engelsk) (1. april 1980). Dato for adgang: 24. januar 2010. Arkiveret fra originalen 15. februar 2012.
  4. Tanenbaum E. Computerarkitektur. - 5. udg. - Sankt Petersborg. : Peter, 2007. - 844 s. - S. 89.

Links