реклама на сайте
подробности

 
 
> А кто ткнет в наиболее правильный способ, борьбы с индианностью в С
Evgeny_CD
сообщение Jul 11 2005, 12:55
Сообщение #1


Гуру
******

Группа: СуперМодераторы
Сообщений: 2 065
Регистрация: 11-01-05
Из: Москва
Пользователь №: 1 892



Пишется код. Он будет идти на разных платформах/компилерах. Почти наверняка будет разная endian: младший байт вначале (прямой порядок, Little Endian) или старший байт в начале (обратный порядок, Big Endian).

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

Кстати, а с 32 битами приколов разной индианности не бывает (когда для dword и word раные endian)?

Какой наиболее правильный способ борьбы с этим?
Go to the top of the page
 
+Quote Post
 
Start new topic
Ответов
Eugeno
сообщение Jul 19 2005, 10:45
Сообщение #2


Участник
*

Группа: Свой
Сообщений: 19
Регистрация: 12-04-05
Из: Таганрог, Ростовской обл.
Пользователь №: 4 048



Цитата(Evgeny_CD @ Jul 11 2005, 15:55)
Пишется код. Он будет идти на разных платформах/компилерах. Почти наверняка будет разная endian: младший байт вначале (прямой порядок, Little Endian) или старший байт в начале (обратный порядок, Big Endian).

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

Кстати, а с 32 битами приколов разной индианности не бывает (когда для dword и word раные endian)?

Какой наиболее правильный способ борьбы с этим?
*


Если программа работает c данными только на одной платформе, то проблем меньше. Endian-о зависимые участки кода локализуются и переписываются для разных Endian-ов, далее под разные платформы выбираются (линкуются) разные варианты.

angry.gif Другой момент - обмен данными между устройствами (процессорами), у которых разный endian. Частный случай - если данные как-либо сохраняются в одном типе, а считываются уже на платформе с другим типом.
Проблемы возникают тоько при обмене и только если данные процессором беруться из канала обмена (или из файла) не по байтам, а бОльшими порциями. Одно из решений (не самое лучшее по скорости работы, но лучшее в смысле переносимости) - передавать и принимать данные побайтно. Т.е. если надо передать 2х байтное слово, то выделяем и передаём сначала старший байт, далее младший; на приёмной стороне обратный процесс - считываем один байт, другой, и из двух этих байтов формируем сдвигами нужное нам число. Переносимость стопроцентная. То же можно организовать при сохранении/считывании данных на/с долговременных носителей.
Если же нужна скорость, то при передаче данных всё равно кто-то должен делать перекодировку endiana, и выбирается та сторона, которой можно потормозить больше.
Go to the top of the page
 
+Quote Post
Hercules
сообщение Jul 20 2005, 06:01
Сообщение #3


Участник
*

Группа: Свой
Сообщений: 54
Регистрация: 2-03-05
Пользователь №: 3 000



Цитата(Eugeno @ Jul 19 2005, 13:45)
angry.gif Другой момент - обмен данными между устройствами (процессорами), у которых разный endian. Частный случай - если данные как-либо сохраняются в одном типе, а считываются уже на платформе с другим типом.
Проблемы возникают тоько при обмене и только если данные процессором беруться из канала обмена (или из файла) не по байтам, а бОльшими порциями. Одно из решений (не самое лучшее по скорости работы, но лучшее в смысле переносимости) - передавать и принимать данные побайтно. Т.е. если надо передать 2х байтное слово, то выделяем и передаём сначала старший байт, далее младший; на приёмной стороне обратный процесс - считываем один байт, другой, и из двух этих байтов формируем сдвигами нужное нам число. Переносимость стопроцентная. То же можно организовать при сохранении/считывании данных на/с долговременных носителей.
Если же нужна скорость, то при передаче данных всё равно кто-то должен делать перекодировку endiana, и выбирается та сторона, которой можно потормозить больше.
*


Вообще-то, обычная практика при обмене между двумя устройствами (с разными или одинаковыми endian) приводить порядок следования байт к одному виду, а именно к "network byte order" (ака bigendian). А на хосте используются функции конвертации из "network byte order" к порядку следования байт на хосте и обратно типа: htonl (для 32-х разрядов), htons (для 16-ти разрядов).
Эти функции в зависимости от того какой endian на хосте либо крутят байты, либо нет.

Пример:

#ifndef LITTLE_ENDIAN
#define LITTLE_ENDIAN 3412
#endif /* LITTLE_ENDIAN */

#ifndef BIG_ENDIAN
#define BIG_ENDIAN 1234
#endif /* BIG_ENDIAN */


#ifndef BYTE_ORDER
#error BYTE_ORDER is not defined
#endif

#if BYTE_ORDER == LITTLE_ENDIAN
u16_t htons(u16_t n)
{
return ((n & 0xff) << 8) | ((n & 0xff00) >> 8);
}

u16_t ntohs(u16_t n)
{
return htons(n);
}

u32_t htonl(u32_t n)
{
return ((n & 0xff) << 24) |
((n & 0xff00) << 8) |
((n & 0xff0000) >> 8) |
((n & 0xff000000) >> 24);
}

u32_t ntohl(u32_t n)
{
return htonl(n);
}
#else /* BYTE_ORDER == BIG_ENDIAN */

#define htons(x) (x)
#define ntohs(x) (x)
#define htonl(x) (x)
#define ntohl(x) (x)

#endif /* BYTE_ORDER == LITTLE_ENDIAN */


--------------------
Best regards,
Hercules
Go to the top of the page
 
+Quote Post
Evgeny_CD
сообщение Jul 20 2005, 09:12
Сообщение #4


Гуру
******

Группа: СуперМодераторы
Сообщений: 2 065
Регистрация: 11-01-05
Из: Москва
Пользователь №: 1 892



Спасибо всем ответившим!!!

Но у меня окончательно снесло башню wacko.gif . Пытаюсь разобраться.

Код
[b31---byte_dword_3---b24][b23---byte_dword_2---b16][b15---byte_dword_1---b8][b7---byte_dword_0---b0]
|~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~dword_0~~~~~~~~~~~~~~~~~~~~~~~~
~~~~~~~~~~~~~~~~~~~~|
[b15----byte_word_1----b8][b7----byte_word_0-----b0][b15----byte_word_1---b8][b7----byte_word_0---b0]
|~~~~~~~~~~~~~~~~~~~~word_1~~~~~~~~~~~~~~~~~~~~~~~~||~~~~~~~~~~~~~~~~~~~~~word_0
~~~~~~~~~~~~~~~~~~~~|

b0 - бит 0 - младший бит - LSB
b31 - бит 31 - старший бит - MSB

byte_dword_0 - младший байт - LSB
byte_dword_3 - старший байт - MSB

word_0 - младший word - LSW (его так и вправду обозначают???)
word_1 - старший word - MSW (его так и вправду обозначают???)

byte_word_0 - младший байт - LSB
byte_word_1 - старший байт - MSB

BASE - адрес dword_0

********************** BIG ENDIAN ******************************************************
* байты внутри word - {BIG ENDIAN}, старшие вначале
* байты внутри dword - {BIG ENDIAN}, старшие вначале
* word внутри dword - {BIG ENDIAN}, старшие вначале

word_0{BIG ENDIAN}----BASE+0x00 = [byte_dword_3] = word_1{BIG ENDIAN}-[byte_word_1]
                  \---BASE+0x01 = [byte_dword_2] =                   \[byte_word_0]
                   \--BASE+0x02 = [byte_dword_1] = word_0{BIG ENDIAN}-[byte_word_1]
                    \-BASE+0x03 = [byte_dword_0] =                   \[byte_word_0]
********************************************************************************
*********

*********************** LITTLE ENDIAN ***************************************************
* байты внутри word - {LITTLE ENDIAN}, младшие вначале
* байты внутри dword - {LITTLE ENDIAN}, младшие вначале
* word внутри dword - {LITTLE ENDIAN}, младшие вначале

word_0{LITTLE ENDIAN}----BASE+0x00 = [byte_dword_0] = word_0{LITTLE ENDIAN}-[byte_word_0]
                     \---BASE+0x01 = [byte_dword_1] =                      \[byte_word_1]
                      \--BASE+0x02 = [byte_dword_2] = word_1{LITTLE ENDIAN}-[byte_word_0]
                       \-BASE+0x03 = [byte_dword_3] =                      \[byte_word_1]
********************************************************************************
*********

*** А это что за нафиг??? И как его назвать??? Насколько я понимаю, так PDP-11 жила... **
* байты внутри word - {BIG ENDIAN}, старшие вначале
* word внутри dword - {LITTLE ENDIAN}, младшие вначале
* байты внутри word ????

word_0{CRAZY_1}----BASE+0x00 = [byte_dword_1] = word_0{BIG ENDIAN}-[byte_word_1]
               \---BASE+0x01 = [byte_dword_0] =                   \[byte_word_0]
                \--BASE+0x02 = [byte_dword_3] = word_1{BIG ENDIAN}-[byte_word_1]
                 \-BASE+0x03 = [byte_dword_2] =                   \[byte_word_0]
********************************************************************************
*********

************************** комплементарное извращение ***********************************
* байты внутри word - {LITTLE ENDIAN}, младшие вначале
* word внутри dword - {BIG ENDIAN}, старшие вначале
* байты внутри word ???
word_0{CRAZY_2}----BASE+0x00 = [byte_dword_2] = word_1{LITTLE ENDIAN}-[byte_word_0]
               \---BASE+0x01 = [byte_dword_3] =                      \[byte_word_1]
                \--BASE+0x02 = [byte_dword_0] = word_0{LITTLE ENDIAN}-[byte_word_0]
                 \-BASE+0x03 = [byte_dword_1] =                      \[byte_word_1]
********************************************************************************
*********

Интересно, а в 64 битных машинках все тоже не договорились, и там существуют 8 комбинаций индианов???

Вопрос: когда говорят ARM LITTLE ENDIAN, ARM BIG ENDIAN - кака я из комбинаций имеется в виду? Они у всех ARMов одинаковы????
Go to the top of the page
 
+Quote Post
Hercules
сообщение Jul 20 2005, 14:07
Сообщение #5


Участник
*

Группа: Свой
Сообщений: 54
Регистрация: 2-03-05
Пользователь №: 3 000



Цитата(Evgeny_CD @ Jul 20 2005, 12:12)
Вопрос: когда говорят ARM LITTLE ENDIAN, ARM BIG ENDIAN - кака я из комбинаций имеется в виду?
*


Может быть так будет понятней:

Код
 
Пусть у нас при 8-ми битном доступе:
addr      value
0x0000   0x12
0x0001   0x34
0x0002   0x56
0x0003   0x78
0x0004   0x9A
0x0005   0xBC
0x0006   0xDE
0x0007   0xF0

Тогда для LITLE_ENDIAN эта же память при 16-ти разрядном доступе будет выглядеть так:
addr      value
0x0000   0x3412
0x0002   0x7856
0x0004   0xBC9A
0x0006   0xF0DE

При 32-ти разрядном доступе:
addr      value
0x0000   0x78563412
0x0004   0xF0DEBC9A

При 64-ти разрядном доступе:
addr      value
0x0000   0xF0DEBC9A78563412

А для BIG_ENDIAN эта же память при 16-ти разрядном доступе будет выглядеть так:
addr      value
0x0000   0x1234
0x0002   0x5678
0x0004   0x9ABC
0x0006   0xDEF0

При 32-ти разрядном доступе:
addr      value
0x0000   0x12345678
0x0004   0x9ABCDEF0

При 64-ти разрядном доступе:
addr      value
0x0000   0x123456789ABCDEF0


т.е. если говорят ARM LITTLE ENDIAN, то имеется ввиду порядок байт в слове: 0x4321 (если рассматривать 16-ти разрядный доступ),

а если говорят ARM BIG ENDIAN, то имеется ввиду порядок байт в слове: 0x1234 (если рассматривать 16-ти разрядный доступ)


Цитата(Evgeny_CD @ Jul 20 2005, 12:12)
Они у всех ARMов одинаковы????
*


Все ARM-ы с одинаковым ENDIAN имеют один и тот же порядок следования байт в слове (если это имелось ввиду).


--------------------
Best regards,
Hercules
Go to the top of the page
 
+Quote Post

Сообщений в этой теме


Reply to this topicStart new topic
1 чел. читают эту тему (гостей: 1, скрытых пользователей: 0)
Пользователей: 0

 


RSS Текстовая версия Сейчас: 24th June 2025 - 05:01
Рейтинг@Mail.ru


Страница сгенерированна за 0.01419 секунд с 7
ELECTRONIX ©2004-2016