|
|
  |
Поменять местами биты в байте. |
|
|
|
May 10 2007, 20:36
|

Шаман
     
Группа: Модераторы
Сообщений: 3 064
Регистрация: 30-06-04
Из: Киев, Украина
Пользователь №: 221

|
Цитата(Serg76 @ May 9 2007, 17:44)  Прошу прощения, но по-моему сильно мудрЕно и, как мне кажется, неверно. Смотрите:
при взаимных сдвижках - (xxx>>1)|(xxx<<1) без предварительного выделения нужных бит X и Y с помощью маскирования (xxx&0x80), (xxx&0x40) и последующего сложения ИЛИ непременно возникнет ошибка (Y | b = ????????). Попробуем проследить ход операций: 1. Сдвижка xxx на бит вправо даст 00 bXY0 0000; 2. Сдвижка xxx на бит влево даст bX Y000 0000; 3. После ИЛИ непонятно вообще что получится.
А далее я что-то тоже не понял: ...&xxx&0xBF)^0b01000000;
Если бы мы имели дело с регистром вида 00XY000000, то проканал бы и вариант zltigo, а так у нас имеется еще бит 'b', который как я понимаю может принимать любое значение. Поэтому мой вариант является универсальным, даже если на всех остальных позициях, кроме XY, будут биты с различными значениями. Комментарий в стиле клетчатого. Что ни предложение, то шедевр! Я плакалъ.
|
|
|
|
|
May 11 2007, 00:34
|

Местный
  
Группа: Свой
Сообщений: 208
Регистрация: 6-07-04
Из: Полтава
Пользователь №: 279

|
Цитата(Visor @ May 10 2007, 16:07)  Есть такой флаг "Т", вот через него можно легко гонять биты регистров, с помощью команд BST и BLD. Но это асм, который не все жалуют.  На ассемблере получается очень просто с использованием временного регистра и флага Т: ... ld temp, x bst temp, 6 bld x, 7 bst temp, 7 bld x, 6 ... Пробовал получить такую же последовательность команд при помощи IAR-C. Хотя IAR-C в самом принципе флаг Т использует, но как только ни пытался шаманить, так и не смог выдавить такую компактную последовательность.
|
|
|
|
|
May 11 2007, 02:04
|
Участник
  
Группа: Свой
Сообщений: 462
Регистрация: 2-04-07
Из: Иркутск
Пользователь №: 26 695

|
Цитата(ps1x @ May 9 2007, 18:43)  Допустим есть 0bXY000000. Как сделать 0bYX000000? ... асм, три инструкции: bst temp, 7 lsl temp bld temp, 6 в С не силён, но попробую :) temp=(temp<<1)|(0x40 & (temp>=128))
|
|
|
|
|
May 11 2007, 14:47
|

Местный
  
Группа: Свой
Сообщений: 208
Регистрация: 6-07-04
Из: Полтава
Пользователь №: 279

|
Цитата(ae_ @ May 11 2007, 05:04)  асм, три инструкции: bst temp, 7 lsl temp bld temp, 6 Поганятся остальные биты. Цитата(ae_ @ May 11 2007, 05:04)  в С не силён, но попробую  temp=(temp<<1)|(0x40 & (temp>=128)) Не годится, потому что это - только лишь логический сдвиг влево.
|
|
|
|
|
May 11 2007, 15:27
|
дятел
    
Группа: Свой
Сообщений: 1 681
Регистрация: 13-05-06
Из: Питер
Пользователь №: 17 065

|
Цитата(kv_addr @ May 11 2007, 04:34)  На ассемблере получается очень просто с использованием временного регистра и флага Т: ... ld temp, x bst temp, 6 bld x, 7 bst temp, 7 bld x, 6 ... Пробовал получить такую же последовательность команд при помощи IAR-C. Хотя IAR-C в самом принципе флаг Т использует, но как только ни пытался шаманить, так и не смог выдавить такую компактную последовательность.  Длинновато... , да и лишний регистр используем  Код ; 4 words / 4 cycles; ; Input: tmp= abcdefgh reversbits78: bst tmp,7 ; T=a lsl tmp ; tmp= bcdefgh0 asr tmp ; tmp= bbcdefgh bld tmp,6 ; tmp= bacdefgh
|
|
|
|
|
May 11 2007, 15:50
|

Местный
  
Группа: Свой
Сообщений: 208
Регистрация: 6-07-04
Из: Полтава
Пользователь №: 279

|
Цитата(singlskv @ May 11 2007, 18:27)  Длинновато... , да и лишний регистр используем  Дык, не спорю.  Правда мой вариант более универсален. Можно применить к любым битам. Цитата(singlskv @ May 11 2007, 18:27)  Код ; 4 words / 4 cycles; ; Input: tmp= abcdefgh reversbits78: bst tmp,7 ; T=a lsl tmp; tmp= bcdefgh0 asr tmp; tmp= bbcdefgh bld tmp,6 ; tmp= bacdefgh Пытался вышаманить из IAR-C, а там, как на мой взгляд, с asr ещё более проблематично, чем с флагом Т.
|
|
|
|
|
May 11 2007, 16:39
|
дятел
    
Группа: Свой
Сообщений: 1 681
Регистрация: 13-05-06
Из: Питер
Пользователь №: 17 065

|
Цитата(kv_addr @ May 11 2007, 19:50)  Пытался вышаманить из IAR-C, а там, как на мой взгляд, с asr ещё более проблематично, чем с флагом Т.  Дык с ASR как раз просто, вот код на С: Код volatile unsigned char x=0b10101010; volatile unsigned char y;
int main() { char tmp=x; tmp >>=1; y=tmp;
while (1); return tmp; } А вот результат компиляции: Код 7: char tmp=x; +00000032: 91800060 LDS R24,0x0060 Load direct from data space 8: tmp >>=1; +00000034: 9585 ASR R24 Arithmetic shift right 9: y=tmp; +00000035: 93800062 STS 0x0062,R24 Store direct to data space правда на Gcc, но я думаю на IAR будет аналогично (лень проверять) А вот с флагом T непонятно...
|
|
|
|
|
May 11 2007, 20:13
|

Местный
  
Группа: Свой
Сообщений: 208
Регистрация: 6-07-04
Из: Полтава
Пользователь №: 279

|
Цитата(singlskv @ May 11 2007, 19:39)  Дык с ASR как раз просто, вот код на С: Код volatile unsigned char x=0b10101010; volatile unsigned char y;
int main() { char tmp=x; tmp >>=1; y=tmp;
while (1); return tmp; } А вот результат компиляции: Код 7: char tmp=x; +00000032: 91800060 LDS R24,0x0060 Load direct from data space 8: tmp >>=1; +00000034: 9585 ASR R24 Arithmetic shift right 9: y=tmp; +00000035: 93800062 STS 0x0062,R24 Store direct to data space правда на Gcc, но я думаю на IAR будет аналогично (лень проверять) IAR-C дает следующий результат: Код ... LDI R30, `x` LDI R31, 0 LD R16, Z LSR R16 STD Z+1, R16 ... Как видите, результат зависит от выбранного компилятора.
|
|
|
|
|
May 11 2007, 21:05
|
дятел
    
Группа: Свой
Сообщений: 1 681
Регистрация: 13-05-06
Из: Питер
Пользователь №: 17 065

|
Цитата(kv_addr @ May 12 2007, 00:13)  IAR-C дает следующий результат: Код ... LDI R30, `x` LDI R31, 0 LD R16, Z LSR R16 STD Z+1, R16 ... Как видите, результат зависит от выбранного компилятора. А у Вас случайно не стоит опция воспринимать char как unsigned char ? Цитата(singlskv @ May 12 2007, 00:20)  А у Вас случайно не стоит опция воспринимать char как unsigned char ? Отвечу сам... У Вас таки стоит опция char как unsigned char  Вы так меня заинтриговали, что я даже не поленился включить второй копм на котором есть IAR и таки проверить соблюдает ли IAR стандарт С (ну хотябы пусть и не по умолчанию), оказалось соблюдает  : Код 6: char tmp=x; +00000016: EAE0 LDI R30,0xA0 Load immediate +00000017: E0F0 LDI R31,0x00 Load immediate +00000018: 8100 LDD R16,Z+0 Load indirect with displacement 8: y=tmp; +00000019: 9505 ASR R16 Arithmetic shift right +0000001A: 8301 STD Z+1,R16 Store indirect with displacement
|
|
|
|
|
May 11 2007, 21:07
|

Местный
  
Группа: Свой
Сообщений: 208
Регистрация: 6-07-04
Из: Полтава
Пользователь №: 279

|
Цитата(singlskv @ May 11 2007, 23:20)  А у Вас случайно не стоит опция воспринимать char как unsigned char ? Проверил, стояло дефолтное "Plain 'char' is Unsigned", поменял на "Signed", получилось следующее: Код ... LDI R30, `x` LDI R31, 0 LD R16, Z ASR R16 STD Z+1, R16 ... Ну, с asr вроде как разобрались. А вот с флагом Т пока не совсем понятно. Заметил, что компилятор его использует при проверках битов и при установках либо снятиях битов в регистрах, а вот чтобы флаг Т был установлен по биту из регистра и потом любой бит этого или иного регистра был установлен по этому флагу, такого не вышаманил.
|
|
|
|
|
May 11 2007, 21:22
|
дятел
    
Группа: Свой
Сообщений: 1 681
Регистрация: 13-05-06
Из: Питер
Пользователь №: 17 065

|
Цитата(kv_addr @ May 12 2007, 01:07)  Проверил, стояло дефолтное "Plain 'char' is Unsigned", поменял на "Signed", получилось следующее: Код ... LDI R30, `x` LDI R31, 0 LD R16, Z ASR R16 STD Z+1, R16 ... Ну, с asr вроде как разобрались. А вот с флагом Т пока не совсем понятно. Заметил, что компилятор его использует при проверках битов и при установках либо снятиях битов в регистрах, а вот чтобы флаг Т был установлен по биту из регистра и потом любой бит этого или иного регистра был установлен по этому флагу, такого не вышаманил. А вот с флагом T компиляторонезависимого решения точно не получится  Флаг T это такая фича AVR, и каждый компилятор может ей пользоватся/не пользоваться на свое усмотрение и с С он никак не связан То есть нашаманить наверное чего-то и можно, но это будет "странное" решение
|
|
|
|
|
May 11 2007, 22:35
|

Местный
  
Группа: Свой
Сообщений: 208
Регистрация: 6-07-04
Из: Полтава
Пользователь №: 279

|
Цитата(singlskv @ May 12 2007, 00:22)  А вот с флагом T компиляторонезависимого решения точно не получится  Флаг T это такая фича AVR, и каждый компилятор может ей пользоватся/не пользоваться на свое усмотрение и с С он никак не связан Хотел бы заметить, что в данном случае я не пытался получить какой-либо совместимости. Меня интересовало поведение конкретного компилятора с максимальным уровнем оптимизации. Т.е., в какой степени он может воспользоваться ресурсами контроллера, а именно - AVR, в пределе. Наверно согласитесь, что Embedded C все же вещь достаточно специфическая и должна иметь возможность по максимуму использовать возможности конкретно взятого контроллера. Иначе эффективное кодирование может быть не реализованым. Это для ПиСи можна писать "гектарные" программы, не сильно заботясь о "выжимании воды", а микроконтроллер - это такой себе "ночной горшок с ручкой вовнутрь" - чтобы места меньше занимал.  Ведь и переносимость программ, написанных на том же самом С, в определенной степени условна даже внутри семейства, не говоря о разных семействах. Цитата(singlskv @ May 12 2007, 00:22)  То есть нашаманить наверное чего-то и можно, но это будет "странное" решение Предпочел бы использовать термин - "трюковое".
|
|
|
|
|
  |
1 чел. читают эту тему (гостей: 1, скрытых пользователей: 0)
Пользователей: 0
|
|
|