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

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

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

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

M = \sum_{i=0}^{n}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.

Набор целых чисел A_0,\dots,A_n, каждое из которых лежит в интервале от 0 до 255, является последовательностью байтов, составляющих M. При этом A_0 называется младшим байтом, а A_n — старшим байтом числа M.

Содержание

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

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

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

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

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

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

Порядок от младшего к старшему или (англ. little-endian, дословно: «остроконечный»), о происхождении термина ниже): A_0,\dots,A_n, запись начинается с младшего и заканчивается старшим. Этот порядок записи принят в памяти персональных компьютеров с x86-процессорами, в связи с чем иногда его называют интеловский порядок байтов (по названию фирмы-создателя архитектуры x86). В некоторых кругах используется название англ. VAX order, например, в документации Perl[1].

В противоположность «тупоконечному» порядку, меньше[источник не указан 580 дней] кросс-платформенных протоколов и форматов данных с «остроконечным» порядком байт; заметные исключения: USB, конфигурация PCI, таблица разделов GUID, рекомендации FidoNet.

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

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

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

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

Классический пример middle-endian — представление 4-байтных целых чисел на 16-битных процессорах семейства PDP-11 (известен как PDP-endian). Для представления двухбайтных значений (слов) использовался порядок little-endian, но 4-хбайтное двойное слово записывалось от старшего слова к младшему.

В процессорах VAX и 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 есть «неочевидность» значения байтов памяти при отладке (последовательность байтов (A1, B2, C3, D4) на самом деле значит 0xD4C3B2A1, для big-endian эта последовательность (A1, B2, C3, D4) читалась бы «естественным» для арабской записи чисел образом: 0xA1B2C3D4). Наименее удобным в работе считается middle-endian формат записи; он сохранился только на старых платформах.

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

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

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

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

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

#include <stdio.h>
unsigned short x = 1; /* 0x0001 */
int main(void)
{
  printf("%s\n", *((unsigned char *) &x) == 0 ? "big-endian" : "little-endian");
  return 0;
}
Вывод данной программы осмыслен только на платформах, где размер типа unsigned short больше, чем размер типа unsigned char. Это заведомо верно на подавляющем большинстве компьютеров, так как они имеют 8-разрядный байт. Однако существуют и аппаратные платформы, в которых размер байта равен размеру слова (или, в терминах языка C: sizeof(char) == sizeof(int)). Например, в суперкомпьютерах Cray.

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

 $ uname -m
 sparc64
 $ gcc -o testendian testendian.c 
 $ ./testendian 
 big-endian

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

 $ uname -m
 i386
 $ gcc -o testendian testendian.c 
 $ ./testendian 
 little-endian

Вещественные числа

Хранение вещественных чисел может зависеть от порядка байт; так, на x86 используются форматы IEEE 754 со знаком и порядком числа в старших байтах.

Юникод

Если Юникод записан в виде UTF-16 или UTF-32, то порядок байтов является существенным. Одним из способов обозначения порядка байтов в юникодовых текстах является постановка в начале специального символа BOM (byte order mark, U+FEFF) — «перевёрнутый» вариант этого символа (U+FFFE) не существует и не допускается в текстах.

Конвертация

Для преобразования между сетевым порядком байтов (англ. network byte order), который всегда big-endian, и порядком байтов, использующимся на машине (англ. host byte order), стандарт POSIX предусматривает функции 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-битную беззнаковую величину из сетевого порядка байтов в локальный.

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

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

Ядро Linux: le16_to_cpu(), cpu_to_be32(), cpu_to_le16p(), и так далее;

Ядро FreeBSD: htobe16(), le32toh(), и так далее;

Erlang:

 <<Count:32/big-unsigned-integer, Average:64/big-float>> = Chunk
 
 Message = <<Length:32/little-unsigned-integer,
        MType:16/little-unsigned-integer, MessageBody>>

Python:

 import struct
 Count, Average = struct.unpack(">Ld", Chunk)
 Message = struct.pack("<LH", Length, MType) + MessageBody

Perl:

 ($Count, $Average) = unpack('L>d>', $Chunk);
 $Message = pack('(LS)<', $Length, $MType) . $MessageBody;
 (или то же самое: $Message = pack('Vv', $Length, $MType) . $MessageBody;)

данные примеры для Erlang, Python, Perl содержат идентичную функциональность.

Этимология названия

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

Термины big-endian и little-endian ввёл Коэн (англ. Danny Cohen) в 1980 году в своей статье «On Holy Wars and a Plea for Peace».[3][4]

См. также

Примечания

  1. pack() в Perl
  2. DAV’s Endian FAQ(недоступная ссылка — история)
  3. Danny Cohen. On Holy Wars and a Plea for Peace  (англ.) (1 апреля 1980). Архивировано из первоисточника 15 февраля 2012. Проверено 24 января 2010.
  4. Таненбаум Э. Архитектура компьютера. — 5-е изд. — СПб.: Питер, 2007. — 844 с. — С. 89.

Ссылки


Wikimedia Foundation. 2010.

Игры ⚽ Поможем написать реферат

Полезное


Смотреть что такое "Порядок байтов" в других словарях:

  • обратный порядок байтов — Способ хранения и обмена данными в сети, при котором сначала передается самый младший байт, а затем остальные в порядке, обратном их размещению в блоке данных. [Л.М. Невдяев. Телекоммуникационные технологии. Англо русский толковый словарь… …   Справочник технического переводчика

  • прямой порядок байтов — Способ хранения и обмена данными в сети, при котором сначала передается самый старший байт, а затем остальные в порядке их размещения в блоке данных. Ср. little . [Л.М. Невдяев. Телекоммуникационные технологии. Англо русский толковый словарь… …   Справочник технического переводчика

  • Порядок байт — Порядок байтов в информатике  метод записи байтов многобайтовых чисел. В общем случае, когда нужно компактно записать число, большее 255 (28 − 1 = 255  максимальное целое число, записываемое одним байтом (октетом)) необходимо использовать… …   Википедия

  • порядок следования байтов — Под этим термином понимается порядок хранения байтов в машинном слове (или двойном слове). Порядок может быть "прямым" (т.е. 32 битовое число хранится так 0x12345678) и тогда говорят "big endianness" (на отечественном жаргоне… …   Справочник технического переводчика

  • прямой порядок (следования) байтов — Формат для хранения и передачи двоичных данных, при которой старший (наиболее значимый бит (или байт) передается сначала. Обратное преобразование называется little endian. [http://www.morepc.ru/dict/] Тематики информационные технологии в целом EN …   Справочник технического переводчика

  • UTF-16 — (англ. Unicode Transformation Format) в информатике один из способов кодирования символов из Unicode в виде последовательности 16 битных слов. Данная кодировка позволяет записывать символы Юникода в диапазонах U+0000..U+D7FF и… …   Википедия

  • UCS-4 — Юникод, или Уникод (англ. Unicode)  стандарт кодирования символов, позволяющий представить знаки практически всех письменных языков. Стандарт предложен в 1991 году некоммерческой организацией «Консорциум Юникода» (англ. Unicode Consortium,… …   Википедия

  • UNICODE — Юникод, или Уникод (англ. Unicode)  стандарт кодирования символов, позволяющий представить знаки практически всех письменных языков. Стандарт предложен в 1991 году некоммерческой организацией «Консорциум Юникода» (англ. Unicode Consortium,… …   Википедия

  • UTF-32LE — Юникод, или Уникод (англ. Unicode)  стандарт кодирования символов, позволяющий представить знаки практически всех письменных языков. Стандарт предложен в 1991 году некоммерческой организацией «Консорциум Юникода» (англ. Unicode Consortium,… …   Википедия

  • UTF-32 Little Endian — Юникод, или Уникод (англ. Unicode)  стандарт кодирования символов, позволяющий представить знаки практически всех письменных языков. Стандарт предложен в 1991 году некоммерческой организацией «Консорциум Юникода» (англ. Unicode Consortium,… …   Википедия


Поделиться ссылкой на выделенное

Прямая ссылка:
Нажмите правой клавишей мыши и выберите «Копировать ссылку»