Как зайти в Даркнет?!
25th January, 01:11
6
0
Как в tkinter из поля ввода Entry получить значение в одну переменную и обновить строку кнопкой, затем получить ещё одно введённое значение и затем сложить их. Ниже пример кода
21st July, 19:00
895
0
Программа, которая создает фейковые сервера в поиске игровых серверов CS 1.6 Steam
21st March, 17:43
948
0
Очень долго работает Update запрос Oracle
27th January, 09:58
914
0
не могу запустить сервер на tomcat HTTP Status 404 – Not Found
21st January, 18:02
905
0
Где можно найти фрилансера для выполнения поступающих задач, на постоянной основе?
2nd December, 09:48
938
0
Разработка мобильной кроссплатформенной военной игры
16th July, 17:57
1724
0
период по дням
25th October, 10:44
3955
0
Пишу скрипты для BAS только на запросах
16th September, 02:42
3720
0
Некорректный скрипт для закрытия блока
14th April, 18:33
4613
0
прокидывать exception в блоках try-catch JAVA
11th March, 21:11
4381
0
Помогите пожалуйста решить задачи
24th November, 23:53
6086
0
Не понимаю почему не открывается детальное описание продукта
11th November, 11:51
4351
0
Нужно решить задачу по программированию на массивы
27th October, 18:01
4396
0
Метода Крамера С++
23rd October, 11:55
4309
0
помогите решить задачу на C++
22nd October, 17:31
4002
0
Помогите решить задачу на python с codeforces
22nd October, 11:11
4492
0
Python с нуля: полное руководство для начинающих
18th June, 13:58
2599
0
Типы байтов
В чем разница между следующими типами байтов?
- байт (8b) инвариантная большая и малая конечность
- полуслова (16b) инвариантная большая и малая конечность
- слово (32b) инвариантная большая и малая конечность
- двойное слово (64b) инвариантная большая и малая конечность
Есть ли другие types/variations?
Существует два подхода к эндианскому отображению: инвариантность адреса и инвариантность данных .
Инвариантность Адреса
В этом типе отображения адрес байтов всегда сохраняется между большим и малым. Это имеет побочный эффект изменения порядка значимости (от наиболее значимого к наименее значимому) конкретного датума (например, 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. Эффект сохранения значения конкретного размера datum заключается в том, что байтовые адреса байтов внутри datum меняются местами между большими и малыми конечными отображениями.
Пример
32-разрядная инвариантность данных( также известная как инвариантность слов): datum-это 32-разрядное слово , которое всегда имеет значение 0xddccbbaa, независимо от endianness. Однако для обращений, размер которых меньше слова, адреса байтов меняются местами между большими и малыми конечными отображениями.
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)
Филибер сказал:,
биты были фактически перевернуты
Я сомневаюсь, что любая архитектура нарушит инвариантность значений байтов. Порядок битовых полей может нуждаться в инверсии при сопоставлении структур, содержащих их, с данными. Такое прямое сопоставление опирается на специфику компилятора, которая находится за пределами стандарта 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;
Причина необходимости инвертировать порядок битовых полей в каждом конечном нейтральном блоке хранения данных для конкретного приложения заключается в том, что компиляторы упаковывают битовые поля в байты растущих адресов.
"order of bits" в каждом байте не имеет значения, поскольку единственный способ извлечь их-это применить маски значений и перейти в направлении least-significant-bit или most-significant-bit. Проблема "order of bits" станет важной только в воображаемых архитектурах с понятием битовых адресов. Я считаю, что все существующие архитектуры скрывают это понятие в аппаратном обеспечении и обеспечивают только наименьшее и самое значительное извлечение битов, которое основано на конечных нейтральных байтовых значениях.
Есть также средний или смешанный эндиан. Подробности смотрите в Википедии .
Единственный раз, когда я должен был беспокоиться об этом, был при написании некоторого сетевого кода в C. Сетей, как правило, используется обратный порядок байтов IIRC. Большинство языков либо абстрагируют все это, либо предлагают библиотеки, чтобы гарантировать, что вы используете правильный конечный язык.
На самом деле, я бы описал конечность машины как порядок байтов внутри слова, а не порядок битов .
Под "bytes" там наверху я подразумеваю "smallest unit of memory the architecture can manage individually". Итак, если самая маленькая единица имеет длину 16 бит (то, что в x86 называется словом ) , то 32 бит "word", представляющий значение 0xFFFF0000, может быть сохранен следующим образом:
FFFF 0000
или вот это:
0000 FFFF
в памяти, в зависимости от конечности.
Итак, если у вас есть 8-битная конечность, это означает, что каждое слово, состоящее из 16 бит, будет храниться как:
FF 00
или:
00 FF
и так далее.
Практически говоря, endianess относится к тому, как процессор будет интерпретировать содержимое данного места памяти. Например, если у нас есть ячейка памяти 0x100 со следующим содержимым (hex байт)
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
Две ситуации, в которых вам нужно иметь в виду endianess, связаны с сетевым кодом, и если вы делаете вниз кастинг с указателями.
TCP/IP определяет, что сведения о провод должен быть с обратным порядком байтов. Если вы передаете типы, отличные от байтовых массивов (например, указатели на структуры), вы должны убедиться, что используете ntoh/hton macros, чтобы гарантировать, что данные передаются big endian. Если вы отправляете данные от процессора с малым концом к процессору с большим концом (или наоборот), данные будут искажены...
Вопросы кастинга:
uint32_t* lptr = 0x100;
uint16_t data;
*lptr = 0x0000FFFF
data = *((uint16_t*)lptr);
Какова будет ценность данных? В системе с большим концом она будет равна 0, в системе с малым концом-FFFF
13 лет назад я работал над инструментом, переносимым как на систему DEC ALPHA, так и на PC. На этом декодере биты были фактически перевернуты . То есть:
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;
};
основной концепцией является упорядочение битов:
1010 0011
в little-endian является таким же, как
0011 1010
у тупоконечников (и наоборот).
Вы заметите, что порядок меняется по группам, а не по отдельным битам. Я не знаю, например, какой системы, где
1100 0101
это будет версия "other-endian" первой версии.