2.8 1 1 1 1 1 1 1 1 1 1 Рейтинг 2.80 (5 Голоса(ов)

Начинающим: что такое Big-Endian и Little-Endian

Знаю, что для начинающих разработчиков часто такая простая, вроде бы, вещь, как "порядок байтов" становится просто наказанием.

И даже знаю, почему... Пока мы работаем с байтами все вполне однозначно, но стоит перейти к словам, либо двойным словам, могут начаться "странности". Вроде бы нужно передать слово 0x1234. В эмуляторе разработчик видит 0x1234, переменную в отладчике ему показывают 0x1234 и все хорошо. Включаем прямой доступ к памяти, запускаем передачу... и принимаем на другом конце 0x3412.

И в институте, вроде, учили про Big-Endian и Little-Endian, да кто же вспоминает, чему там учили...

Всегда надо учитывать порядок данных при передаче от одного процессора к другому, иначе они банально могут друг-друга не понять, либо понять неверно.

Порядок от старшего к младшему (Big-endian)

Это привычный нам порядок записи. Слово 0x1234 будет храниться в памяти как два последовательных байта 0x12 0x34.

Big Endian
76543210
0 0 0 1 0 0 1 0
0 0 1 1 0 1 0 0

 

Длинное слово 0x12345678 будет лежать в памяти следующим образом: 0x12 0x34 0x56 0x78.

Big Endian
76543210
0 0 0 1 0 0 1 0
0 0 1 1 0 1 0 0
0 1 0 1 0 1 1 0
0 1 1 1 1 0 0 0

Такой порядок байт используется в TCP/IP, процессорах SPARC и 68k.

Порядок от младшего к старшему (Little-Endian)

При хранении данных в памяти в Little-Endian слово 0x1234 расположится в памяти так: 0x34 0x12.

Little Endian
76543210
0 0 1 1 0 1 0 0
0 0 1 0 0 0 1 1

 

Обратите внимание, что порядок бит в байте не меняется, так же как и порядок ниблов!!

Длинное слово 0x12345678 будет лежать в памяти следующим образом: 0x78 0x56 0x34 0x12.

Little Endian
76543210
0 1 1 1 1 0 0 0
0 1 0 1 0 1 1 0
0 1 0 0 0 0 1 1
0 0 1 0 0 0 0 1

То есть самый старший байт лежит по последнему байтовому адресу. Это необходимо учитывать, если Вы пытаетесь получить данные через указатели разных типов.

Например, банальный код

Код C:
unsigned char endian[2] = {1, 0}; short x;   x = *(short *) endian;
для машины с Big Endian выдаст в x значение 256, а для машины с Little Endian - 1.

Little-Endian характерен для USB, PCI, а также процессоров x86 и VAX.

Смешанный порядок (Middle-Endian)

Сами слова в пределах длинного слова могут лежать от старшего к младшему, однако в пределах слова используется порядок от младшего к старшему.

Двухбайтовое слово хранится аналогично Big Endian.

То есть длинное слово 0x12345678 будет представлено в памяти как гибрид Big Endian и Little Endian 0x34 0x12 0x78 0x56.

Middle Endian
76543210
0 0 1 1 0 1 0 0
0 0 0 1 0 0 1 0
0 1 1 1 1 0 0 0
0 1 0 1 0 1 1 0

Такой порядок использовался в PDP-11, есть ли на данный момент процессоры, использующие этот порядок расположения байт, мне не известно.


Некоторые процессоры (ARM, PowerPC) умеют работать с разным порядком байт, и его можно задать при конфигурировании процессора.

 Как писать хорошо переносимый код?

Естественный вопрос: как писать такой код, который не придется переписывать под каждую конкретную архитектуру процессора? Может ли программа сама определять порядок байт?

Да, может! И все давно придумано до нас. Приведу несколько примеров от IBM.

Пример 1

Код C:
const int i = 1; #define is_bigendian() ( (*(char*)&i) == 0 )   int main(void) { int val; char *ptr; ptr = (char*) &val; val = 0x12345678; if (is_bigendian()) { printf("%X.%X.%X.%X\n", u.c[0], u.c[1], u.c[2], u.c[3]); } else { printf("%X.%X.%X.%X\n", u.c[3], u.c[2], u.c[1], u.c[0]); } exit(0); }

Пример 2

Код C:
#define LITTLE_ENDIAN 0 #define BIG_ENDIAN 1   int endian() { int i = 1; char *p = (char *)&i;   if (p[0] == 1) return LITTLE_ENDIAN; else return BIG_ENDIAN; }

Оставьте свой комментарий

Оставить комментарий как гость

0
  • Комментариев нет
Начинающим: что такое Big-Endian и Little-Endian - 2.8 out of 5 based on 5 votes