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

 
 
> Поменять местами биты в байте.
ps1x
сообщение May 9 2007, 09:43
Сообщение #1


Местный
***

Группа: Свой
Сообщений: 300
Регистрация: 15-03-06
Из: Москва
Пользователь №: 15 284



Допустим есть

0bXY000000.

Как сделать

0bYX000000?

Надо использовать битовые маски и логические операции, только вот с масками никак не разберусь...

И еще, есть ли в CVAVR функция, возвращающая № буквы, т.е. типа chr("a")=35 ?

С уважением.
Go to the top of the page
 
+Quote Post
 
Start new topic
Ответов
Visor
сообщение May 10 2007, 13:07
Сообщение #2


Местный
***

Группа: Свой
Сообщений: 240
Регистрация: 23-03-07
Пользователь №: 26 428



Есть такой флаг "Т", вот через него можно легко гонять биты регистров, с помощью команд BST и BLD. Но это асм, который не все жалуют. cool.gif
Go to the top of the page
 
+Quote Post
kv_addr
сообщение May 11 2007, 00:34
Сообщение #3


Местный
***

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



Цитата(Visor @ May 10 2007, 16:07) *
Есть такой флаг "Т", вот через него можно легко гонять биты регистров, с помощью команд BST и BLD. Но это асм, который не все жалуют. cool.gif

На ассемблере получается очень просто с использованием временного регистра и флага Т:
...
ld temp, x
bst temp, 6
bld x, 7
bst temp, 7
bld x, 6
...
Пробовал получить такую же последовательность команд при помощи IAR-C. Хотя IAR-C в самом принципе флаг Т использует, но как только ни пытался шаманить, так и не смог выдавить такую компактную последовательность. sad.gif
Go to the top of the page
 
+Quote Post
singlskv
сообщение May 11 2007, 15:27
Сообщение #4


дятел
*****

Группа: Свой
Сообщений: 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 в самом принципе флаг Т использует, но как только ни пытался шаманить, так и не смог выдавить такую компактную последовательность. sad.gif

Длинновато... , да и лишний регистр используем smile.gif
Код
;  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
Go to the top of the page
 
+Quote Post
kv_addr
сообщение May 11 2007, 15:50
Сообщение #5


Местный
***

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



Цитата(singlskv @ May 11 2007, 18:27) *
Длинновато... , да и лишний регистр используем smile.gif

Дык, не спорю. smile.gif
Правда мой вариант более универсален. Можно применить к любым битам.

Цитата(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 ещё более проблематично, чем с флагом Т. 05.gif
Go to the top of the page
 
+Quote Post
singlskv
сообщение May 11 2007, 16:39
Сообщение #6


дятел
*****

Группа: Свой
Сообщений: 1 681
Регистрация: 13-05-06
Из: Питер
Пользователь №: 17 065



Цитата(kv_addr @ May 11 2007, 19:50) *
Пытался вышаманить из IAR-C, а там, как на мой взгляд, с asr ещё более проблематично, чем с флагом Т. 05.gif

Дык с 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 непонятно...
Go to the top of the page
 
+Quote Post
kv_addr
сообщение May 11 2007, 20:13
Сообщение #7


Местный
***

Группа: Свой
Сообщений: 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
...

Как видите, результат зависит от выбранного компилятора.
Go to the top of the page
 
+Quote Post
singlskv
сообщение May 11 2007, 21:05
Сообщение #8


дятел
*****

Группа: Свой
Сообщений: 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 smile.gif

Вы так меня заинтриговали, что я даже не поленился включить второй копм
на котором есть IAR и таки проверить соблюдает ли IAR стандарт С (ну хотябы пусть и не
по умолчанию), оказалось соблюдает smile.gif :
Код
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
Go to the top of the page
 
+Quote Post
kv_addr
сообщение May 11 2007, 21:07
Сообщение #9


Местный
***

Группа: Свой
Сообщений: 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 вроде как разобрались. А вот с флагом Т пока не совсем понятно. Заметил, что компилятор его использует при проверках битов и при установках либо снятиях битов в регистрах, а вот чтобы флаг Т был установлен по биту из регистра и потом любой бит этого или иного регистра был установлен по этому флагу, такого не вышаманил.
Go to the top of the page
 
+Quote Post
singlskv
сообщение May 11 2007, 21:22
Сообщение #10


дятел
*****

Группа: Свой
Сообщений: 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 компиляторонезависимого решения точно не получится sad.gif
Флаг T это такая фича AVR, и каждый компилятор может ей пользоватся/не пользоваться
на свое усмотрение и с С он никак не связан

То есть нашаманить наверное чего-то и можно, но это будет "странное" решение
Go to the top of the page
 
+Quote Post
Александр Куличо...
сообщение May 12 2007, 15:33
Сообщение #11


Местный
***

Группа: Свой
Сообщений: 256
Регистрация: 6-03-06
Из: Украина, г. Винница
Пользователь №: 15 017



Цитата(singlskv @ May 12 2007, 00:22) *
А вот с флагом T компиляторонезависимого решения точно не получится sad.gif
Флаг T это такая фича AVR, и каждый компилятор может ей пользоватся/не пользоваться
на свое усмотрение и с С он никак не связан

То есть нашаманить наверное чего-то и можно, но это будет "странное" решение


Ничего странного, если использовать в IAR битовые поля:
Код
union ByteBit {  
      signed char Byte;                
      unsigned char UByte;                
      struct {                        
         unsigned char Bit0:1,
                       Bit1:1,
                       Bit2:1,
                       Bit3:1,
                       Bit4:1,
                       Bit5:1,
                       Bit6:1,
                       Bit7:1;
              };
      };

union ByteBit s;


void main( void )
{  
   union ByteBit ss,tt;

   ss = tt = s;        
   ss.Bit3 = ss.Bit4;
   ss.Bit4 = tt.Bit3;  
   s = ss;
}


дает такой результат при среднем уровне оптимизации:
Код
    24             ss = tt = s;        
   \   00000000   9100....           LDS     R16, s
   \   00000004   2F10               MOV     R17, R16
     25             ss.Bit3 = ss.Bit4;
     26             ss.Bit4 = tt.Bit3;  
   \   00000006   2F21               MOV     R18, R17
   \   00000008   FB24               BST     R18, 4
   \   0000000A   F913               BLD     R17, 3
   \   0000000C   FB23               BST     R18, 3
   \   0000000E   F914               BLD     R17, 4
     27             s = ss;
   \   00000010   9310....           STS     s, R17


Правда, IAR странно читает 7-й бит в флаг Т - через флаг С перемещает его в 0-й бит регистра(при этом обнуляя сам регистр) и уже потом делает bst Rxx,0. Если в вышеприведенном примере менять местами не 3 и 4-й биты, а 6 с 7-м, то результат получается следующий:
Код
//   24    ss = tt = s;        
        LDS    R16, s
        MOV    R17, R16
//   25    ss.Bit7 = ss.Bit6;
//   26    ss.Bit6 = tt.Bit7;  
        MOV    R18, R17
        BST    R18, 6
        BLD    R17, 7
        LSL    R18
        LDI    R18, 0
        ROL    R18
        BST    R18, 0
        BLD    R17, 6
//   27    s = ss;
        STS    s, R17
Go to the top of the page
 
+Quote Post
singlskv
сообщение May 12 2007, 21:12
Сообщение #12


дятел
*****

Группа: Свой
Сообщений: 1 681
Регистрация: 13-05-06
Из: Питер
Пользователь №: 17 065



Цитата(Александр Куличок @ May 12 2007, 19:33) *
Ничего странного, если использовать в IAR битовые поля:
.............
Правда, IAR странно читает 7-й бит в флаг Т - через флаг С перемещает его в 0-й бит регистра(при этом обнуляя сам регистр) и уже потом делает bst Rxx,0. Если в вышеприведенном примере менять местами не 3 и 4-й биты, а 6 с 7-м, то результат получается следующий:
...............

Все правильно, в варианте с битом 7, компилятор поступает правильно,
тк значение tt.Bit7 есть не что иное как unsigned char (0 или 1, то есть полный байт),
и если далее в коде будет работа с этим битом через обращение tt.Bit7, то он
будет пользоваться значением временной регистровой переменной в которой хранится 0 или 1.
А в варианте с битами 3 и 4 оптимизатор понял что дальше обращения к этим битам не будет
и смог соптимизировать это на конструкцию bst/bld

Вы спросите почему он не проделал тоже самое с битами 6 и 7 ?
Так собственно по тому, что (8бит) это не только unsigned char(byte) но еще и просто
char, для которого правила арифметики чуть-чуть отличаются...(старший бит может быть знаком)

Да, и еще, в Вашем варианте для перестановки битов получилось использование
двух временных регистров, что не есть гуд...
то есть в тестовом варианте это конечно выглядит неплохо, но в реальной задачке,
когда другие регистры тоже чем то заняты, это будет приводить к
дополнительным(нежелательным) операциям сохранения регистров или в младших
регистрах или в памяти/стеке.

Ну и в конечном итоге, нужно понимать/помнить что все эти варианты
оптимизации(и мои в том числе) в достаточной степени компиляторозависимы,
то есть пишем код на С, компилим, если непонравилось, начинаем сначала,
и так неколько итераций...
Go to the top of the page
 
+Quote Post

Сообщений в этой теме
- ps1x   Поменять местами биты в байте.   May 9 2007, 09:43
- - zltigo   Цитата(ps1x @ May 9 2007, 12:43) Допустим...   May 9 2007, 10:22
|- - ps1x   Цитата(zltigo @ May 9 2007, 13:22) xxx = ...   May 9 2007, 10:36
||- - zltigo   Цитата(ps1x @ May 9 2007, 13:36) да нет, ...   May 9 2007, 10:46
||- - haker_fox   Цитата(ps1x @ May 9 2007, 18:36) да нет, ...   May 9 2007, 11:47
||- - ps1x   Цитата(haker_fox @ May 9 2007, 14:47) А к...   May 9 2007, 12:16
||- - haker_fox   Цитата(ps1x @ May 9 2007, 21:16) У меня е...   May 11 2007, 02:41
|- - Serg76   Цитата(zltigo @ May 9 2007, 13:22) xxx = ...   May 9 2007, 12:23
|- - ps1x   Цитата(Serg76 @ May 9 2007, 15:23) Как мн...   May 9 2007, 13:24
|- - Serg76   Цитата(ps1x @ May 9 2007, 16:24) Я это сд...   May 9 2007, 14:44
|- - zltigo   Цитата(Serg76 @ May 9 2007, 17:44) ....то...   May 9 2007, 15:16
|- - Edmundo   Цитата(Serg76 @ May 9 2007, 18:44) 1. Сдв...   May 9 2007, 15:30
|- - IgorKossak   Цитата(Serg76 @ May 9 2007, 17:44) Прошу ...   May 10 2007, 20:36
- - Laksus   Цитата(Serg76 @ May 9 2007, 14:23) Как мн...   May 9 2007, 15:00
- - xemul   Тупое решение в лоб Кодt = x; x &= 0x3f; if...   May 9 2007, 15:27
|- - kv_addr   Цитата(singlskv @ May 12 2007, 00:22) А в...   May 11 2007, 22:35
- - Punk   Цитата(ps1x @ May 9 2007, 12:43) Допустим...   May 10 2007, 14:06
|- - Dog Pawlowa   Два порта контроллера закольцевать еще не предлага...   May 10 2007, 14:20
- - ae_   Цитата(ps1x @ May 9 2007, 18:43) Допустим...   May 11 2007, 02:04
|- - kv_addr   Цитата(ae_ @ May 11 2007, 05:04) асм, три...   May 11 2007, 14:47
- - defunct   ЦитатаВедь и переносимость программ, написанных на...   May 12 2007, 00:15
|- - kv_addr   Цитата(defunct @ May 12 2007, 03:15) Позв...   May 12 2007, 02:01
|- - defunct   Цитата(kv_addr @ May 12 2007, 04:01) Но 1...   May 12 2007, 02:42
|- - kv_addr   Цитата(defunct @ May 12 2007, 05:42) Прот...   May 12 2007, 04:01
|- - defunct   Цитата(kv_addr @ May 12 2007, 06:01) IMHO...   May 12 2007, 12:16
- - singlskv   Видимо самый быстрый вариант на С будет таким: Код...   May 12 2007, 12:05
- - sensor_ua   Цитатапрограммная реализация encoder'a/decoder...   May 12 2007, 15:09
|- - kv_addr   Цитата(sensor_ua @ May 12 2007, 18:09) Ду...   May 12 2007, 23:08
- - Александр Куличок   ЦитатаВсе правильно, в варианте с битом 7, компиля...   May 13 2007, 07:05


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

 


RSS Текстовая версия Сейчас: 12th August 2025 - 18:35
Рейтинг@Mail.ru


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