Здравствуйте, почему байты считываются в обратном порядке?
Проверял на MSVC ( x86, x64 ) и на gcc, вывод один и тот же.
Читал, что иногда байты считываются в обратном порядке, но почему и где про это прочесть?
С какой целью производится такое странное считывание?
Здравствуйте, plusovik, Вы писали:
P>Здравствуйте, почему байты считываются в обратном порядке? P>Проверял на MSVC ( x86, x64 ) и на gcc, вывод один и тот же. P>Читал, что иногда байты считываются в обратном порядке, но почему и где про это прочесть?
Это называется Endianness — порядок байт в слове.
У интела принята Little-endian (младший байт идет первым), у HPUX (если склероз не подводит) — Big-endian (первый — старший байт).
_____________________
С уважением,
Stanislav V. Zudin
Re[2]: Обратный порядок считывания байтов в массиве
Здравствуйте, Stanislav V. Zudin, Вы писали:
SVZ>Это называется Endianness — порядок байт в слове. SVZ>У интела принята Little-endian (младший байт идет первым), у HPUX (если склероз не подводит) — Big-endian (первый — старший байт).
В данном примере вроде байты читаются как и ожидаешь, слева направо, а элементы массива при выходе за границу — в обратном порядке.
Почему так?
Re[3]: Обратный порядок считывания байтов в массиве
Здравствуйте, plusovik, Вы писали:
P>В данном примере вроде байты читаются как и ожидаешь, слева направо, а элементы массива при выходе за границу — в обратном порядке. P>Почему так?
Ну сначала младшие байты, потом старшие.
Re[3]: Обратный порядок считывания байтов в массиве
Здравствуйте, plusovik, Вы писали:
P>В данном примере вроде байты читаются как и ожидаешь, слева направо, а элементы массива при выходе за границу — в обратном порядке. P>Почему так?
При выходе за границу массива ты читаешь мусор, казалось бы, это очевидно.
Или я тебя неправильно понял?
На твоей машине LE — это видно, если получить первый байт у инт16.
Знание о Endianness пригодится при передаче двоичных данных по сети и при работе с отдельными битами/байтами в кросс-платформенных приложениях.
_____________________
С уважением,
Stanislav V. Zudin
Re[4]: Обратный порядок считывания байтов в массиве
Здравствуйте, Stanislav V. Zudin, Вы писали: SVZ>При выходе за границу массива ты читаешь мусор, казалось бы, это очевидно. SVZ>Или я тебя неправильно понял?
Там не совсем мусор, а проинициализированные байты
Здравствуйте, T4r4sB, Вы писали: TB>Ну сначала младшие байты, потом старшие.
Судя по всему, сначала читаются младшие биты, тогда понятно, почему a08 = AB.
А почему a32: 33CC21AB, а не a32: 21AB33CC ?
Здравствуйте, plusovik, Вы писали: P>А почему a32: 33CC21AB, а не a32: 21AB33CC ?
Потому что сначала считался a[2] это 21AB, а потом считался a[3] это 33СС, и то, что считалось позже, идёт в старшие байты
Элементы массива всегда идут в одном и том же порядке на любой архитектуре.
Re[5]: Обратный порядок считывания байтов в массиве
plusovik:
P>Судя по всему, сначала читаются младшие биты, тогда понятно, почему a08 = AB.
Не "читаются младшие байты", а размещаются.
Порядок байтов в слове, слов в двойном слове и т.д. — это и есть endianness.
P>А почему a32: 33CC21AB, а не a32: 21AB33CC ?
Возьми тетрадку в клеточку, разрисуй и сразу навсегда разберешься.
Модератор-националист Kerk преследует оппонентов по политическим мотивам.
Re[6]: Обратный порядок считывания байтов в массиве
Здравствуйте, T4r4sB, Вы писали: TB>Потому что сначала считался a[2] это 21AB, а потом считался a[3] это 33СС, и то, что считалось позже, идёт в старшие байты TB>Элементы массива всегда идут в одном и том же порядке на любой архитектуре.
Кажется, понял: младшие байты расположены левее, они же считываются первыми.
По сути в памяти элемент 21AB расположен, как BA12, а элемент 33СС расположен, как СС33, а "вместе" они расположены, как BA12СС33.
Тогда при манипуляциях с указателями читаем, словно ими не манипулирвали, и записываем первые прочитанные байты в младшие и далее по старшинству. После чего из BA12СС33 получаем 33CC21AB ( просто прочли справа налево BA12СС33 ).
Я правильно понял?
Только непонятно, зачем так располагать байты и почему именно байты так странно записываются, а не сразу биты.
Здравствуйте, plusovik, Вы писали:
P>Я правильно понял?
Да
P>Только непонятно, зачем так располагать байты
Это удобно, когда у тебя есть uint32_t число, которое меньше, чем 65536. И тогда если по тому же адресу прочитать uint16_t, то получится такое же значение
P>и почему именно байты так странно записываются, а не сразу биты.
В Intel 8088 были 16-разрядные регистры, но 8-разрядная шина данных.
В регистрах порядок байт — big-endian, а в памяти — little-endian, потому, что разработчикам процессора так было проще из памяти в регистры данные записывать. А потом такой порядок сохранился с целью обратной совместимости.
Re[8]: Обратный порядок считывания байтов в массиве
Здравствуйте, T4r4sB, Вы писали: P>>Я правильно понял? TB>Да
Спасибо за объяснения, остальным тоже.
TB>А как ты определишь порядок битов?
Например, в моём примере вместо 21AB в памяти записали BA12, а потом прочли, начиная заполнять младшие биты.
В двоичной записи это 21AB — это 0010 0001 1010 1011.
Почему тогда его записали как BA12 1011 1010 0001 0010,
а не как 1101 0101 1000 0100 ( D584 )?
Здравствуйте, plusovik, Вы писали:
P>В двоичной записи это 21AB — это 0010 0001 1010 1011. P>Почему тогда его записали как BA12 1011 1010 0001 0010, P>а не как 1101 0101 1000 0100 ( D584 )?
Откуда ты знаешь, как его записали? Это нельзя никак определить, потому что нельзя адресовать отдельные биты в байте.
Всё, что ты можешь сказать — его считали так же, как записали.
Re[10]: Обратный порядок считывания байтов в массиве
Здравствуйте, T4r4sB, Вы писали:
P>>В двоичной записи это 21AB — это 0010 0001 1010 1011. P>>Почему тогда его записали как BA12 1011 1010 0001 0010, P>>а не как 1101 0101 1000 0100 ( D584 )?
TB>Откуда ты знаешь, как его записали? Это нельзя никак определить, потому что нельзя адресовать отдельные биты в байте. TB>Всё, что ты можешь сказать — его считали так же, как записали.
Подтверждение тому, что биты не переворачиваются, можно найти в реализации функций htons, ntohs, htonl, ntohl — переставляются только байты.
_____________________
С уважением,
Stanislav V. Zudin
Re[9]: Обратный порядок считывания байтов в массиве
Здравствуйте, plusovik, Вы писали:
P>В двоичной записи это 21AB — это 0010 0001 1010 1011. P>Почему тогда его записали как BA12 1011 1010 0001 0010, P>а не как 1101 0101 1000 0100 ( D584 )?
Понятие "порядка" ("endianness") применимо только к индивидуально адресуемым единицам в рамках некоего составного агрегата, напр. к отдельным 8-битным байтам в 64-битном слове. То есть речь в данном случае идет о том, как порядок значимости байтов в слове соотносится с их порядком в адресах памяти.
Биты не являются индивидуально адресуемыми, поэтому к ним понятие "endianness" не применимо вообще. У битов нет "порядка в памяти". Поэтому не ясно, с чего это вдруг вы собрались их переворачивать. "Переворачивать" относительно чего?
P.S. На многих платформах существуют машинные команды, которые действительно "адресуют", т.е. локально нумеруют индивидуальные биты в байте. Но там везде действует единое соглашение: младшие по значимости биты имеют младшие номера. То есть нумерация битов всегда и везде подчиняется правилам условного "little-endian" и никакого "плюрализма мнений" не допускается.
Best regards,
Андрей Тарасевич
Re[9]: Обратный порядок считывания байтов в массиве
Здравствуйте, Stanislav V. Zudin, Вы писали:
P>>Здравствуйте, почему байты считываются в обратном порядке? P>>Проверял на MSVC ( x86, x64 ) и на gcc, вывод один и тот же. P>>Читал, что иногда байты считываются в обратном порядке, но почему и где про это прочесть?
SVZ>Это называется Endianness — порядок байт в слове. SVZ>У интела принята Little-endian (младший байт идет первым), у HPUX (если склероз не подводит) — Big-endian (первый — старший байт).
HP-UX это ОС, а не ISA. Живые архитектуры с big-endian это SPARC, IBM System/Z (самая живучая и актуальная сейчас).
The God is real, unless declared integer.
Re[8]: Обратный порядок считывания байтов в массиве
Здравствуйте, T4r4sB, Вы писали:
P>>Только непонятно, зачем так располагать байты
TB>Это удобно, когда у тебя есть uint32_t число, которое меньше, чем 65536. И тогда если по тому же адресу прочитать uint16_t, то получится такое же значение
Да, очень удобно делать ошибки с молчаливым усечением значения, которые максимально долго не будут ловиться тестами.
The God is real, unless declared integer.
Re[9]: Обратный порядок считывания байтов в массиве
Здравствуйте, plusovik, Вы писали:
TB>>А как ты определишь порядок битов? P>Например, в моём примере вместо 21AB в памяти записали BA12, а потом прочли, начиная заполнять младшие биты.
Перестановка порядка идёт блоками размером в байт. Поэтому 21AB при обратном порядке будет прочтено как AB21, а не BA12.
Чтобы переставлять ещё и полубайты в байте, нужны спец. меры.
Я с этим недавно столкнулся в понятии PLMN id (идентификатор мобильной сети): в актуальных стандартах его упаковывают в 3 байта в BCD (binary coded decimal) формате с переставленными полубайтами.
Например MCC=123, MNC=45 будет представлено 3 байтами: 0x21 0xf3 0x54 ('f' тут заполнитель для двузначного номера сети). Заметим, что MNC=45 и MNC=045 это разные случаи(!), во втором будет представление 0x21 0x03 0x54.
Так что, возможно, у вас ещё всё впереди
P>В двоичной записи это 21AB — это 0010 0001 1010 1011. P>Почему тогда его записали как BA12 1011 1010 0001 0010, P>а не как 1101 0101 1000 0100 ( D584 )?
Разворот порядка битов тоже имеет значение в некоторых случаях: тут
Здравствуйте, Андрей Тарасевич, Вы писали:
АТ>P.S. На многих платформах существуют машинные команды, которые действительно "адресуют", т.е. локально нумеруют индивидуальные биты в байте. Но там везде действует единое соглашение: младшие по значимости биты имеют младшие номера. То есть нумерация битов всегда и везде подчиняется правилам условного "little-endian" и никакого "плюрализма мнений" не допускается.
Вы явно не всё знаете. На System/Z адресация в соответствующих командах (например, RISBG) сделана так, что 0 — старший. Это последовательная big endian архитектура (и самая живучая из них на сейчас). Возможно, есть и другие (облом искать), одного контрпримера достаточно.
В стандартах IETF вся нумерация сделана так, что 0 — старший бит (в байте или слове), при реализации на несоответствующих этому архитектурах приходится пересчитывать. Это не железо, но всё равно влиятельный источник.
АТ>Биты не являются индивидуально адресуемыми, поэтому к ним понятие "endianness" не применимо вообще. У битов нет "порядка в памяти".
Он появляется, когда надо рассматривать сквозной порядок битов между разными байтами, , я рядом писал уже про особенности
работы с bitset. Это точно так же обсуждено со всех сторон в основополагающем документе (именно тут был введён термин endianness), там явно упоминается, что может быть bit order, byte order, word order... и какие могут быть проблемы от их рассогласования.
AT> Поэтому не ясно, с чего это вдруг вы собрались их переворачивать. "Переворачивать" относительно чего?
Это совершенно логичная (хоть и не единственная такая) мысль и я не вижу в ней ничего неясного. Просто требуется введение в то, как оно работает сейчас и почему.