Endianness
- HistoryEdit
- Obecne architekturyEdit
- Bi-endiannessEdit
- Floating pointEdit
- Dane o zmiennej długościEdit
- OptimizationEdit
- Kolejność obliczeńEdit
- Operacje rozpoczynające się od najmniej znaczącej cyfryEdit
- Operacje rozpoczynające się od najbardziej znaczącej cyfryEdit
- Operandy o zmiennej długościEdit
- Operacje bez wpływuEdit
- Middle-endianEdit
- PDP-endianEdit
- Honeywell Series 16Edit
- Deskryptory segmentów Intel IA-32Edit
HistoryEdit
Wiele historycznych i istniejących procesorów używa reprezentacji pamięci big-endian, wyłącznie lub jako opcji projektowej. Reprezentacja pamięci big-endian jest powszechnie określana jako porządek sieciowy, używany w pakiecie protokołów internetowych. Inne typy procesorów używają reprezentacji pamięci little-endian; inne używają jeszcze innego schematu zwanego „middle-endian”, „mixed-endian” lub „PDP-11-endian”.
IBM System/360 używa kolejności bajtów big-endian, podobnie jak jego następcy System/370, ESA/390 i z/Architecture. PDP-10 również używa adresowania big-endian dla instrukcji zorientowanych na bajty. Minikomputer IBM Series/1 również używa big-endian byte order.
Radzenie sobie z danymi o różnej endianiczności jest czasami określane jako problem NUXI. Ta terminologia nawiązuje do konfliktów kolejności bajtów napotkanych podczas adaptacji UNIX-a, który działał na PDP-11 w układzie mixed-endian, do komputera IBM Series/1 w układzie big-endian. Unix był jednym z pierwszych systemów, który pozwalał na kompilację tego samego kodu na platformy o różnych reprezentacjach wewnętrznych. Jeden z pierwszych przekonwertowanych programów miał wydrukować Unix
, ale na Series/1 zamiast tego wydrukował nUxi
.
Datapoint 2200 używa prostej logiki bitowo-seryjnej z little-endian, aby ułatwić propagację przenoszenia. Kiedy Intel opracował mikroprocesor 8008 dla Datapoint, użył little-endian dla kompatybilności. Jednak, ponieważ Intel nie był w stanie dostarczyć 8008 na czas, Datapoint użył odpowiednika o średniej skali integracji, ale little-endianness został zachowany w większości projektów Intela, w tym MCS-48 i 8086 i jego następców x86. DEC Alpha, Atmel AVR, VAX, rodzina MOS Technology 6502 (w tym Western Design Center 65802 i 65C816), Zilog Z80 (w tym Z180 i eZ80), Altera Nios II i wiele innych procesorów i rodzin procesorów są również little-endian.
Procesory Motorola 6800 / 6801, 6809 i seria procesorów 68000 używały formatu big-endian.
Intel 8051, w przeciwieństwie do innych procesorów Intela, oczekuje 16-bitowych adresów dla LJMP i LCALL w formacie big-endian; jednak instrukcje xCALL przechowują adres zwrotny na stosie w formacie little-endian.
SPARC historycznie używał big-endian do wersji 9, która jest bi-endian; podobnie wczesne procesory IBM POWER były big-endian, ale PowerPC i potomkowie Power ISA są teraz bi-endian. Architektura ARM była little-endian przed wersją 3, kiedy stała się bi-endian.
Obecne architekturyEdit
Serie procesorów Intel x86 i AMD64 / x86-64 używają formatu little-endian. Inne architektury zestawów instrukcji, które podążają za tą konwencją, pozwalając tylko na tryb little-endian, obejmują Nios II, Andes Technology NDS32 i Qualcomm Hexagon.
Niektóre architektury zestawów instrukcji pozwalają na uruchamianie oprogramowania z obu endianness na architekturze bi-endian. Obejmuje to ARM AArch64, C-Sky, Power ISA i RISC-V.
Same architektury big-endian obejmują IBM z/Architektura, Freescale ColdFire (który jest oparty na serii Motorola 68000), Atmel AVR32 i OpenRISC. Systemy operacyjne IBM AIX i Oracle Solaris na bi-endian Power ISA i SPARC działają w trybie big-endian; niektóre dystrybucje Linuksa na Power przeszły na tryb little-endian.
Bi-endiannessEdit
Niektóre architektury (włączając ARM wersje 3 i wyższe, PowerPC, Alpha, SPARC V9, MIPS, PA-RISC, SuperH SH-4 i IA-64) posiadają ustawienie, które pozwala na przełączanie endianness w pobieraniu i przechowywaniu danych, pobieraniu instrukcji lub obu. Ta cecha może poprawić wydajność lub uprościć logikę urządzeń sieciowych i oprogramowania. Słowo bi-endian, gdy mówi się o sprzęcie, oznacza zdolność maszyny do obliczania lub przekazywania danych w obu formatach endian.
Wiele z tych architektur można przełączyć za pomocą oprogramowania, aby domyślnie do określonego formatu endian (zwykle zrobić, gdy komputer się uruchamia); jednak w niektórych systemach domyślna endianness jest wybierany przez sprzęt na płycie głównej i nie może być zmieniony przez oprogramowanie (np.Alpha, która działa tylko w trybie big-endian na Cray T3E).
Zauważ, że termin bi-endian odnosi się przede wszystkim do tego, jak procesor traktuje dostęp do danych. Dostęp do instrukcji (pobieranie słów instrukcji) na danym procesorze może nadal przyjmować stałą endianness, nawet jeśli dostęp do danych są w pełni bi-endian, choć nie zawsze tak jest, takich jak w Intel IA-64 opartych Itanium CPU, który pozwala na oba.
Zauważ też, że niektóre nominalnie bi-endian CPU wymagają pomocy płyty głównej, aby w pełni przełączyć endianness. Na przykład, 32-bitowe desktopowe procesory PowerPC w trybie little-endian działają jako little-endian z punktu widzenia wykonywanych programów, ale wymagają płyty głównej do wykonania 64-bitowej zamiany na wszystkich 8 bajtowych ścieżkach, aby zapewnić, że little-endian widok rzeczy będzie miał zastosowanie do urządzeń I/O. W przypadku braku tego niezwykłego sprzętu na płycie głównej, oprogramowanie sterownika urządzenia musi zapisywać pod różnymi adresami, aby cofnąć niekompletną transformację, a także musi wykonać normalną zamianę bajtów.
Niektóre procesory, takie jak wiele procesorów PowerPC przeznaczonych do użytku wbudowanego i prawie wszystkie procesory SPARC, pozwalają na wybór endianness per-page.
Procesory SPARC od końca lat 90-tych (procesory zgodne z SPARC v9) pozwalają na wybór endianness danych w każdej indywidualnej instrukcji, która ładuje z lub zapisuje do pamięci.
Architektura ARM obsługuje dwa tryby big-endian, zwane BE-8 i BE-32. Procesory do ARMv5 obsługują tylko BE-32 lub tryb word-invariant. Tutaj każdy naturalnie wyrównany dostęp 32-bitowy działa jak w trybie little-endian, ale dostęp do bajtu lub 16-bitowego słowa jest przekierowywany do odpowiedniego adresu, a dostęp bez wyrównania nie jest dozwolony. ARMv6 wprowadza BE-8 lub tryb byte-invariant, w którym dostęp do pojedynczego bajtu działa jak w trybie little-endian, ale dostęp do 16-bitowego, 32-bitowego lub (począwszy od ARMv8) 64-bitowego słowa powoduje zamianę danych bajtami. Upraszcza to dostęp do niepodlegającej wyrównaniu pamięci, jak również mapowany w pamięci dostęp do rejestrów innych niż 32-bitowe.
Wiele procesorów ma instrukcje do konwersji słowa w rejestrze na przeciwną endianness, to znaczy zamieniają kolejność bajtów w 16-, 32- lub 64-bitowym słowie. Wszystkie poszczególne bity nie są jednak odwracane.
Późniejsze procesory Intel x86 i architektury x86-64 mają instrukcję MOVBE (Intel Core od generacji 4, po Atom), która pobiera słowo w formacie big-endian z pamięci lub zapisuje słowo do pamięci w formacie big-endian. Procesory te są poza tym dokładnie little-endian. Miały też już szereg instrukcji swap do odwracania kolejności bajtów zawartości rejestrów, np. gdy słowa zostały już pobrane z miejsc w pamięci, gdzie były w „niewłaściwej” endianiczności.
Floating pointEdit
Although the ubiquitous x86 processors of today use little-endian storage for all types of data (integer, floating point), there are a number of hardware architectures where floating-point numbers are represented in big-endian form while integers are represented in little-endian form. Istnieją procesory ARM, które mają pół little-endian, pół big-endian reprezentacji zmiennoprzecinkowej dla liczb podwójnej precyzji: oba 32-bitowe słowa są przechowywane w little-endian jak rejestry liczb całkowitych, ale najbardziej znaczący najpierw. Ponieważ istniało wiele formatów zmiennoprzecinkowych bez „sieciowej” standardowej reprezentacji dla nich, standard XDR używa big-endian IEEE 754 jako swojej reprezentacji. Może się więc wydawać dziwne, że szeroko rozpowszechniony standard zmiennoprzecinkowy IEEE 754 nie określa endianiczności. Teoretycznie oznacza to, że nawet standardowe dane zmiennoprzecinkowe IEEE zapisane przez jedną maszynę mogą nie być możliwe do odczytania przez inną. Jednakże, na nowoczesnych standardowych komputerach (tj. implementujących standard IEEE 754), można w praktyce bezpiecznie założyć, że endianness jest taka sama dla liczb zmiennoprzecinkowych jak dla liczb całkowitych, co czyni konwersję prostą niezależnie od typu danych. (Małe systemy wbudowane używające specjalnych formatów zmiennoprzecinkowych mogą być jednak inną sprawą.)
Dane o zmiennej długościEdit
Większość instrukcji rozważanych do tej pory zawiera rozmiary (długości) swoich operandów wewnątrz kodu operacji. Często dostępne długości operandów to 1, 2, 4, 8 lub 16 bajtów. Istnieją jednak również architektury, w których długość operandu może być przechowywana w osobnym polu instrukcji lub z samym operandem, np. za pomocą znaku słowa. Takie podejście pozwala na operandy o długości do 256 bajtów lub nawet do pełnego rozmiaru pamięci.Typami danych takich operandów są ciągi znaków lub BCD.
Maszyny zdolne do manipulowania takimi danymi za pomocą jednej instrukcji (np. porównaj, dodaj) to np. IBM 1401, 1410, 1620, System/3×0, ESA/390 i z/Architektura, wszystkie typu big-endian.
OptimizationEdit
System little-endian ma tę właściwość, że ta sama wartość może być odczytywana z pamięci o różnej długości bez użycia różnych adresów (nawet gdy nałożone są ograniczenia wyrównania). Na przykład, 32-bitowa lokalizacja pamięci o zawartości 4A 00 00 00
może być odczytana pod tym samym adresem jako 8-bitowa (wartość = 4A), 16-bitowa (004A), 24-bitowa (00004A) lub 32-bitowa (0000004A), z których wszystkie zachowują tę samą wartość liczbową. Chociaż ta właściwość little-endian jest rzadko używana bezpośrednio przez programistów wysokiego poziomu, jest często wykorzystywana przez optymalizatory kodu, jak również przez programistów języka asemblera.
W bardziej konkretnych kategoriach, takie optymalizacje są odpowiednikiem następującego kodu C zwracającego true na większości systemów little-endian:
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");
Choć nie jest to dozwolone przez C++, taki kod typu punning jest dozwolony jako „zdefiniowany przez implementację” przez standard C11 i powszechnie używany w kodzie współdziałającym ze sprzętem.
Z drugiej strony, w niektórych sytuacjach może być użyteczne uzyskanie przybliżenia wartości wielobajtowej lub wielowyrazowej przez odczytanie tylko jej najbardziej znaczącej części zamiast pełnej reprezentacji; procesor big-endian może odczytać takie przybliżenie używając tego samego adresu bazowego, który byłby użyty dla pełnej wartości.
Optymalizacje tego rodzaju nie są przenośne przez systemy o różnej endianiczności.
Kolejność obliczeńEdit
Niektóre operacje w pozycyjnych systemach liczbowych mają naturalną lub preferowaną kolejność, w której mają być wykonywane kroki elementarne.Ta kolejność może wpływać na ich wydajność na małych procesorach z adresacją bajtową i mikrokontrolerach.
Jednakże wysokowydajne procesory zazwyczaj pobierają typowe wielobajtowe operandy z pamięci w tym samym czasie, w którym pobierałyby pojedynczy bajt, więc złożoność sprzętu nie jest dotknięta przez kolejność bajtów.
Operacje rozpoczynające się od najmniej znaczącej cyfryEdit
Dodawanie, odejmowanie i mnożenie rozpoczynają się od pozycji najmniej znaczącej cyfry i propagują przeniesienie do kolejnej, bardziej znaczącej pozycji.Adresowanie danych wielocyfrowych w ich pierwszym (= najmniejszym adresie) bajcie jest dominującym schematem adresowania.Gdy ten pierwszy bajt zawiera najmniej znaczącą cyfrę – co jest równoważne z małą endiancją, wtedy implementacja tych operacji jest minimalnie prostsza.
Operacje rozpoczynające się od najbardziej znaczącej cyfryEdit
Porównywanie i dzielenie rozpoczynają się od najbardziej znaczącej cyfry i propagują ewentualne przeniesienie do kolejnych mniej znaczących cyfr. Dla wartości liczbowych o stałej długości (typowo o długości 1,2,4,8,16), implementacja tych operacji jest marginalnie prostsza na maszynach big-endian.
Operandy o zmiennej długościEdit
Wiele procesorów big-endian zawiera instrukcje sprzętowe do leksykograficznego porównywania ciągów znaków o zmiennej długości (np. IBM System/360 i jego następcy).
Operacje bez wpływuEdit
Normalny transport danych przez instrukcję przypisania jest w zasadzie niezależny od endianness procesora.
Middle-endianEdit
Numerous inne porządki, ogólnie nazywane middle-endian lub mixed-endian, są możliwe. Jednym z takich przykładów poza informatyką jest standardowe amerykańskie formatowanie daty: miesiąc/dzień/rok.
PDP-endianEdit
PDP-11 jest w zasadzie 16-bitowym systemem little-endian. Instrukcje konwersji między wartościami zmiennoprzecinkowymi i całkowitymi w opcjonalnym procesorze zmiennoprzecinkowym w PDP-11/45, PDP-11/70 i w niektórych późniejszych procesorach przechowywały 32-bitowe wartości „double precision integer long” z 16-bitowymi połówkami zamienionymi w stosunku do oczekiwanej kolejności little-endian. Kompilator UNIX C używał tego samego formatu dla 32-bitowych długich liczb całkowitych. To uporządkowanie jest znane jako PDP-endian.
Sposób interpretacji tej endianness jest taki, że przechowuje 32-bitową liczbę całkowitą jako dwa 16-bitowe słowa w big-endian, ale same słowa są little-endian (E.np. „jag cog sin” byłoby „gaj goc nis”):
rosnące adresy → | |||||
0Bh | 0Ah | 0Dh | 0Ch | ||
0A0Bh | 0C0Dh |
Wartości 16-bitowe odnoszą się tutaj do ich wartości numerycznych, a nie do ich rzeczywistego układu.
Honeywell Series 16Edit
Komputery 16-bitowe Honeywell Series, w tym Honeywell 316, są przeciwieństwem PDP-11 w przechowywaniu słów 32-bitowych w języku C. Przechowuje każde 16-bitowe słowo w kolejności big-endian, ale łączy je ze sobą w sposób little-endian:
rosnące adresy → | |||||
0Ch | 0Dh | 0Ah | 0Bh | ||
0C0Dh | 0A0Bh |
Deskryptory segmentów Intel IA-32Edit
Deskryptory segmentów procesorów IA-32 i procesorów zgodnych zachowują 32-bitowy adres bazowy segmentu przechowywany w porządku little-endian, ale w czterech nie następujących po sobie bajtach, na względnych pozycjach 2, 3, 4 i 7 początku deskryptora.
.