Процессоры Intel (и, возможно, некоторые другие) используют формат хранения с прямым порядком байтов для хранения.
Мне всегда интересно, почему кто-то захочет хранить байты в обратном порядке. Есть ли у этого формата какие-либо преимущества перед форматом с прямым порядком байтов?
Ответы:
В любом случае, существуют аргументы, но одна из них заключается в том, что в системе с прямым порядком байтов адрес определенного значения в памяти, принимаемого за 32, 16 или 8 бит, одинаков.
Другими словами, если у вас в памяти есть двухбайтовое значение:
Принятие этого '16' в качестве 16-битного значения (c 'short' в большинстве 32-битных систем) или в качестве 8-битного значения (обычно c 'char') изменяет только используемую вами команду извлечения - не адрес, который вы выбираете из.
В системе с прямым порядком байтов, с вышеизложенным выложенным как:
вам нужно будет увеличить указатель, а затем выполнить более узкую операцию извлечения нового значения.
Итак, вкратце, «в системах с прямым порядком байтов броски не нужны».
источник
Big-endian и little-endian - это только «нормальный порядок» и «обратный порядок» с человеческой точки зрения, и только в том случае, если все это верно ...
Это все человеческие соглашения, которые не имеют никакого значения для процессора. Если бы вы сохранили # 1 и # 2 и перевернули # 3, little-endian показался бы «совершенно естественным» людям, которые читают по-арабски или на иврите, которые написаны справа налево.
И есть другие человеческие соглашения, которые делают big-endian кажущимися неестественными, как ...
Когда я в основном программировал 68K и PowerPC, я считал, что big-endian «правильный», а little-endian «неправильный». Но так как я больше работал над ARM и Intel, я привык к порядку байтов. Это действительно не имеет значения.
источник
Хорошо, вот причина, как я объяснил мне: сложение и вычитание
Когда вы добавляете или вычитаете многобайтовые числа, вы должны начинать с младшего байта. Например, если вы добавляете два 16-разрядных числа, может быть перенос от наименее значимого байта к старшему значащему, поэтому вам нужно начать с наименее значимого байта, чтобы увидеть, есть ли перенос. Это та же самая причина, по которой вы начинаете с самой правой цифры при добавлении от руки. Вы не можете начать слева.
Рассмотрим 8-битную систему, которая последовательно выбирает байты из памяти. Если он сначала выбирает младший значащий байт , он может начать добавление, пока самый старший байт извлекается из памяти. Этот параллелизм является причиной того, что производительность в порядке с прямым порядком байтов выше, чем в системе. Если бы пришлось ждать, пока оба байта были извлечены из памяти, или извлечь их в обратном порядке, это заняло бы больше времени.
Это на старых 8-битных системах. На современном процессоре я сомневаюсь, что порядок байтов имеет какое-либо значение, и мы используем little-endian только по историческим причинам.
источник
С 8-битными процессорами это было, безусловно, более эффективно, вы могли выполнять 8- или 16-битные операции без необходимости в другом коде и без буферизации дополнительных значений.
Еще лучше для некоторых операций сложения, если вы обрабатываете байт за раз.
Но нет никакой причины, по которой big-endian более естественен - в английском языке вы используете тринадцать (little-endian) и двадцать три (big endian)
источник
0x12345678
хранится как,78 56 34 12
тогда как в системе BE это12 34 56 78
(байт 0 слева, байт 3 справа). Обратите внимание, что чем больше число (в битах), тем больше требуется замены; СЛОВО потребует один обмен; DWORD, два прохода (всего три обмена); QWORD три прохода (всего 7) и так далее. То есть(bits/8)-1
свопы. Другим вариантом является чтение их как вперед, так и назад (чтение каждого байта вперед, но сканирование всего # назад).Японское соглашение о дате - "big endian" - гггг / мм / дд. Это удобно для алгоритмов сортировки, которые могут использовать простое сравнение строк с обычным правилом «первый символ - самый значимый».
Нечто подобное применимо и к числам с прямым порядком байтов, хранящимся в записи с наиболее значимым полем-первым. Порядок значимости байтов в полях соответствует значению полей в записи, поэтому вы можете использовать a
memcmp
для сравнения записей, не заботясь о том, сравниваете ли вы два длинных слова, четыре слова или восемь отдельных байтов.Отразите порядок значимости полей, и вы получите то же преимущество, но для порядковых чисел, а не для порядковых.
Это имеет очень мало практического значения, конечно. Независимо от того, используется ли ваша платформа с прямым порядком байтов или с прямым порядком байтов, вы можете при желании использовать поля записей для использования этого трюка. Это просто боль, если вам нужно написать переносимый код.
Я могу также включить ссылку на классический призыв ...
http://tools.ietf.org/rfcmarkup?url=ftp://ftp.rfc-editor.org/in-notes/ien/ien137.txt
РЕДАКТИРОВАТЬ
Дополнительная мысль. Однажды я написал большую целочисленную библиотеку (чтобы посмотреть, смогу ли я), и для этого 32-битные блоки хранятся в порядке с прямым порядком байтов, независимо от того, как платформа упорядочивает биты в этих фрагментах. Причины были ...
Многие алгоритмы естественным образом начинают работать с наименее значимой целью и хотят, чтобы эти цели были согласованы. Например, кроме того, переносы распространяются на все более и более значимые цифры, поэтому имеет смысл начинать с наименее значимого конца.
Увеличение или уменьшение значения означает просто добавление / удаление фрагментов в конце - нет необходимости перемещать фрагменты вверх / вниз. Копирование все еще может быть необходимо из-за перераспределения памяти, но не часто.
Разумеется, это не имеет никакого отношения к процессорам - пока процессоры не созданы с аппаратной поддержкой больших целых чисел, это чисто библиотечная вещь.
источник
Никто другой не ответил, ПОЧЕМУ это может быть сделано, много вещей о последствиях.
Рассмотрим 8-битный процессор, который может загрузить один байт из памяти за заданный тактовый цикл.
Теперь, если вы хотите загрузить 16-битное значение, скажем, в один-единственный 16-битный регистр, который у вас есть - то есть в счетчик программ, то простой способ сделать это:
результат: вы только увеличиваете местоположение выборки, вы загружаете только часть младшего разряда расширенного регистра, и вам нужно только иметь возможность сдвигаться влево. (Конечно, смещение вправо полезно для других операций, так что это немного побочный эффект.)
Следствием этого является то, что 16-битный (двухбайтовый) материал хранится в порядке Most..Least. То есть, у меньшего адреса самый старший байт - такой большой порядок байтов.
Если вместо этого вы попытаетесь загрузить с использованием байтов с прямым порядком байтов, вам нужно будет загрузить байт в нижнюю часть вашего широкого регистра, затем загрузить следующий байт в промежуточную область, сдвинуть его, а затем вставить его в верхнюю часть вашего более широкого регистра. , Или используйте более сложную схему стробирования, чтобы можно было выборочно загружать в верхний или нижний байт.
Результатом попытки перейти к порядку байтов является то, что вам нужно больше кремния (коммутаторы и вентили) или больше операций.
Другими словами, с точки зрения получения отдачи в прежние времена, вы получили больше отдачи за большую производительность и наименьшую площадь кремния.
В наши дни эти соображения и в значительной степени не имеют никакого значения, но такие вещи, как заполнение конвейера, могут все еще быть чем-то большим.
Когда дело доходит до написания программного обеспечения, жизнь часто упрощается при использовании адресации с прямым порядком байтов.
(И процессоры с прямым порядком байтов имеют тенденцию к порядку с прямым порядком байтов с точки зрения упорядочения байтов и с прямым порядком байтов с точки зрения битов в байтах. Но некоторые процессоры являются странными и будут использовать порядок байтов с прямым порядком байтов, а также порядок байтов. Это делает жизнь очень Интересно для дизайнера, добавляющего отображаемые в память периферийные устройства, но не имеет никакого другого значения для программиста.)
источник
Jimwise сделал хорошую мысль. Есть еще одна проблема, в Little Endian вы можете сделать следующее:
Более просты для программистов, на которых не влияет очевидный недостаток мест подкачки в памяти. Лично я нахожу, что обратный порядок байтов обратен тому, что естественно :). 12 должно храниться и записываться как 21 :)
источник
for(i=0; i<4; i++) { num += data[i] << (24 - i * 8); }
соответствуетmove.l data, num
процессору с большим порядком байтов.Десятичные числа пишутся с прямым порядком байтов. Кроме того, как вы пишете по-английски. Вы начинаете с самой значимой цифры и со следующей самой значимой до наименее значимой. например
одна тысяча двести тридцать четыре.
Таким образом, большой порядок байтов иногда называют естественным порядком.
В младшем порядке, это число будет одна, двадцать, триста четыре тысячи.
Однако, когда вы выполняете арифметику, такую как сложение или вычитание, вы начинаете с конца.
Вы начинаете с 4 и 7, пишете младшую цифру и запоминаете перенос. Затем вы добавляете 3 и 6 и т. Д. Для сложения, вычитания или сравнения проще реализовать, если у вас уже есть логика для чтения памяти по порядку, если числа поменялись местами.
Для поддержки байтового порядка таким образом, вам нужна логика для чтения памяти в обратном порядке, или у вас есть процесс RISC, который работает только с регистрами. ;)
Дизайн Intel x86 / Amd x64 во многом является историческим.
источник
Big-endian полезен для некоторых операций (сравнения «bignums» одинаковых значений длины октетов). Little-endian для других (возможно, добавление двух "bignums"). В конце концов, это зависит от того, для чего было настроено аппаратное обеспечение ЦП, обычно это один или другой (некоторые микросхемы MIPS были, IIRC, переключались при загрузке, чтобы быть LE или BE).
источник
Когда речь идет только о хранении и передаче с переменной длиной, но без арифметики с несколькими значениями, то LE обычно легче писать, а BE легче читать.
Давайте возьмем преобразование между строками (и обратно) в качестве конкретного примера.
Когда int преобразуется в строку, младшую значащую цифру легче извлечь, чем самую значимую. Все это можно сделать в простом цикле с простым конечным условием.
Теперь попробуйте то же самое в порядке BE. Обычно вам нужен еще один делитель, который содержит наибольшую степень 10 для определенного числа (здесь 100). Сначала нужно найти это, конечно. Намного больше вещей, чтобы сделать.
Преобразование строки в int легче сделать в BE, когда это делается как операция обратной записи. Запись хранит самую значимую цифру последней, поэтому ее следует прочитать первой.
Теперь сделайте то же самое в порядке LE. Опять же, вам понадобится дополнительный коэффициент, начинающийся с 1 и умноженный на 10 для каждой цифры.
Поэтому я обычно предпочитаю использовать BE для хранения, потому что значение записывается ровно один раз, но читается как минимум один раз, а может и много раз. Для его более простой структуры я обычно иду по пути, чтобы преобразовать в LE и затем полностью изменить результат, даже если это записывает значение во второй раз.
Другим примером хранилища BE будет кодировка UTF-8 и многое другое.
источник