Об упаковке RPM
- О категориях RPM
- Администрирование RPM
- Создание RPM
3.4 Порядок байтов
Разные поставщики микропроцессоров используют разные схемы упорядочения байтов. Например, процессоры Intel традиционно имеют прямой порядок следования байтов. Процессоры Motorola всегда были с обратным порядком байтов. Big-endian — это порядок, в котором «большой конец» (самый старший байт) сохраняется первым. Порядок с прямым порядком байтов — это порядок, в котором "маленький конец" (самый младший байт) сохраняется первым.
На рис. 3.4 и рис. 3.5 показано представление шестнадцатеричного значения 0xFF342109 , где число хранится в ячейках памяти с 0x1000 по 0x1003 на компьютере с прямым и обратным порядком байтов соответственно.
Рис. 3.4. Представление 0xFF342109 в системе с прямым порядком байтов
Рис. 3.5. Представление 0xFF342109 в системе с обратным порядком байтов
Что такое Little Endian?
Это способ сохранения байтов в памяти компьютера.
Тогда что такое Little Endian? Это байты, хранящиеся в памяти компьютера, где младший значащий байт занимает младший адрес памяти.
Будет проще, если я покажу вам образец ниже:
Например, у меня есть данные: abcdefgh или 61,62,63,64,65,66,67,68 в шестнадцатеричном формате (a=61 в таблице Ascii). Если он загружен в память, порядок будет таким:
Проще всего читать справа налево по 4 байта.
Есть 2 типа:
-Little Endian
-Big Endian
Big Endian — это противоположность Little Endian. Порядок байтов в памяти слева направо.
Little Endian в основном используется в мире микропроцессоров.
За пределами мира микропроцессоров Big Endian является распространенным форматом в сети передачи данных для таких протоколов, как TCP, UDP, IPv4 и IPv6 для передачи данных.
Историческое слово ‘Endian.
В 1980 году ученый-компьютерщик Дэнни Коэн ввел термины Big Endian и Little Endian для цифровой электроники. Этот термин на самом деле происходит из романа «Путешествия Гулливера», написанного Джонатаном Свифтом.
Какой тип процессора использует обратный порядок байтов?
Motorolla использует Big Endian, тогда как Intel и AMD используют Little Endian.
Какой тип лучше?
Пока я не напишу эту статью, я все еще не могу найти статью, которая действительно показывает, какой из них лучше с точки зрения скорости, простоты кодирования или тестирования.
Почему Intel и AMD используют прямой порядок байтов и почему Motorolla и ARM используют в своих процессорах обратный порядок байтов.
Я полагаю, что это основано на дизайне их процессора истории, и для обеспечения обратной совместимости каждый поставщик до сих пор продолжает использовать свою систему Endian в своем продукте.
Для Intel, начиная с первого успешного микропроцессора Intel 8088, который был создан Виктором Пуром, американским инженером и первопроходцем в области компьютеров, он продолжает использовать систему с прямым порядком байтов до сих пор.
После загрузки PDF-файла выполните поиск по запросу «например, сохранение чисел с младшим значащим байтом вперед».
Использование GDB, чтобы увидеть, как это работает в системе.
В этом уроке я использую 64-битный процессор AMD и использую «nasm» для компиляции и компоновки моего ассемблерного кода.
Под кодом, который я использую для примера.
Я скомпилировал его с помощью nasm.
$ nasm -f elf64 -g endian.asm -o endian.o
$ ld endian.o -o endian
$
[Проверка URL] Следующие URL-адреса в этой статье устарели. Пожалуйста, обновите.
Байт (из 8 бит) имеет ограниченный диапазон 256 значений. Когда значение выходит за пределы этого диапазона, оно должно храниться в нескольких байтах.Число, такое как 753, в шестнадцатеричном формате равно 0x02F1. Для этого требуется как минимум два байта памяти. Порядок, в котором эти два байта хранятся в памяти, может быть разным. Байт 0x02 может храниться по нижнему адресу памяти, за которым следует 0xF1; или наоборот.
Программы должны соответствовать порядку байтов, поддерживаемому процессором. В противном случае 0x02F1 может быть неправильно интерпретирован как 0xF102, что является числом 61698 в десятичной системе. Порядок байтов также важен, когда данные передаются по сети или между системами, использующими другой порядок.
Порядок байтов — это атрибут процессора, а не работающей на нем операционной системы.
Обсуждение
- Little-Endian: Младший байт хранится по младшему адресу. Это также называется порядок Intel, поскольку семейство процессоров Intel x86 популяризировало этот порядок. Intel, AMD , PDP-11 и VAX — это системы с прямым порядком байтов.
- Big-Endian: старший байт хранится по младшему адресу. Это также называется порядок Motorola, поскольку в архитектуре Motorola PowerPC используется этот порядок. Мейнфреймы Motorola 68K и IBM – это системы с обратным порядком байтов.
Некоторые процессоры поддерживают оба порядка и поэтому называются Bi-Endian. PowerPC и Itanium имеют двусторонний порядок байтов. Процессоры Bi-Endian могут переключаться между двумя порядками. Большинство RISC-архитектур (SPARC, PowerPC, MIPS) изначально были с обратным порядком байтов, но теперь их можно настраивать. Хотя процессоры ARM имеют двусторонний порядок байтов, по умолчанию они работают как системы с прямым порядком байтов, как это видно на Raspberry Pi.
Поскольку компьютеры, использующие другой порядок байтов и обменивающиеся данными, должны корректно работать с данными, по соглашению данные всегда отправляются по сети в формате с обратным порядком байтов. Мы называем это сетевым порядком байтов. Порядок, используемый на компьютере, называется порядком узлов-байтов.
Хост-система может быть с прямым порядком байтов, но при отправке данных в сеть она должна преобразовывать данные в формат с обратным порядком байтов. Точно так же машина с прямым порядком байтов должна сначала преобразовать сетевые данные в прямой порядок байтов перед их обработкой.
Четыре общие функции для выполнения этих преобразований: (для 32-битных длинных и 16-битных коротких) htonl , ntohl , htons и ntohs .
Даже если ваш код не работает в сети, данные могут храниться в другом порядке. Например, данные файла хранятся в формате с обратным порядком байтов, а на вашем компьютере — с обратным порядком байтов. В некоторых случаях инструкции ЦП могут быть доступны для преобразования. 64-битный набор инструкций Intel имеет BSWAP для изменения порядка байтов. Начиная с ARMv6, REV меняет порядок байтов и SETEND, чтобы установить порядок следования байтов.
Вызов этих преобразований является хорошей практикой программирования, поскольку это делает ваш код переносимым. Ту же кодовую базу можно скомпилировать для машины с прямым порядком байтов, и она будет работать. Вызов функций преобразования на машине с обратным порядком байтов не дает никакого эффекта.
Хотя система с прямым порядком байтов, отправляющая данные в другую систему с прямым порядком байтов, не нуждается в каком-либо преобразовании, это полезно. Это делает код более переносимым между системами.
Когда данные хранятся и обрабатываются как последовательность одиночных байтов (а не коротких или длинных), порядок байтов не имеет значения. Никаких преобразований при получении или отправке таких данных в сеть не требуется.
Строки ASCII хранятся в виде последовательности одиночных байтов. Порядок байтов не имеет значения. Порядок байтов для строк Unicode зависит от типа используемой кодировки. Если используется кодировка UTF-8, порядок не имеет значения, поскольку кодировка представляет собой последовательность одиночных байтов. Если используется кодировка UTF-16, порядок байтов имеет значение.
При сохранении изображений в формате TIFF порядок байтов имеет значение, поскольку пиксели хранятся в виде слов. Для изображений GIF и JPEG не важен порядок байтов, поскольку хранение не ориентировано на слова.
Альтернативой преобразованиям "хост-сеть" и "сеть-хост" является отправка данных вместе с указанием используемого порядка. Этот порядок указывается двумя дополнительными байтами, известными как метка порядка байтов (BOM).
В системах с прямым порядком байтов достаточно прочитать младший байт, чтобы узнать, четное это число или нечетное. Это может быть преимуществом для низкоуровневой обработки. Системы с обратным порядком байтов имеют аналогичное преимущество: младший байт может сказать нам, является ли целое число со знаком положительным или отрицательным.
Приведение типов (скажем, от int16_t к int8_t ) проще в системах с прямым порядком байтов. Из-за простой связи между смещением адреса и номером байта прямой порядок байтов может быть проще для написания математических процедур.
Во время низкоуровневой отладки программисты могут видеть байты, хранящиеся от младшего адреса к старшему, в порядке слева направо. Системы с обратным порядком байтов хранят данные в одном и том же порядке слева направо, что упрощает отладку. По той же причине проще конвертировать двоичные числа в десятичные.
По большей части программистам приходится иметь дело с обеими системами. Каждая система развивалась отдельно, поэтому трудно жаловаться на отсутствие единой системы.
Окончание байтов применимо к многобайтовым числовым значениям.Инструкции не являются числовыми значениями, поэтому порядок следования байтов не имеет значения. Однако инструкция может содержать 16-битные целые числа, адреса или другие значения. Порядок байтов в этих частях важен.
Например, 8051 имеет инструкцию LCALL, которая сохраняет адрес следующей инструкции в стеке. Адрес помещается в стек в формате с прямым порядком байтов. Однако инструкции LJMP и LCALL содержат 16-битные адреса в формате с обратным порядком байтов.
В Linux и Mac для определения порядка байтов можно использовать команду lscpu.
Разработчики также могут написать простую программу для определения порядка следования байтов хост-компьютера. В программе C, например, хранить два байта в памяти. Затем используйте короткую *ptr, чтобы указать на нижний адрес. Разыменуйте этот указатель, чтобы получить короткое значение, которое скажет нам, является ли машина прямым или обратным порядком байтов.
Биты внутри байта обычно нумеруются как Bit0 для младшего бита и Bit7 для старшего бита. Таким образом, нумерация битов в 32-битном целом числе будет производиться слева направо в порядке с обратным порядком байтов и справа налево в порядке с прямым порядком байтов. Однако в некоторых системах, таких как автомобильный интерфейс OpenXC, используется противоположная нумерация, в которой младшим значащим битом является Bit7. Обратите внимание, что в любом случае содержание остается одинаковым, отличается только нумерация.
Дэнни Коэн в своей классической статье на тему порядка следования байтов приводит несколько примеров непоследовательной нумерации битов в ранних компьютерных системах. Например, M68000 был с обратным порядком байтов, но нумерация битов напоминала обратный порядок байтов.
В связи с этим возникает вопрос о том, как хранить многобайтовые величины на машинах, где каждый байт имеет собственный адрес — какой байт сохраняется в «первой», младшей ячейке памяти, а какие байты следуют по старшим адресам памяти?
Если двухбайтовое целое число 0x55FF хранится на диске на одной машине, где 0x55 (старший байт) хранится по младшему адресу памяти, а 0xFF (младший байт) хранится по старшему адресу памяти, но другая машина считывает целое, подбирая 0xFF для старшего байта и 0x55 для младшего байта, что дает 0xFF55, две машины не согласятся со значением целого числа!
Увы, не существует "правильного" порядка хранения байтов в многобайтовых количествах. Аппаратное обеспечение предназначено для обработки байтов в определенном порядке, и пока совместимое оборудование считывает байты в том же порядке, все в порядке. Мы рассмотрим два основных типа порядка байтов: Little-Endian и Big-Endian.
Цитата из Hardcore Visual Basic Брюса МакКинни:
Endian относится к порядку, в котором хранятся байты. Этот термин взят из рассказа Джонатана Свифта «Путешествия Гулливера» о войнах между теми, кто считал, что яйца следует разбивать на Большом конце, и теми, кто настаивал на Малом конце. С чипсами, как и с яйцами, это не имеет большого значения, если вы знаете, какой конец вверху.
Маленький порядок байтов
Если оборудование сконструировано таким образом, что младший, наименее значащий байт многобайтового скаляра хранится "сначала" по наименьшему адресу памяти, тогда говорят, что аппаратное обеспечение имеет порядок байтов с прямым порядком байтов; «маленький» конец целого числа сохраняется первым, а следующие байты сохраняются в более высоких (возрастающих) ячейках памяти. Порядок байтов с прямым порядком байтов таков: «самый маленький конец идет первым (к самому маленькому адресу)».
Такие машины, как Intel/AMD x86, Digital VAX и Digital Alpha, обрабатывают скаляры в форме с прямым порядком байтов.
Большой порядок байтов
Если аппаратное обеспечение сконструировано таким образом, что старший, наиболее значащий байт многобайтового скаляра хранится «сначала» по наименьшему адресу памяти, тогда аппаратное обеспечение называется «обратным порядком байтов»; «большой» конец целого числа сохраняется первым, а следующие байты сохраняются в более высоких (возрастающих) ячейках памяти. Порядок байтов с обратным порядком байтов таков: «самый большой конец идет первым (к самому младшему адресу)».
Такие машины, как мейнфреймы IBM, Motorola 680x0, Sun SPARC, PowerPC и большинство машин RISC, обрабатывают скаляры в форме с обратным порядком байтов.
Пример четырехбайтового целого числа
Четырехбайтовое целое: 0x44332211 |
Память адрес | Big-Endian значение байта | Little-Endian значение байта< /th> |
104 | 11 | 44 |
103 | < td>22 33 |
102 | 33 | 22 |
101 | 44 | 11 |
Если бы мы посмотрели на дамп памяти из этих четырех байтов, как бы он выглядел? Дамп памяти всегда отображает соседние байты памяти слева направо на странице в порядке возрастания адресов памяти. Адреса с нехваткой памяти находятся слева, а адреса увеличиваются один за другим по мере того, как мы перемещаемся вправо по строке в дампе.
Если мы отобразим дамп памяти с номером 0x44332211, хранящимся в памяти по адресу 101, в обратном порядке, мы увидим примерно следующее:
В порядке хранения с обратным порядком байтов «старший», наиболее значимый байт 0x44 хранится «первым» в самой младшей ячейке памяти 101. 0x44 отображается слева от других байтов, которые следуют в порядке возрастания слева. порядок адресов памяти справа: 102, 103, 104. Порядок байтов, выводимых в дампе «44 33 22 11», такой же, как порядок байтов в целом числе, записанном как 0x44332211. Это приятное свойство оборудования с обратным порядком байтов — байты многобайтовых чисел выгружаются на страницу в «правильном» порядке.
Если мы отобразим дамп памяти с тем же номером 0x44332211, который хранится в памяти по адресу 101, в порядке Little-Endian, мы увидим что-то вроде этого:
В порядке хранения с прямым порядком байтов «младший», наименее значимый байт 0x11 хранится «первым» в самой младшей ячейке памяти 101. 0x11 отображается слева от других байтов, которые следуют в порядке возрастания слева. порядок адресов памяти справа: 102, 103, 104. Но порядок вывода байтов в дампе «11 22 33 44» оказывается «обратным» тому, как мы читаем исходный номер 0x44332211! Это неудобная вещь с дампами с прямым порядком байтов - байты многобайтовых скаляров перечислены на странице "задом наперед". Аппаратное обеспечение знает, как подобрать байты в правильном порядке, но, как люди, мы должны не забывать обратить байты, которые мы видим в дампе с прямым порядком байтов, прежде чем реконструировать скалярное значение. Мы видим четырехбайтовое целое число в выходных данных дампа с прямым порядком байтов как «11 22 33 44», и мы должны обратить и реконструировать его как 0x44332211.
ПРИМЕЧАНИЕ. Всегда меняйте порядок байтов многобайтовых скаляров, которые вы видите в дампе с прямым порядком байтов!
Окончание байтов и символьные данные
Однобайтовые символы, такие как ASCII и Latin-1, не затрагиваются порядком байтов. Если вы храните любую строку символов ASCII в памяти, она всегда выглядит одинаково, независимо от порядка байтов аппаратного обеспечения, поскольку длина каждого символа составляет один байт, а начальный символ строки всегда хранится в самой нижней ячейке памяти. Для строки "abcd" буква "a" сохраняется "первой", т.е.
Четырехсимвольная строка: "abcd"< /th> |
Память адрес | значение байта | символ ASCII |
104 | 64 | d |
103 | 63 | c< /td> |
102 | 62 | b |
101 | < td>61 a |
Если вы выгружаете символьные данные из памяти, они также правильно читаются в дампе слева направо:
Таким образом, независимо от того, каков фактический порядок следования байтов аппаратного обеспечения, порядок байтов однобайтовых символьных данных напоминает порядок байтов с обратным порядком байтов — крайний левый байт идет первым — и это хорошо выглядит в выходных данных дампа.
Ничто из этой независимости от Endian не применимо к многобайтовым символам, например. Unicode, где для представления каждого символа требуется более одного байта. Чтобы правильно читать многобайтовые символы, вам нужно знать Endianness, используемый для их хранения. Например, если вы неправильно прочитали двузначный символ UTF-16 0x0041 (буква «А») с перевернутыми байтами как 0x4100, вы получите китайскую иероглифику UTF-16, которая означает «бедствие, бедствие, зло или несчастье». ". Осторожно!
Преобразования между порядком байтов
Вы видите, что файл, полный четырехбайтовых целых чисел с прямым порядком байтов (и/или двухбайтовых символов UTF-16), не будет корректно считываться на машине с прямым порядком байтов, поскольку аппаратное обеспечение с прямым порядком байтов подхватит каждое из четырехбайтовых чисел (и двухбайтовые символы) в «неправильном» порядке байтов и наоборот.
Для передачи многобайтовых скалярных данных с одного компьютера на другой может потребоваться, чтобы каждый скаляр был индивидуально "переставлен байтами" - может потребоваться изменить порядок байтов в каждом скаляре, чтобы число могло быть правильно прочитано другое оборудование. Обратите внимание, что для этого требуется глубокое знание того, где именно скаляры (и символы UTF-16) находятся во входных данных и насколько они велики. Вы не можете просто поменять местами все последовательности из четырех байтов, поскольку не все байты могут принадлежать четырехбайтовым целым числам!
Так как же программа на одной машине может отправить целое число или другой скаляр на другую машину, не зная порядка байтов на обеих машинах? Вы не можете. Вы должны знать порядок байтов на обеих машинах.
Некоторые программы пытаются решить проблему путем преобразования всех скалярных данных в строки символов ASCII, которые не зависят от байтов, например вместо того, чтобы отправлять двухбайтовое целое число 0x010A (десятичное число 266), программа отправит трехбайтовую строку ASCII «266», поскольку строки ASCII не зависят от порядка байтов. Удаленный компьютер преобразует ASCII обратно в исходный целочисленный формат.
Эндийские войны
"Это попытка остановить войну.Я надеюсь, что еще не слишком поздно, и каким-то волшебным образом мир снова восторжествует», — Дэнни Коэн, 1980 г.
Должны ли многобайтовые типы данных храниться с младшим значащим байтом (LSB) в самой нижней ячейке памяти (с прямым порядком байтов: 80x86, VAX, Alpha) или в самой верхней ячейке памяти (с прямым порядком байтов: Motorola, PPC, SPARC , и почти все остальные)? Другими словами, если вы захватываете байт с наименьшим адресом, вы захватываете младший конец числа (младший бит, прямой порядок байтов) или старший конец числа (старший бит, прямой порядок байтов)?
Информация о формате файла — обратите внимание, что GIF и JPEG имеют разный порядок байтов!
Вот несколько прямых ссылок на оригинальную статью Дэнни Коэна 1980 года, в которой проблема была названа "endian":
А вот взрослые люди все еще спорят об этом в августе 2000 года, двадцать лет спустя:
Читайте также: