Kolejność bajtów- Endianess - Programowanie jest łatwe

W książce "Podróże Guliwera" autorstwa Johnatan'a Swift'a występują dwa zwaśnione plemiona: Liliputów i Blefusków. Jedną z rzeczy, która ich podzieliła to strona, od której należy rozbijać ugotowane jajko. Król Lilipótów nakazał rozbijać jajko od jego większego końca i zabronił, pod karą wtrącenia do lochu, rozbijać jajko zaczynając od jego małej strony. Blefuskowie robili zaś dokładne odwrotnie. Ta historia konfliktu "końcówki" jajka po angielsku nazywa się "endianess" (ang. end- koniec).

Nazwy systemów określających kolejność bajtów wzięła się od końcówki jajka, od której zaczyna się jego konsupcję, źródło zdjęcia: https://commons.wikimedia.org/wiki/File:Egg_spiral_egg_cup.jpg

W świecie informatyki na początku powstawania standardów powstał podobny konflikt, ale nikt nie szedł za to do więzienia. Chodziło o rozróżnienie, w jaki sposób radzić sobie z umieszczaniem w pamięci poszczególnych bajtów dla wartości wielobajtowych.

Wyobraźmy sobie sytuację, w której mamy do czynienia z wartością 32-bitową. W pamięci komputera będzie ona zajmować 4 bajty. Dla przykładu podam tutaj wartość zapisaną w systemie szesnastkowym: 0x4b1a98ff. Dla nas naturalny jest zapis od lewej do prawej, czyli dokładnie tak, jak to zapisałem. Ten sposób umieszczania bajtów w pamięci nosi nazwę Big Endian Byte Order (w skrócie Big Endian).

Big Endian

W tym przypadku najbardziej znaczący bajt (czyli taki, który zawiera bit o największej wartości, a w przypadku zmiennych typu int- bit określający znak liczby- dodatnia albo ujemna) umieszczany jest jako pierwszy- w sensie pod najniższym adresem pamięci. Korzystając z wartości liczbowej powyżej i zakładając adresy pamięci kolejno 1001, 1002, etc., w pamięci mielibyśmy taki obrazek:

adres / wartość

1001 : 0x4b

1002 : 0x1a

1003 : 0x98

1004 : 0xff

Lilipuci byliby dumni. A co na to Blefuskowie?

Little endian

Little Endian Byte Order, czyli kolejność zapisywania bajtów w pamięci zaczynając od bajtu najmniej znaczącego. Czyli odwrotnie niż w przypadku Big Endian. Korzystając z przykładu powyżej, wartości w pamięci układały by się następująco:

adres/wartość

1001 : 0xff

1002 : 0x98

1003 : 0x1a

1004 : 0x4b

I co daje taki Little Endian? W przykładzie powyżej różnicy raczej nie ma i little endian wydaje się być bez sensu. Jeżeli jednak rozpatrujemy programowanie z perspektywy języka niskiego poziomu jakim jest asembler, to pisanie na architekturze little endian jest prostsze ponieważ do "niższych bajtów" (tych o niższym adresie) jest bardziej naturalny. Pomyśl jak wykonujesz operacje arytmetycznie pisemnie- zaczynasz od jedności (najmłodszych wartości) a kończysz na kolejnej potędze liczby 10 (najstarsze wartości). Operacje wykonujesz od najmniejszej do największej wartości- podobnie działa little endian.

Skąd to się wzięło

Inżynierowie to naprawdę dziwni ludzie i czasami wymyślają… A tak naprawdę, powód jest prozaiczny- dla niektórych układów cyfrowych jedna metoda ułatwia wiele spraw i nie ma tutaj konkretnego powodu dlaczego akurat big endian czy little endian.

Ile powinno mnie to obchodzić?

Zasadniczo nie aż tak wiele, dopóki nie zaczynasz bawić się z wartościami binarnymi. Kompilator robi sporo rzeczy za Ciebie- pisząc kod, który wczytuje binarnie wartości do pamięci układa je tam w należyty sposób. W momencie, gdy masz, np. plik z takimi wartościami, podejrzyj jego zawartość za pomocą hexedit- zobaczysz wtedy, że bajty są zapisane w odpowiedni dla architektury sposób. W przypadku procesorów Intel i AMD będzie to Little Endian.

Inne endianess’y

Aby nie wywołać globalnego, termonokluarnego konfliktu… a tak naprawdę to, aby ułatwić życie programistom stworzono "ujednolicony" sposób zapisywania bajtów, tzw. Network Byte Order. Jest to po prostu big endian. Ten mechanizm wykorzystuje się w transmisji danych przez sieć TCP/IP. Wszystkie bajty, które wychodzą z komputera little endian muszą być zmienione na big endian i odwrotnie w przypadku odbierania informacji.

Tak jak w przypadku liliputów, zdania informatyków są i były podzielone, który sposób jest lepszy. Jakie jest Twoje zdanie? Spotkałeś się z sytuacją, w której wiedza o kolejności bajtów była Tobie potrzebna? No i najważniejsze: którą stroną rozbijasz jajko?

Dodano: 2018-02-20 05:26 przez Piotr Poźniak

endianess , kolejność bajtów , big endian , little endian , netowork byte order , najstarszy bit , najmłodszy bit ,
Piotr Poźniak
O autorze:

Programuję od ponad 15 lat. Prowadzę software house. Angażuję i zachęcam wszystkich do programowania w ramach inicjatywy Programowanie jest łatwe.