Типы байтов

В чем разница между следующими типами байтов?

  • байт (8b) инвариант большого и малого порядка байтов
  • полуслово (16b) инвариант больших и малых порядков байтов
  • слово (32b) инвариант большой и маленький порядковый номер
  • двойное слово (64b) инвариант большого и малого порядка байтов

Существуют ли другие типы / варианты?

21.08.2008 23:42:44
Если ваша система имеет 128-битные типы данных, у вас, конечно, есть большое слово quadword и порядок байтов. // Это часто возникает в многопроцессорном коде, где у вас есть инструкции, такие как Intel CMPXCHG16B: представьте, что LE x86 разговаривает с устройством ввода / вывода Big Endian.
Krazy Glew 14.09.2016 22:34:46
8 ОТВЕТОВ

основная концепция - это порядок следования битов:

1010 0011

в порядке байтов так же, как

0011 1010

в обратном порядке (и наоборот).

Вы заметите изменения порядка по группам, а не по отдельным битам. Я не знаю системы, например, где

1100 0101

будет "обратным порядком" версия первой версии.

-1
21.08.2008 23:49:01
Как правило, порядковый номер байтовый, но вы описали здесь порядковый номер байтов (группы из 4, а не 8 битов, которые, я сомневаюсь, что-либо использует).
Scott Griffiths 9.09.2009 20:41:30

Также есть средний или смешанный порядок байтов. Смотрите википедию для деталей.

Единственное время, когда мне приходилось беспокоиться об этом, было при написании некоторого сетевого кода на языке C. Сеть обычно использует IIRC с прямым порядком байтов. Большинство языков либо абстрагируют все целиком, либо предлагают библиотеки, чтобы гарантировать, что вы используете правильный порядок байтов.

3
21.08.2008 23:57:39

На самом деле, я бы описал порядковый номер машины как порядок байтов внутри слова, а не порядок битов .

Под «байтами» я подразумеваю «наименьшую единицу памяти, которой архитектура может управлять индивидуально». Итак, если наименьшая единица имеет длину 16 бит (то, что в x86 будет называться словом ), тогда 32-битное «слово», представляющее значение 0xFFFF0000, может быть сохранено так:

FFFF 0000

или это:

0000 FFFF

в памяти, в зависимости от порядка байтов.

Итак, если у вас есть 8-битный порядок байтов, это означает, что каждое слово, состоящее из 16 битов, будет храниться как:

FF 00

или:

00 FF

и так далее.

1
22.08.2008 00:39:51
Извините, но это очень смущает. Порядковый номер (почти) всегда либо побитовый, либо чаще побайтный, где байт - это стандартные восемь битов. Ваш FFFF0000пример плохо выбран, так как он становится, 0000FFFFесли вы поменяете его битами, байтами или словами, поэтому невозможно сказать, что вы пытаетесь сказать!
Scott Griffiths 26.10.2009 16:18:22
Да, вы абсолютно правы, я просто поленился, LOL. Спасибо за указание, хотя :)
dguaraglia 15.11.2009 22:18:02
Я говорю «байтовый порядок байтов» или «битовый порядок байтов», когда мне нужно различить.
Krazy Glew 19.02.2014 02:05:59

Лучшая статья, которую я прочитал о порядке байтов " Понимание старшего и младшего байтового порядка ".

1
22.08.2008 01:57:42

Есть два подхода к Endian отображения: адрес инвариантность и инвариантность данных .

Адресная Инвариантность

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

пример

Инвариантность адреса (также известная как байтовая инвариантность ): адрес байта является постоянным, но значение байта меняется на противоположное.

Addr   Memory
       7    0
       |    |    (LE)   (BE)
       |----|
 +0    | aa |    lsb    msb
       |----|
 +1    | bb |     :      :
       |----|
 +2    | cc |     :      :
       |----|
 +3    | dd |    msb    lsb
       |----|
       |    |

At Addr=0:          Little-endian          Big-endian
Read 1 byte:              0xaa                0xaa   (preserved)
Read 2 bytes:           0xbbaa              0xaabb
Read 4 bytes:       0xddccbbaa          0xaabbccdd

Инвариантность данных

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

пример

32-битная инвариантность данных (также известная как инвариантность слова ): элемент данных - это 32-битное слово, которое всегда имеет значение 0xddccbbaa, не зависящее от порядка байтов. Тем не менее, для обращений, меньших слова, адрес байтов меняется на обратный.

Addr                Memory

            | +3   +2   +1   +0 |  <- LE
            |-------------------|
+0      msb | dd | cc | bb | aa |  lsb
            |-------------------|
+4      msb | 99 | 88 | 77 | 66 |  lsb
            |-------------------|
     BE ->  | +0   +1   +2   +3 |


At Addr=0:             Little-endian              Big-endian
Read 1 byte:                 0xaa                    0xdd
Read 2 bytes:              0xbbaa                  0xddcc
Read 4 bytes:          0xddccbbaa              0xddccbbaa   (preserved)
Read 8 bytes:  0x99887766ddccbbaa      0x99887766ddccbbaa   (preserved)

пример

16-битная инвариантность данных (также известная как инвариантность половинных слов ): элемент данных - это 16-битный, который всегда имеет значение 0xbbaa, не зависящее от порядка байтов. Тем не менее, для обращений, меньших половины слова, адрес байтов инвертируется между отображениями с прямым и прямым порядком байтов.

Addr           Memory

            | +1   +0 |  <- LE
            |---------|
+0      msb | bb | aa |  lsb
            |---------|
+2      msb | dd | cc |  lsb
            |---------|
+4      msb | 77 | 66 |  lsb
            |---------|
+6      msb | 99 | 88 |  lsb
            |---------|
     BE ->  | +0   +1 |


At Addr=0:             Little-endian              Big-endian
Read 1 byte:                 0xaa                    0xbb
Read 2 bytes:              0xbbaa                  0xbbaa   (preserved)
Read 4 bytes:          0xddccbbaa              0xddccbbaa   (preserved)
Read 8 bytes:  0x99887766ddccbbaa      0x99887766ddccbbaa   (preserved)

пример

64-битная инвариантность данных (также известная как инвариантность двойных слов ): элемент данных - это 64-битное слово, которое всегда имеет значение 0x99887766ddccbbaa, не зависящее от порядка байтов. Тем не менее, для обращений, меньших двойного слова, адрес байтов меняется на обратный.

Addr                         Memory

            | +7   +6   +5   +4   +3   +2   +1   +0 |  <- LE
            |---------------------------------------|
+0      msb | 99 | 88 | 77 | 66 | dd | cc | bb | aa |  lsb
            |---------------------------------------|
     BE ->  | +0   +1   +2   +3   +4   +5   +6   +7 |


At Addr=0:             Little-endian              Big-endian
Read 1 byte:                 0xaa                    0x99
Read 2 bytes:              0xbbaa                  0x9988
Read 4 bytes:          0xddccbbaa              0x99887766
Read 8 bytes:  0x99887766ddccbbaa      0x99887766ddccbbaa   (preserved)
25
14.09.2008 23:46:37

Практически говоря, endianess относится к тому, как процессор будет интерпретировать содержимое заданной области памяти. Например, если у нас есть ячейка памяти 0x100 со следующим содержимым (шестнадцатеричные байты)


  0x100:  12 34 56 78 90 ab cd ef

Reads    Little Endian            Big Endian
 8-bit:  12                        12
16-bit:  34 12                     12 34
32-bit:  78 56 34 12               12 34 56 78
64-bit:  ef cd ab 90 78 56 34 12   12 34 56 78 90 ab cd ef

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

TCP / IP указывает, что данные на проводе должны иметь порядок байтов. Если вы передаете типы, отличные от байтовых массивов (например, указатели на структуры), вы должны обязательно использовать макросы ntoh / hton, чтобы гарантировать, что данные отправляются с прямым порядком байтов. Если вы отправляете из процессора с прямым порядком байтов в процессор с прямым порядком байтов (или наоборот), данные будут искажены ...

Проблемы с кастингом:


 uint32_t* lptr = 0x100;
 uint16_t  data;
 *lptr = 0x0000FFFF

 data = *((uint16_t*)lptr);

Какова будет ценность данных? В системе с прямым порядком байтов это будет 0 В системе с прямым порядком байтов это будет FFFF

0
16.09.2008 01:53:37

13 лет назад я работал над инструментом, переносимым как на систему DEC ALPHA, так и на ПК. На этом DEC ALPHA биты были фактически инвертированы . Это:

1010 0011

на самом деле переводится на

1100 0101

Это было почти прозрачно и незаметно в коде C, за исключением того, что у меня было битовое поле, объявленное как

typedef struct {
   int firstbit:1;
   int middlebits:10;
   int lastbits:21;
};

что нужно перевести на (используя условную компиляцию #ifdef)

typedef struct {
   int lastbits:21;
   int middlebits:10;
   int firstbit:1;
};
0
16.09.2008 03:27:04
Порядок назначения битовых полей в слове определяется реализацией. Первое указанное поле может быть в MSB или LSB (старший или младший значащий байт или бит, в зависимости от того, на что вы хотите посмотреть). Вы нашли это трудным путем. Ни одна из систем неверна; выбранные реализации просто разные.
Jonathan Leffler 19.04.2015 06:05:26

Филиберт сказал:

биты были фактически инвертированы

Я сомневаюсь, что любая архитектура нарушит неизменность байтового значения. Порядок битовых полей может нуждаться в инверсии при отображении структур, содержащих их, против данных. Такое прямое отображение опирается на особенности компилятора, которые находятся за пределами стандарта C99, но которые все еще могут быть распространены. Прямое отображение выполняется быстрее, но не соответствует стандарту C99, который не предусматривает упаковку, выравнивание и порядок байтов. C99-совместимый код должен использовать медленное отображение на основе значений, а не адресов. То есть вместо того, чтобы делать это,

#if LITTLE_ENDIAN
  struct breakdown_t {
    int least_significant_bit: 1;
    int middle_bits: 10;
    int most_significant_bits: 21;
  };
#elif BIG_ENDIAN
  struct breakdown_t {
    int most_significant_bits: 21;
    int middle_bits: 10;
    int least_significant_bit: 1;
  };
#else
  #error Huh
#endif

uint32_t data = ...;
struct breakdown_t *b = (struct breakdown_t *)&data;

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

uint32_t data = ...;
uint32_t least_significant_bit = data & 0x00000001;
uint32_t middle_bits = (data >> 1) & 0x000003FF;
uint32_t most_significant_bits = (data >> 11) & 0x001fffff;

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

«Порядок битов» в каждом байте не имеет значения, так как единственный способ извлечь их - применить маски значений и сместиться в направлении младшего бита или старшего бита. Проблема «порядка битов» станет важной только в воображаемых архитектурах с понятием битовых адресов. Я полагаю, что все существующие архитектуры скрывают это понятие в аппаратном обеспечении и обеспечивают только наименьшее по сравнению с наиболее значительным извлечение битов, которое основано на байтово-нейтральных значениях байтов.

3
23.05.2017 11:53:30
Легко нарушить неизменность значения байта. Например, у вас есть 8-битная шина, биты данных 0-7, и вы подключаете их к устройству или памяти назад - т.е. вы подключаете Dev0.Bit0-Dev1.Bit7, Dev0.Bit1-Dev1.Bit6 ... Dev0.Bit7 -Dev1.Bit0. // Возможно, вы не столкнетесь с этим во всей системе, но это МОЖЕТ произойти, и часто это происходит для узкой области памяти и т. Д. // Я склонен использовать такие термины как «битовая последовательность» и «байтовая последовательность», чтобы быть точным в том, что обсуждается.
Krazy Glew 14.09.2016 22:26:34