Evgeny_CD 0 11 июля, 2005 Опубликовано 11 июля, 2005 · Жалоба Пишется код. Он будет идти на разных платформах/компилерах. Почти наверняка будет разная endian: младший байт вначале (прямой порядок, Little Endian) или старший байт в начале (обратный порядок, Big Endian). Соотвественно, если к какой-то переменной обращаются не только как, например, int (он тоже разный на разных платформах), но и как к массиву из 2 или 4 байтов, то это вызовет очень веселые глюки. Кстати, а с 32 битами приколов разной индианности не бывает (когда для dword и word раные endian)? Какой наиболее правильный способ борьбы с этим? Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Andrew2000 0 11 июля, 2005 Опубликовано 11 июля, 2005 · Жалоба #ifdef BIG_ENDIAN #define intswap(x) ((((x)&0x00ff)<<8)|(((x)& 0xff00)>>8)) #else #define intswap(a) a #endif или что-то типа этого Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Evgeny_CD 0 11 июля, 2005 Опубликовано 11 июля, 2005 · Жалоба #ifdef BIG_ENDIAN #define intswap(x) ((((x)&0x00ff)<<8)|(((x)& 0xff00)>>8)) #else #define intswap(a) a #endif или что-то типа этого <{POST_SNAPBACK}> Спасибо! Но в таком случае при разной индианности будет разное количество операций. Что не есть гуд. Хотелось бы идею, как свести алгоритм к примитивам, а их уже менять макросами в зависимости от дефайна. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
acex2 0 11 июля, 2005 Опубликовано 11 июля, 2005 · Жалоба Хотелось бы идею, как свести алгоритм к примитивам, а их уже менять макросами в зависимости от дефайна. А вы посмотрите исходники криптографических алгоритмов на Си - там такая задача решается именно через define и макроопределения базовых операций с байтами в зависимости от индианности. Но вот сохранить равное количество команд вряд-ли получится, разве что отключать оптимизацию компилятора или специально вводить nop. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Evgeny_CD 0 11 июля, 2005 Опубликовано 11 июля, 2005 · Жалоба А вы посмотрите исходники криптографических алгоритмов на Си - там такая задача решается именно через define и макроопределения базовых операций с байтами в зависимости от индианности. Но вот сохранить равное количество команд вряд-ли получится, разве что отключать оптимизацию компилятора или специально вводить nop. Хорошая мысль! Спасибо! Искуственно замедлять проц не надо, надо не нагружать его лишней работой. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Zig 28 18 июля, 2005 Опубликовано 18 июля, 2005 · Жалоба Можно ещё попробовать вот такую функцию: /* Вычисление endian'ности в реальном времени */ int is_little_endian( void ) { union { unsigned long i; unsigned char b[sizeof(i)]; } test; } Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Zig 28 18 июля, 2005 Опубликовано 18 июля, 2005 · Жалоба Можно ещё попробовать вот такую функцию: /* Вычисление endian'ности в реальном времени Должно возвращать 1: Intel (little endian), 0: Power PC (big endian) */ int is_little_endian( void ) { union Test { int i; char b[sizeof(int)]; }; static const Test test = { 1 }; return test.b[0]; } Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
acex2 0 18 июля, 2005 Опубликовано 18 июля, 2005 · Жалоба Можно ещё попробовать вот такую функцию: Вычисление endian'ности в реальном времени Должно возвращать 1: Intel (little endian), 0: Power PC (big endian) skipped А смысл такой функции кроме академического интереса? Бинарный код все равно придется перекомпилировать под конкретный процессор. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Eugeno 0 19 июля, 2005 Опубликовано 19 июля, 2005 · Жалоба Пишется код. Он будет идти на разных платформах/компилерах. Почти наверняка будет разная endian: младший байт вначале (прямой порядок, Little Endian) или старший байт в начале (обратный порядок, Big Endian). Соотвественно, если к какой-то переменной обращаются не только как, например, int (он тоже разный на разных платформах), но и как к массиву из 2 или 4 байтов, то это вызовет очень веселые глюки. Кстати, а с 32 битами приколов разной индианности не бывает (когда для dword и word раные endian)? Какой наиболее правильный способ борьбы с этим? <{POST_SNAPBACK}> Если программа работает c данными только на одной платформе, то проблем меньше. Endian-о зависимые участки кода локализуются и переписываются для разных Endian-ов, далее под разные платформы выбираются (линкуются) разные варианты. :angry2: Другой момент - обмен данными между устройствами (процессорами), у которых разный endian. Частный случай - если данные как-либо сохраняются в одном типе, а считываются уже на платформе с другим типом. Проблемы возникают тоько при обмене и только если данные процессором беруться из канала обмена (или из файла) не по байтам, а бОльшими порциями. Одно из решений (не самое лучшее по скорости работы, но лучшее в смысле переносимости) - передавать и принимать данные побайтно. Т.е. если надо передать 2х байтное слово, то выделяем и передаём сначала старший байт, далее младший; на приёмной стороне обратный процесс - считываем один байт, другой, и из двух этих байтов формируем сдвигами нужное нам число. Переносимость стопроцентная. То же можно организовать при сохранении/считывании данных на/с долговременных носителей. Если же нужна скорость, то при передаче данных всё равно кто-то должен делать перекодировку endiana, и выбирается та сторона, которой можно потормозить больше. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
acex2 0 19 июля, 2005 Опубликовано 19 июля, 2005 · Жалоба Если же нужна скорость, то при передаче данных всё равно кто-то должен делать перекодировку endiana, и выбирается та сторона, которой можно потормозить больше. Иногда в таких случаях можно плату развести с учетом индианности, тогда и тормозить никого не придется ;) Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Eugeno 0 19 июля, 2005 Опубликовано 19 июля, 2005 · Жалоба Кстати, а с 32 битами приколов разной индианности не бывает (когда для dword и word раные endian)? <{POST_SNAPBACK}> Проверил, как TI компилирует сохранение long-a, который у них 40-битный, но, естественно, при обменен с памятью сохраняет-считывает в регистровую пару все 64 бита (8 байт). Так вот, в зависимости от установленного в опциях endian-a сохраняет по разному. Т.е. получается, что все восемь байт будут при этом идти по разному и при попытки обратится как к массиву из int-ов 32-битных для разного endiana получим разные результаты! :( Иногда в таких случаях можно плату развести с учетом индианности, тогда и тормозить никого не придется Это если сам разводишь плату (или влияешь на этот процесс). Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Hercules 0 20 июля, 2005 Опубликовано 20 июля, 2005 · Жалоба :angry2: Другой момент - обмен данными между устройствами (процессорами), у которых разный endian. Частный случай - если данные как-либо сохраняются в одном типе, а считываются уже на платформе с другим типом. Проблемы возникают тоько при обмене и только если данные процессором беруться из канала обмена (или из файла) не по байтам, а бОльшими порциями. Одно из решений (не самое лучшее по скорости работы, но лучшее в смысле переносимости) - передавать и принимать данные побайтно. Т.е. если надо передать 2х байтное слово, то выделяем и передаём сначала старший байт, далее младший; на приёмной стороне обратный процесс - считываем один байт, другой, и из двух этих байтов формируем сдвигами нужное нам число. Переносимость стопроцентная. То же можно организовать при сохранении/считывании данных на/с долговременных носителей. Если же нужна скорость, то при передаче данных всё равно кто-то должен делать перекодировку endiana, и выбирается та сторона, которой можно потормозить больше. <{POST_SNAPBACK}> Вообще-то, обычная практика при обмене между двумя устройствами (с разными или одинаковыми 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 */ Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Evgeny_CD 0 20 июля, 2005 Опубликовано 20 июля, 2005 · Жалоба Спасибо всем ответившим!!! Но у меня окончательно снесло башню . Пытаюсь разобраться. [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ов одинаковы???? Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Hercules 0 20 июля, 2005 Опубликовано 20 июля, 2005 · Жалоба Вопрос: когда говорят ARM LITTLE ENDIAN, ARM BIG ENDIAN - кака я из комбинаций имеется в виду? <{POST_SNAPBACK}> Может быть так будет понятней: Пусть у нас при 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-ти разрядный доступ) Они у всех ARMов одинаковы???? <{POST_SNAPBACK}> Все ARM-ы с одинаковым ENDIAN имеют один и тот же порядок следования байт в слове (если это имелось ввиду). Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Evgeny_CD 0 20 июля, 2005 Опубликовано 20 июля, 2005 · Жалоба Все ARM-ы с одинаковым ENDIAN имеют один и тот же порядок следования байт в слове (если это имелось ввиду). <{POST_SNAPBACK}> Спасибо за "альтернативный" вариант! Я, прежде всего, хотел выяснить, совпадает ли индианность для байтов внутри word и для word внутри dword. Судя по Вашим ответам - совпадает. А что, что я назвал CRAZY, это, вероятно, существует только в глюканутых бошках творцов компиляторов на 8 и 16 битные системы. :smile3046: Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться