Little endian и big endian что это
Перейти к содержимому

Little endian и big endian что это

  • автор:

Порядок байтов

В вычислительной технике и цифровых системах связи информация обычно представлена в виде последовательности байтов. В том случае, если число не может быть представлено одним байтом, имеет значение, в каком порядке байты записываются в памяти компьютера или передаются по линиям связи. Часто выбор порядка записи байтов произволен и определяется только соглашениями.

От старшего к младшему (big-endian)

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

Этот порядок соответствует привычному порядку записи арабских цифр, например, число сто двадцать три было бы записано при таком порядке как 123. В этом же порядке принято записывать байты в технической и учебной литературе, если другой порядок явно не обозначен.

Этот порядок является стандартным для протоколов TCP/IP, он используется в заголовках пакетов данных и во многих протоколах более высокого уровня, разработанных для использования поверх TCP/IP. Поэтому порядок байтов от старшего к младшему часто называют «сетевым порядком байтов» (network byte order). Этот порядок байтов используется процессорами IBM 360/370/390, SPARC, Motorola 68000 (отсюда третье название — порядок байтов Motorola, Motorola byte order).

От младшего к старшему (little-endian)

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

Это обратный порядок по отношению к привычному порядку записи арабских цифр, например, число сто двадцать три было бы записано при таком порядке как 321.

Этот порядок записи принят в памяти персональных компьютеров с процессорами архитектуры x86, в связи с чем иногда его называют интеловский порядок байтов (по названию компании-создателя архитектуры x86). Современные процессоры x86 позволяют работать с одно-, двух-, четырёх- и восьмибайтовыми операндами. При таком порядке байтов очень удобно то обстоятельство, что при увеличении размера (количества байт) операнда, значение его первого байта остаётся прежним: 3210 → 3210’0000. При порядке от старшего к младшему значение изменилось бы, например: 0123 → 0000’0123;

Кроме x86, такой порядок байтов применяется в архитектурах VAX, DEC Alpha, Zilog Z80 и многих других.

Переключаемый порядок (bi-endian)

Многие процессоры могут работать и в порядке от младшего к старшему, и в обратном, например, ARM (по умолчанию — little endian), PowerPC (но не PowerPC 970), DEC Alpha, MIPS, PA-RISC и IA-64. Обычно порядок байтов выбирается программно во время инициализации операционной системы, но может быть выбран и аппаратно перемычками на материнской плате. В этом случае правильнее говорить о порядке байтов операционной системы.

Little endian и big endian что это

Понятие Byte order, или порядок следования байт (или endianness) относится к очередности размещения в памяти многобайтовых величин (обычно целых чисел и чисел с плавающей точкой; хотя числа с плавающей точкой не используются в Linux kernel, они могут работать в пользовательских программах), как это поддерживается аппаратурой процессора. Соответственно бывает 2 варианта порядка байт — big endian и little endian. Big endian это такой порядок байт, когда самый значимый по значению байт числа (most significant byte) сохранен в памяти первым по порядку (т. е. у него самый маленький абсолютный адрес байта, в сравнении с остальными байтами числа). Соответственно little endian это противоположный порядок байт, когда наименее значимый байт сохраняется в памяти первым.

Чтобы было понятнее, рассмотрим пример. 4-байтное целое число 0x01020304 будет сохранено в памяти системы big endian следующим образом:

Байт0 Байт1 Байт2 Байт3
0x01 0x02 0x03 0x04

Big endian всегда используется для так называемого сетевого порядка байт (network byte order), который применяется при кодировании адресов в сетевых протоколах.

Та же самая величина, которая будет храниться в памяти системы little endian, разместится в противоположном порядке:

Байт0 Байт1 Байт2 Байт3
0x04 0x03 0x02 0x01

Обычно при программировании можно не обращать внимания на endianness, то есть не важно, как процессор сохранит байты чисел в системе — big endian или little endian; ядро CPU просто загружает данные из памяти и сохраняет данные в память, и представляет данные в Вашей программе уже в правильном виде. Однако, когда нужно обмениваться данными с другой системой, обе системы должны учитывать формат хранения данных в памяти (endianness).

Linux kernel может быть либо big endian, либо little endian, в зависимости от архитектуры, в расчете на которую kernel скомпилировано. Ниже в таблице показан endianness для различных типов архитектур процессоров и протоколов.

Примечание: процессор ARM может быть либо с архитектурой big endian, либо little endian, в зависимости от типа применяемого чипа, однако чаще всего это big endian. Архитектура PowerPC может быть сконфигурирована для работы либо в режиме big endian, либо little endian, но в Linux используется только big endian.

[Почему следует беспокоиться об endianness]

Как уже упоминалось, порядок байт на низком уровне в системе полностью прозрачен для программиста (про endianness можно часто забыть). Однако могут быть проблемы, когда происходит обмен данными с другой системой, поскольку эта другая система может ожидать появления данных в блоке памяти в противоположном порядке.

Например, если заранее нельзя предсказать тип системы на каком-то дальнем окончании сетевого соединения, сетевые протоколы должны заранее определить порядок байт, используемый для хранения многобайтных величин в заголовках пакетов. В этом случае порядок байт называют сетевым порядком байт (network byte order), и для протокола TCP/IP это будет big endian. Таким образом, отправляющая пакеты система конвертирует данные из локального порядка хранения байт в сетевой. После этого принимающая система преобразует данные из сетевого порядка байт в локальный. На практике, когда есть жесткие требования к быстродействию и заранее известно, что локальный порядок байт такой же, как сетевой, операция конверсии отбрасывается в целях оптимизации.

Другой хороший пример — протокол USB, у которого порядок байт для многобайтных величин little endian.

[Как программно определить endianness]

Можно написать простую программу, которая будет определять порядок байт в имеющейся системе.

1 2 3 4 5 6 7 8 9 10
union < int i; char c[sizeof(int)]; > foo; foo.i = 1;
if (foo.c[0] == 1) printf("Little endian\n");
else printf("Big endian\n");

Строки 1..4 определяют переменную foo, к которой можно обращаться либо как к числу типа int (тип int почти всегда состоит из нескольких байт) или как к массиву символов characters. На строке 6 переменная инициализируется целым значением 1, так что как минимум один байт в многобайтном числе станет равен 1 (наименее значащий байт), а все остальные значащие байты будут нулями. Если байт 0 массива наименее значимый, то он станет равным 1, и это означает, что система little endian. Если байт 0 массива самый значимый байт, то он будет нулем, и значит система big endian.

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

[Идентификаторы типов]

Следующие идентификаторы соответствуют типам u16, u32 и u64, за исключением случаев, когда они определены с поразрядным (bitwise) атрибутом, который вводят для ограничения применения их как целых чисел. Bitwise-атрибут используется утилитой sparse, чтобы гарантировать, что переменная преобразована в локальный тип процессора перед тем, как над переменной выполнятся другие (небезопасные, unsafe) операции.

Следующие типы можно применять для endian-зависимых переменных, после подключения header-файла linux/kernel.h.

__le16 __le32 __le64 __be16 __be32 __be64

[Макросы для преобразований]

Имеется множество макросов для преобразования порядка байт, используемого текущим процессором, в порядок либо big, либо little endian. Дополнительно для каждого типа конверсии имеются отдельные макросы для 16-, 32- и 64-разрядных значений. Имена макросов кодируют исходный и целевой порядок байт значения, так что по имени сразу понятно, что каждый макрос делает.

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

Следующие макросы вернут значение после конвертации. Обратите внимание, что заголовочный файл linux/kernel.h является заголовком, который должен быть подключен к файлам исходного кода, где макросы используются, но это не тот файл заголовка, где макросы реально определены.

#include < linux/kernel.h > 
__u16 le16_to_cpu(const __le16); __u32 le32_to_cpu(const __le32); __u64 le64_to_cpu(const __le64); __le16 cpu_to_le16(const __u16); __le32 cpu_to_le32(const __u32); __le64 cpu_to_le64(const __u64); __u16 be16_to_cpu(const __be16); __u32 be32_to_cpu(const __be32); __u64 be64_to_cpu(const __be64); __be16 cpu_to_be16(const __u16); __be32 cpu_to_be32(const __u32); __be64 cpu_to_be64(const __u64);

Следующие макросы такие же, как и предыдущие, отличие только в том, что параметр макроса — это указатель на преобразуемую величину. Обратите внимание, что имена этих макросов такие же, только добавлен суффикс «p» (от слова pointer) в конце каждого имени.

#include < linux/kernel.h > 
__u16 le16_to_cpup(const __le16 *); __u32 le32_to_cpup(const __le32 *); __u64 le64_to_cpup(const __le64 *); __le16 cpu_to_le16p(const __u16 *); __le32 cpu_to_le32p(const __u32 *); __le64 cpu_to_le64p(const __u64 *); __u16 be16_to_cpup(const __be16 *); __u32 be32_to_cpup(const __be32 *); __u64 be64_to_cpup(const __be64 *); __be16 cpu_to_be16p(const __u16 *); __be32 cpu_to_be32p(const __u32 *); __be64 cpu_to_be64p(const __u64 *);

Следующие макросы делают то же самое, что и предыдущие, но здесь место расположения исходной величины и преобразованной величины совпадают. Обратите внимание, что имена этих макросов такие же, только добавлен суффикс «s» (от латинской фразы in situ, что обозначает «в том же месте») в конце каждого имени.

#include < linux/kernel.h >
void le16_to_cpus(__u16 *);
void le32_to_cpus(__u32 *);
void le64_to_cpus(__u64 *);
void cpu_to_le16s(__u16 *);
void cpu_to_le32s(__u32 *);
void cpu_to_le64s(__u64 *);
void be16_to_cpus(__u16 *);
void be32_to_cpus(__u32 *);
void be64_to_cpus(__u64 *);
void cpu_to_be16s(__u16 *);
void cpu_to_be32s(__u32 *);
void cpu_to_be64s(__u64 *);

Следующие макросы предоставляют алиасы для имен функций, которые обычно применяются для преобразования порядка байт в коде сетевых приложений. Первые два макроса используются для преобразования из локального в сетевой порядок байт. Остальные два предоставляют обратное преобразование. Буквы «s» и «l» в конце имен в этом случае означают short (16-битное значение) и long (32-битное значение).

#include < linux/kernel.h >
#define htons(x) cpu_to_be16(x)
#define htonl(x) cpu_to_be32(x)
#define ntohs(x) be16_to_cpu(x)
#define ntohl(x) be32_to_cpu(x) 

Как отмечалось ранее, сетевой порядок байт всегда big endian, и реализация этих макросов гарантирует корректное использование порядка байт сетевым хостом.

[Отличия между шинами BE-32 и BE-8]

Различия между обработкой шин данных Word-Invariant, или BE-32, и Byte-Invariant, или BE-8, следующее (BE означает Big Endian):

● В системе BE-32, Word-Invariant, представление 32-битного доступа по шине к слову (word access) является одинаковым в сравнении с доступом LE (Little Endian) к одному и тому же адресу слова. Однако представление байтового доступа шины (byte access) и доступа к половине слова (half-word access) различается.
● В BE-8, Byte Invariant, система представляет байтовый доступ одинаковым в сравнении с доступом LE к одному и тому же байтовому адресу.

Причем в обоих реализациях big-endian доступа BE-32 и BE-8 самый малый байтовый адрес соответствует самому значимому байту.

Таблица ниже показывает эффект доступа LE, BE-8 и BE-32 на 64-разрядной шине. Базовая форма для доступа к байту столбцов LE и BE-8 одинаковая, и также она одинаковая для доступа к слову столбцов LE и BE-32.

Примечание: в обоих случаях BE-8 и BE-32, доступ к байту по адресу 0 (самый младший адрес в системе) соответствует самому старшему байту доступа к слову, поэтому соответствует описанию big-endian.

Биты
шины
данных
Байтовый доступ
Доступ к половине слова
Доступ к слову
LE BE8 BE32 LE BE8 BE32 LE BE8 BE32
63:56 A7 A7 A4 A6:MS A6:LS A4:MS A4:MS A4:LS A4:MS
55:48 A6 A6 A5 A6:LS A6:MS A4:LS A4:MS-1 A4:LS+1 A4:MS-1
47:40 A5 A5 A6 A4:MS A4:LS A6:MS A4:LS+1 A4:MS-1 A4:LS+1
39:32 A4 A4 A7 A4:LS A4:MS A6:LS A4:LS A4:MS A4:LS
31:24 A3 A3 A0 A2:MS A2:LS A0:MS A0:MS A0:LS A0:MS
23:16 A2 A2 A1 A2:LS A2:MS A0:LS A0:MS-1 A0:LS+1 A0:MS-1
15:8 A1 A1 A2 A0:MS A0:LS A2:MS A0:LS+1 A0:MS-1 A0:LS+1
7:0 A0 A0 A3 A0:LS A0:MS A2:LS A0:LS A0:MS A0:LS

Пояснения к таблице:

A < Num >Доступ к байту к address[2:0] = Num.
A< Num >: < Byte >Байт < Byte >доступа к слову / половине слова к address[2:0]=Num.
< Byte >: MS Самый значимый байт.
MS-1 Следующий по значимости байт.
LS+1 Следующий по минимуму значимости байт.
LS Наименее значимый байт.

[Ссылки]

1. Byte Order site:bruceblinn.com .
2. Макросы для реверсирования порядка байт.
3. Differences between BE-32 and BE-8 buses site:developer.arm.com.

Порядок байт

Поря́док ба́йтов в информатике — метод записи байтов многобайтовых чисел.

В общем случае, когда нужно компактно записать число, большее 255 ( 2 8 − 1 = 255 — максимальное целое число, записываемое одним байтом (октетом)) необходимо использовать несколько байтов. Число M факторизуется по основанию 256:

M = \sum_<i=0></p>
<p>^A_i\cdot 256^i=A_0\cdot 256^0+A_1\cdot 256^1+A_2\cdot 256^2+\dots+A_n\cdot 256^n» width=»» height=»» /></p>
<p><img decoding=

Набор чисел и является последовательностью байтов для записи.

Варианты записи

Порядок от младшего к старшему

A_0,\dots,A_n

Порядок от младшего к старшему или «остроконечный» (англ. little-endian , о происхождении термина ниже): , запись начинается с младшего и заканчивается старшим. Этот порядок записи принят в памяти персональных компьютеров с интеловский порядок байтов (по названию фирмы-создателя архитектуры x86).

Порядок от старшего к младшему

A_n,\dots,A_0

Порядок от старшего к младшему или «тупоконечный» (англ. big-endian ): , запись начинается со старшего и заканчивается младшим. Этот порядок является стандартным для протоколов TCP/IP, он используется в заголовках пакетов данных и во многих протоколах более высокого уровня, разработанных для использования поверх TCP/IP. Поэтому, порядок байтов от старшего к младшему часто называют сетевым порядком байтов (англ. network byte order ). Этот порядок байтов используется процессорами IBM 360/370/390, Motorola 68000, порядок байтов Motorola, Motorola byte order).

В этом же виде (но с факторизацией по основанию 10) записываются числа индийско-арабскими цифрами.

Порядок байтов от старшего к младшему применяется в многих форматах файлов — например, PNG.

Переключаемый порядок

Многие процессоры могут работать и в порядке от младшего к старшему, и в обратном, например, PowerPC (но не PowerPC 970), DEC Alpha, MIPS, IA-64. Обычно порядок байтов выбирается программно во время инициализации операционной системы, но может быть выбран и аппаратно перемычками на материнской плате. В этом случае правильнее говорить о порядке байтов операционной системы. Переключаемый порядок байтов иногда называют англ. bi-endian .

Смешанный порядок

Смешанный порядок байтов (англ. middle-endian) иногда используется при работе с числами, длина которых превышает машинное слово. Производится факторизация числа на машинные слова, которые записываются в формате, естественном для данной архитектуры, но сами слова записываются в обратном порядке.

Классический пример middle-endian — представление 4-байтных целых чисел на 16-битных процессорах семейства

В процессорах ARM используется смешанное представление для длинных вещественных чисел.

Пример

Далее приведён пример, в котором описывается размещение 4-байтового числа в ОЗУ ЭВМ, доступ к которому может производиться как к 32-разрядному слову, так и побайтно.

Все числа записаны в 16-тиричной системе счисления.

Число: 0xA1B2C3D4 Факторизация : D4*0x01 + C3*0x100 + B2*0x10000 + A1*0x1000000 Порядок от младшего к старшему (little-endian) : 0xD4, 0xC3, 0xB2, 0xA1 Порядок от старшего к младшему (big-endian) : 0xA1, 0xB2, 0xC3, 0xD4 Порядок, принятый в PDP-11 (PDP-endian) : 0xB2, 0xA1, 0xD4, 0xC3

Сравнение

Размещение байтов слова в памяти Big-endian и Little-endian ЭВМ

Существенным достоинством little-endian по сравнению с big-endian порядком записи считается возможность «неявной типизации» целых чисел при чтении меньшего объёма байт (при условии, что читаемое число помещается в диапазон). Так, если в ячейке памяти содержится число 0x00000022, то прочитав его как int16 (два байта) мы получим число 0x0022, прочитав один байт — число 0x22.

Обратно, считается что у little-endian, по сравнению с big-endian есть «неочевидность» значения байтов памяти при отладке (последовательность байтов (33, 44, 55, 12) на самом деле значит 0x12554433, для big-endian эта последовательность (33, 44, 55, 12) читалась бы «естественным» для арабской записи чисел образом: 0x33445512). Наименее удобным в работе считается middle-endian формат записи; он сохранился только на старых платформах.

Для записи длинных чисел (чисел, длина которых существенно превышает разрядность машины) обычно предпочтительнее порядок слов в числе little-endian (поскольку арифметические операции над длинными числами производятся от младших разрядов к старшим). Порядок байтов в слове — обычный для данной архитектуры.

Проблемы совместимости

Запись многобайтового числа из памяти компьютера в файл или передача по сети требует соблюдения соглашений о том, какой из байтов является старшим, а какой младшим. Прямая запись ячеек памяти приводит к возможным проблемам при переносе приложения с платформы на платформу.

Определение порядка байтов

Порядок байтов в конкретной машине можно определить с помощью программы на языке Си (testendian.c):

  Вывод данной программы осмыслен только на платформах, где размер типа unsigned short больше, чем размер типа unsigned char. Это заведомо верно на подавляющем большинстве компьютеров, так как они имеют 8-разрядный байт. Однако существуют и аппаратные платформы с 32-разрядным байтом.

Результаты запуска на big-endian машине (

Результаты запуска на little-endian машине (

Конвертация

Для преобразования между сетевым порядком байтов (англ. network byte order ), который всегда big-endian, и порядком байтов, использующимся на машине (англ. host byte order ), стандарт htonl() , htons() , ntohl() , ntohs() :

  • uint32_t htonl(uint32_t hostlong); — конвертирует из текущего порядка байтов в сетевой 32-битную беззнаковую величину;
  • uint16_t htons(uint16_t hostshort); — конвертирует из текущего порядка байтов в сетевой 16-битную беззнаковую величину;
  • uint32_t ntohl(uint32_t netlong); — конвертирует из сетевого порядка байтов в текущий 32-битную беззнаковую величину;
  • uint16_t ntohs(uint16_t netshort); — конвертирует из сетевого порядка байтов в текущий 16-битную беззнаковую величину.

В случае совпадения текущего порядка байтов и сетевого, функции могут быть «пустыми» (то есть, не менять порядка байтов). Стандарт также допускает, чтобы эти функции были реализованы макросами.

Интересные факты

  • Термины big-endian и little-endian первоначально не имели отношения к информатике. В сатирическом произведении Джонатана Свифта «Путешествия Гулливера» описываются вымышленные государства Лилипутия и Блефуску, в течение многих лет ведущие между собой войны из-за разногласия по поводу того, с какого конца следует разбивать варёные яйца. Тех, кто считает, что их нужно разбивать с тупого конца, в произведении называют «Big-endians» («тупоконечники»). Споры между сторонниками big-endian и little-endian в информатике также часто носят характер «религиозных войн».

См. также

Ссылки

  • Сетевой порядок байтов, функции htons(), htonl(), ntohs(), ntohl()
  • Порядок байтов
  • Порядок байтов
  • http://www.rdrop.com/~cary/html/endian_faq.html (англ.)

Little endian и big endian что это

1) На Раздел распространяются все Правила Форума.
2) Перед тем, как создать новый топик, убедитесь, что Вы читали Правила создания тем в Разделе.
3) Вопросы, не связанные с программированием (настройки MS Visual Studio, книги, библиотеки и т.д.),
обсуждаются в разделе C/C++: Прочее
4) Вопросы разработки .NET (Windows Form, C++/CLI и т.п.) приложений на Visual C++/C# обсуждаются в разделе .NET.
5) Нарушение Правил может повлечь наказание со стороны модераторов.

Модераторы: ElcnU
‘> Что это: big-endian и little-endian ?

  • Подписаться на тему
  • Сообщить другу
  • Скачать/распечатать тему

Сообщ. #1 , 30.06.06, 19:59
Senior Member
Рейтинг (т): 2
Что это означает: big-endian и little-endian ?
Сообщ. #2 , 30.06.06, 20:56
Рейтинг (т): 215

AndreySol
Речь идет о порядке хранения цифр целого числа в оперативной памяти. Известны два принципиально различные подхода к решению этого вопроса.
Человек «западного стиля» как читает числа, так и нумерует позиции цифр числа слева направо, в результате чего старшая цифра оказывается в самой первой левой (младшей) позиции. В компьютерной терминологии такого рода расположение целого числа в оперативной памяти называется «обратный порядок байтов» – по-английски –»big-endian». Этот же «человеческий» порядок принят и при передаче целых чисел в сети, и называется «сетевой порядок байтов – network byte order».
В IBM-совместимых компьютерах и компьютерах некоторых других фирм принят как-бы «естественный» для компьютера порядок расположения байтов целого числа, при котором в младшей – левой — позиции числа располагается и младшая значащая цифра. Это – «прямой порядок байтов», или по-английски «litle-endian». В процессорах фирмы Motorolla и некоторых других принят обратный порядок следования.
Например, число 247 в этих двух способах расположения в памяти будет выглядеть так:
· 247 — обратный порядок байтов;
· 742 — прямой порядок байтов.
Поскольку на хосте может поддерживаться любой порядок следования байтов, то он называется общим термином «порядок байтов хоста – host byte order».

Сообщ. #3 , 01.07.06, 01:12
Full Member
Рейтинг (т): 16

Проще воспользоваться поиском в интернете набрав big-endian к примеру
http://private.peterlink.ru/kx/_software_h. big2little.html

Сообщ. #4 , 02.07.06, 13:46
Senior Member
Рейтинг (т): 2
Значит такого типа данных как big-endian или little-endian не существует ?
Сообщ. #5 , 02.07.06, 13:50

Рейтинг (т): 640

Это не тип данных. Это порядок следования байтов в многобайтовых типах.
little-endian — младший байт располагается в памяти по меньшему адресу.
big-endian — старший байт располагается в памяти по меньшему адресу.
Есть более сложные варианты расположения, но они довольно редки.

Добавить комментарий

Ваш адрес email не будет опубликован. Обязательные поля помечены *