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

Little endian и big endian что это

  • автор:

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 для различных типов архитектур процессоров и протоколов.

Big Endian Little Endian Оба варианта
Архитектуры процессоров
AVR32
FR-V
H8300
PA-RISC
S390
Motorola 680×0 PowerPC
SPARC
Alpha
CRIS
Blackfin
Intel 64
IA-32 (x86) MN10300
AT91SAM7
Cortex, STM32
ARM
SuperH (sh)
M32R
MIPS
Xtensa

Примечание: процессор 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.

Сокеты Windows. Порядок байтов

В этой статье и двух дополнительных статьях объясняется несколько проблем программирования сокетов Windows. В этой статье рассматриваются упорядочение байтов. Другие проблемы рассматриваются в статьях: сокеты Windows: блокировка и сокеты Windows: преобразование строк.

Если вы используете или извлекаете из класса CAsyncSocket, вам потребуется самостоятельно управлять этими проблемами. При использовании или производных от класса CSocket MFC управляет ими.

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

Разные архитектуры компьютеров иногда хранят данные с помощью разных заказов байтов. Например, компьютеры на основе Intel хранят данные в обратном порядке компьютеров Macintosh (Motorola). Порядок байтов Intel, называемый «little-Endian», также является обратным порядком сети «big-Endian». В следующей таблице описаны эти термины.

Порядок больших и маленьких байтов

Порядок байтов Значение
Big-Endian Самый значительный байт находится в левом конце слова.
Маленький эндиан Самый значительный байт находится в правом конце слова.

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

Когда необходимо преобразовать заказы байтов

В следующих ситуациях необходимо преобразовать заказы байтов:

  • Вы передаете информацию, которая должна интерпретироваться сетью, а не данные, отправляемые на другой компьютер. Например, можно передать порты и адреса, которые должны понимать сеть.
  • Серверное приложение, с которым вы взаимодействуете, не является приложением MFC (и у вас нет исходного кода). Это вызывает преобразования порядка байтов, если два компьютера не используют одинаковый порядок байтов.

Если вам не нужно преобразовывать заказы байтов

Вы можете избежать работы преобразования заказов байтов в следующих ситуациях:

  • Компьютеры на обоих концах могут не переключать байты, и оба компьютера используют одинаковый порядок байтов.
  • Сервер, с которым вы взаимодействуете, является приложением MFC.
  • У вас есть исходный код для сервера, с которым вы взаимодействуете, поэтому вы можете явно определить, нужно ли преобразовать заказы байтов или нет.
  • Сервер можно перенести в MFC. Это довольно легко сделать, и результат обычно меньше, быстрее кода.

Работая с CAsyncSocket, необходимо самостоятельно управлять любыми необходимыми преобразованиями порядка байтов. Сокеты Windows стандартизуют модель байтового порядка big-Endian и предоставляет функции для преобразования между этим порядком и другими. Однако CArchive, который вы используете с CSocket, использует противоположный порядок («маленький эндиан»), но CArchive заботится о деталях преобразования байтов для вас. Используя этот стандартный порядок в приложениях или с помощью функций преобразования байтов в сокетах Windows, вы можете сделать код более переносимым.

Идеальным вариантом использования сокетов MFC является написание обоих окончаний взаимодействия: использование MFC в обоих концах. Если вы пишете приложение, которое будет взаимодействовать с приложениями, не являющихся MFC, например FTP-сервером, вам, вероятно, потребуется самостоятельно управлять переключениями байтов перед передачей данных в архивный объект, используя подпрограммы преобразования сокетов Windows ntohs, ntohl, htons и htonl. Пример этих функций, используемых в взаимодействии с приложением, отличным от MFC, отображается далее в этой статье.

Если другой конец связи не является приложением MFC, необходимо также избежать потоковой передачи объектов C++, производных от CObject архива, так как получатель не сможет обрабатывать их. См. примечание в сокетах Windows: использование сокетов с архивами.

Дополнительные сведения о заказах байтов см. в спецификации сокетов Windows, доступной в пакете SDK для Windows.

Пример преобразования байтового порядка

В следующем примере показана функция сериализации для CSocket объекта, использующего архив. Он также иллюстрирует использование функций преобразования байтов в API сокетов Windows.

В этом примере представлен сценарий, в котором вы пишете клиент, который взаимодействует с серверным приложением, отличным от MFC, для которого у вас нет доступа к исходному коду. В этом сценарии необходимо предположить, что сервер, отличный от MFC, использует стандартный порядок байтов сети. В отличие от этого, клиентское приложение MFC использует объект с CSocket объектом и CArchive использует CArchive байтовый порядок «little-Endian», противоположность стандарту сети.

Предположим, что сервер, отличный от MFC, с которым планируется взаимодействовать, имеет установленный протокол для пакета сообщений, как показано ниже:

struct Message < long MagicNumber; unsigned short Command; short Param1; long Param2; >; 

В терминах MFC это будет выражено следующим образом:

struct Message < long m_lMagicNumber; short m_nCommand; short m_nParam1; long m_lParam2; void Serialize(CArchive &ar); >; 

В C++, это struct , по сути, то же самое, что и класс. Структура Message может иметь функции-члены, такие как функция-член, объявленная Serialize выше. Функция-член Serialize может выглядеть следующим образом:

void Message::Serialize(CArchive &ar) < if (ar.IsStoring()) < ar else < WORD w; DWORD dw; ar >> dw; m_lMagicNumber = ntohl((long)dw); ar >> w; m_nCommand = ntohs((short)w); ar >> w; m_nParam1 = ntohs((short)w); ar >> dw; m_lParam2 = ntohl((long)dw); > > 

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

Функции преобразования сокетов Windows Byte-Order

Функция Назначение
ntohs Преобразование 16-разрядного количества из сетевого байтового порядка в порядок байтов узла (big-Endian в маленький эндиан).
ntohl Преобразование 32-разрядного количества из байтов сети в порядок байтов узла (big-Endian в маленький эндиан).
Хтоны Преобразование 16-разрядного количества из порядка байтов узла в сетевой порядок байтов (маленький байт в big-Endian).
Htonl Преобразование 32-разрядного количества из порядка байтов узла в сетевой байтовый порядок (маленький байт в big-Endian).

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

где pMsg указатель на объект C++, производный от класса CObject . Это приведет к отправке дополнительных сведений MFC, связанных с объектами, и сервер не поймет его, так как это было бы, если бы это было приложение MFC.

Дополнительные сведения см. в разделе:

  • Сокеты Windows. Использование класса CAsyncSocket
  • Сокеты Windows. Фон
  • Сокеты Windows. Сокеты потоков
  • Сокеты Windows. Сокеты датаграмм

Понятие порядка байтов в цифровых системах: прямой (Big Endian) и обратный (Little Endian) порядок байтов

Различные термины «порядка байтов» («endian») могут показаться немного странными, но основная концепция довольно проста. Если вы еще не хорошо знакомы с вариантами порядка байтов, читайте статью дальше!

Порядок байтов, прямой порядок (big endian), обратный порядок (little endian). Что означают эти термины, и как они влияют на работу инженеров?

Что такое порядок байтов?

Оказывает, это неправильный вопрос. При обсуждении данных «порядок байтов» не является отдельным термином. Вернее, к форматам расположения байтов относятся термины «прямой порядок» («big-endian») и «обратный порядок» («little-endian»).

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

В 1980 году израильский ученый-компьютерщик Денни Коэн написал статью («О священных войнах и призыве к миру»), в которой он представил насмешливое объяснение столь же мелкой «войны», вызванной одним вопросом:

«Каков правильный порядок байтов в сообщениях?»

Чтобы объяснить эту проблему, он позаимствовал у Свифта термины «big endian» и «little endian», чтобы описать две противоположные стороны дискуссии о том, что он называл «endianness» (в данном контексте «порядок байтов»).

Когда Свифт писал «Путешествия Гулливера» где-то в первой четверти восемнадцатого века, он, конечно, не знал, что однажды его работа послужит вдохновением для неологизмов двадцатого века, которые определяют расположение цифровых данных в памяти и системах связи. Но такова жизнь – часто странная и всегда непредсказуемая.

Зачем нам нужен порядок байтов

Несмотря на сатирическую трактовку Коэном борьбы «big endians» (прямого порядка, от старшего к младшему) против «little endians» (обратного порядка, от младшего к старшему), вопрос о порядке байтов на самом деле очень важен для нашей работы с данными.

Блок цифровой информации – это последовательность единиц и нулей. Эти единицы и нули начинаются с наименьшего значащего бита (least significant bit, LSb – обратите на строчную букву «b») и заканчиваются на наибольшем значащем бите (most significant bit, MSb).

Это кажется достаточно простым; рассмотрим следующий гипотетический сценарий.

32-разрядный процессор готов к сохранению данных и, следовательно, передает 32 бита данных в соответствующие 32 блока памяти. Этим 32 блокам памяти совместно назначается адрес, скажем 0x01. Шина данных в системе спроектирована таким образом, что нет возможности смешивать LSb с MSb, и все операции используют 32-битные данные, даже если соответствующие числа могут быть легко представлены в 16 или даже 8 битами. Когда процессору требуется получить доступ к сохраненным данным, он просто считывает 32 бита с адреса памяти 0x01. Эта система является надежной, и нет необходимости вводить понятие порядка байтов.

Возможно, вы заметили, что слово «байт» в описании этого гипотетического процессора нигде не упоминалось. Всё основано на 32-битных данных – зачем нужно делить эти данные на 8-битные части, если всё оборудование предназначено для обработки 32-битных данных? Вот здесь-то теория и реальность расходятся. Реальные цифровые системы, даже те, которые могут напрямую обрабатывать 32-битные или 64-битные данные, широко использую 8-битный сегмент данных, известный как байт.

Порядок байтов в памяти

Удобным средством демонстрации порядка байтов действии и объяснения разницы между прямым и обратным порядками является процесс хранения цифровых данных. Представьте, что мы используем 8-разрядный микроконтроллер. Всё аппаратное обеспечение в этом устройстве, включая ячейки памяти, предназначено для 8-битных данных. Таким образом, адрес 0x00 может хранить один байт, адрес 0x01 тоже хранит один байт, и так далее.

Эта схема показывает 11 байтов памяти, то есть 11 ячеек памяти, причем каждая ячейка хранит 8 бит данных

Допустим, мы решили запрограммировать этот микроконтроллер, используя компилятор C, который позволяет нам определять 32-разрядные (т.е. 4-байтовые) переменные. Компилятор должен хранить эти переменные в смежных ячейках памяти, но что не очень понятно, так это то, в самом младшем адресе памяти должен храниться наибольший значащий байт (most significant byte, MSB – обратите внимание на заглавную «B») или наименьший значащий байт (least significant byte, LSB).

Другими словами, должна ли система использовать порядок памяти от старшего к младшему (прямой порядок, big-endian) или от младшего к старшему (обратный порядок, little-endian)?

Хранения данных с прямым порядком и с обратным порядком. D относится к 32-разрядному слову данных, а номера индексов указывают на отдельные биты от MSb (D31) до LSb (D0)

Здесь на самом деле нет правильного или неправильного ответа – любая договоренность может быть совершенно эффективной. Решение между прямым и обратным порядком может быть основано, например, на поддержании совместимости с предыдущими версиями данного процессора, что, конечно, поднимает вопрос о том, как инженеры приняли решение для первого процессора в этом семействе. Я не знаю; возможно, генеральный директор подбросил монету.

Прямой порядок против обратного порядка

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

Обратный порядок (little endian) указывает на организацию, которая начинается с «маленького» конца и продолжается в направлении «большого» конца.

Решение между прямым и обратным порядками байтов не ограничивается схемами памяти и 8-разрядными процессорами. Байт является универсальной единицей в цифровых системах. Подумайте только о персональных компьютерах: пространство на жестком диске измеряется в байтах, ОЗУ измеряется в байтах, скорость передачи данных по USB указывается в байтах в секунду (или в битах в секунду), и это несмотря на тот факт, что 8-разрядные персональные компьютеры полностью устарели. Вопрос о порядке байтов вступает в игру всякий раз, когда цифровая система совмещает хранение или передачу данных на основе байтов с числовыми значениями, длина которых превышает 8 бит.

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

Порядок байтов в контексте последовательной передачи данных

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

Примером интерпретации на основе порядка байтов является случай, когда байты данных передаются от модуля датчика на ПК через «последовательный порт» (что в настоящее время почти наверняка означает, что в качестве COM порта используется USB соединение). Допустим, всё, что вам нужно сделать, это вывести эти данные, используя какой-то код MATLAB. Когда вы вводите эти байты в среду MATLAB и конвертируете их в обычные переменные, вы должны интерпретировать значения отдельных байтов в соответствии с порядком, в котором они хранятся в памяти.

Заключение

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

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

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

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

От старшего к младшему (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. Обычно порядок байтов выбирается программно во время инициализации операционной системы, но может быть выбран и аппаратно перемычками на материнской плате. В этом случае правильнее говорить о порядке байтов операционной системы.

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

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