|
А кто ткнет в наиболее правильный способ, борьбы с индианностью в С |
|
|
|
 |
Ответов
|
Jul 19 2005, 10:45
|
Участник

Группа: Свой
Сообщений: 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-ов, далее под разные платформы выбираются (линкуются) разные варианты.  Другой момент - обмен данными между устройствами (процессорами), у которых разный endian. Частный случай - если данные как-либо сохраняются в одном типе, а считываются уже на платформе с другим типом. Проблемы возникают тоько при обмене и только если данные процессором беруться из канала обмена (или из файла) не по байтам, а бОльшими порциями. Одно из решений (не самое лучшее по скорости работы, но лучшее в смысле переносимости) - передавать и принимать данные побайтно. Т.е. если надо передать 2х байтное слово, то выделяем и передаём сначала старший байт, далее младший; на приёмной стороне обратный процесс - считываем один байт, другой, и из двух этих байтов формируем сдвигами нужное нам число. Переносимость стопроцентная. То же можно организовать при сохранении/считывании данных на/с долговременных носителей. Если же нужна скорость, то при передаче данных всё равно кто-то должен делать перекодировку endiana, и выбирается та сторона, которой можно потормозить больше.
|
|
|
|
|
Jul 20 2005, 06:01
|
Участник

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

|
Цитата(Eugeno @ Jul 19 2005, 13:45)  Другой момент - обмен данными между устройствами (процессорами), у которых разный 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
|
|
|
|
|
Jul 20 2005, 09:12
|
Гуру
     
Группа: СуперМодераторы
Сообщений: 2 065
Регистрация: 11-01-05
Из: Москва
Пользователь №: 1 892

|
Спасибо всем ответившим!!! Но у меня окончательно снесло башню  . Пытаюсь разобраться. Код [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ов одинаковы????
|
|
|
|
|
Jul 20 2005, 14:07
|
Участник

Группа: Свой
Сообщений: 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
|
|
|
|
Сообщений в этой теме
Evgeny_CD А кто ткнет в наиболее правильный способ Jul 11 2005, 12:55 Andrew2000 #ifdef BIG_ENDIAN
#define intswap(x) ((((x)&0x... Jul 11 2005, 13:20 Evgeny_CD Цитата(Andrew2000 @ Jul 11 2005, 17:20)#ifdef... Jul 11 2005, 13:37  acex2 Цитата(Evgeny_CD @ Jul 11 2005, 10:37)Хотелос... Jul 11 2005, 14:30   Evgeny_CD Цитата(acex2 @ Jul 11 2005, 18:30)А вы посмот... Jul 11 2005, 15:17 Zig Можно ещё попробовать вот такую функцию:
Код/*
Вы... Jul 18 2005, 14:07 Zig Можно ещё попробовать вот такую функцию:
Код/*
Вы... Jul 18 2005, 14:10 acex2 Цитата(Zig @ Jul 18 2005, 11:10)Можно ещё поп... Jul 18 2005, 15:57 acex2 Цитата(Eugeno @ Jul 19 2005, 07:45)Если же ну... Jul 19 2005, 11:48    Evgeny_CD Цитата(Hercules @ Jul 20 2005, 18:07)Все ARM-... Jul 20 2005, 21:44 Eugeno Цитата(Evgeny_CD @ Jul 11 2005, 15:55)Кстати,... Jul 19 2005, 12:39
1 чел. читают эту тему (гостей: 1, скрытых пользователей: 0)
Пользователей: 0
|
|
|