|
|
  |
поменять местами биты в байте, простой вопрос |
|
|
|
Apr 26 2010, 06:58
|

Гуру
     
Группа: Свой
Сообщений: 13 372
Регистрация: 27-11-04
Из: Riga, Latvia
Пользователь №: 1 244

|
Цитата(Vny4ek @ Apr 26 2010, 07:33)  я проще себе это представлял, не знаю только как на языке реализовать: Все плохо, Вы, как оказалось, не только написать не можете, но и прочитать уже написанное  . Ибо все варианты с циклом в таком стиле и делают. Надо учить язык. Цитата(baralgin @ Apr 26 2010, 00:31)  Насчёт 0x01: не корректно. Потому что компилятор умудряется считать результат до исполнения  . Вообще-то причина не в этом, а том, что цикл будет прерван как только закончатся единичные биты в старшей части байта. Цитата оказывается что даже инструкции специальные для этого бывают  ). А когда не бывают, можно сопроцессор  поставить. Много лет назад, когда по ошибке разработчиков периферийного оборудования (несколько стативов) на CPU на шустром (аж целых 12MHz) 80286 сыпались 32 последовательных потока из развернутых байт, поставил в помощь к процессору 8bit регистр с выходами перекрестно запаралеленными на входы. Записал в него байт и считал развернутым.
--------------------
Feci, quod potui, faciant meliora potentes
|
|
|
|
|
Apr 26 2010, 07:56
|

Профессионал
    
Группа: Модераторы
Сообщений: 1 951
Регистрация: 27-08-04
Из: Санкт-Петербург
Пользователь №: 555

|
Для AVR все равно быстрее так Код uint8_t rsb(uint8_t a) { a = ((a & 0x55) << 1) | ((a & 0xAA) >> 1); a = ((a & 0xCC) >> 2) | ((a & 0x33) << 2); return __swap_nibbles(a); } 15 тактов. Даже если на асм написать развернутый цикл со сдвигом через перенос получится 16 тактов. Код 5 a = ((a & 0x55) << 1) | ((a & 0xAA) >> 1); \ 00000000 2F10 MOV R17,R16 \ 00000002 7515 ANDI R17,0x55 \ 00000004 0F11 LSL R17 \ 00000006 7A0A ANDI R16,0xAA \ 00000008 9506 LSR R16 \ 0000000A 2B01 OR R16,R17 6 a = ((a & 0xCC) >> 2) | ((a & 0x33) << 2); 7 return __swap_nibbles(a); \ 0000000C 2F10 MOV R17,R16 \ 0000000E 7C1C ANDI R17,0xCC \ 00000010 9516 LSR R17 \ 00000012 9516 LSR R17 \ 00000014 7303 ANDI R16,0x33 \ 00000016 0F00 LSL R16 \ 00000018 0F00 LSL R16 \ 0000001A 2B01 OR R16,R17 \ 0000001C 9502 SWAP R16 \ 0000001E 9508 RET
|
|
|
|
|
Apr 26 2010, 17:12
|
Частый гость
 
Группа: Участник
Сообщений: 145
Регистрация: 11-01-08
Пользователь №: 34 001

|
Цитата Все плохо, Вы, как оказалось, не только написать не можете, но и прочитать уже написанное sad.gif. Ибо все варианты с циклом в таком стиле и делают. Надо учить язык. да я с этим полностью согласен, вроде принцип реализации правильно изложил, а на практике написать не могу, если бы на русском ткнули в учебник где можно было понять, как извлечь бит из байта, как установить 0 или 1 в нужном месте байта был бы признателен. Инфы много, но то что читаю либо не содержит такие вещи либо уже идет слишком сложно и не могу просто понять.
|
|
|
|
|
Apr 26 2010, 19:45
|
Частый гость
 
Группа: Участник
Сообщений: 149
Регистрация: 2-06-08
Из: Москва
Пользователь №: 38 003

|
Цитата(Vny4ek @ Apr 26 2010, 21:12)  Инфы много, но то что читаю либо не содержит такие вещи либо уже идет слишком сложно и не могу просто понять. Да фиг с ними с учебниками, Вы тему-то свою с начала до конца внимательно перечитайте. Как перечитаете выберите один из предложенных вариантов, перечитайте его еще раз, попытайтесь понять, затем задайте вопросы, если что-то останется непонятным.
Сообщение отредактировал smac - Apr 26 2010, 19:46
|
|
|
|
|
Apr 26 2010, 19:55
|

I WANT TO BELIEVE
     
Группа: Свой
Сообщений: 2 617
Регистрация: 9-03-08
Пользователь №: 35 751

|
Vny4ek вот как-то так: установить бит в байте Код b |= 1 << bit_number; сбросить бит в ноль Код b &= ~(1 << bit_number); bit_number, естественно от 0 до 7, 15 или 31 или даже 63 в зависимости от типа переменных  *Для типов подлиннее(длиннее int) придётся указать явное приведение к нужному типу, иначе то, что в скобках - будет приводиться к int(в общем случае).
--------------------
The truth is out there...
|
|
|
|
|
Apr 26 2010, 20:59
|

неотягощённый злом
     
Группа: Свой
Сообщений: 2 746
Регистрация: 31-01-08
Из: Санкт-Петербург
Пользователь №: 34 643

|
Цитата(KRS @ Apr 26 2010, 11:56)  Даже если на асм написать развернутый цикл со сдвигом через перенос получится 16 тактов. Можно и так, но не менее 16 тактов... Код BLD R16,0 BST R17,7
BLD R16,1 BST R17,6
BLD R16,2 BST R17,5
BLD R16,3 BST R17,4
BLD R16,4 BST R17,3
BLD R16,5 BST R17,2
BLD R16,6 BST R17,1
BLD R16,7 BST R17,0 А ещё кто-то предлагал соединить два 8-ми битных порта перемычками крест-накрест и инвертировать за 2-3 такта: Код out PORTB, R16 nop in R17,PORTD
--------------------
“Будьте внимательны к своим мыслям - они начало поступков” (Лао-Цзы)
|
|
|
|
|
Apr 27 2010, 01:53
|
Профессионал
    
Группа: Участник
Сообщений: 1 273
Регистрация: 3-03-06
Пользователь №: 14 942

|
Цитата(KRS @ Apr 26 2010, 11:56)  Для AVR все равно быстрее так Код uint8_t rsb(uint8_t a) { a = ((a & 0x55) << 1) | ((a & 0xAA) >> 1); a = ((a & 0xCC) >> 2) | ((a & 0x33) << 2); return __swap_nibbles(a); } 15 тактов. Даже если на асм написать развернутый цикл со сдвигом через перенос получится 16 тактов. Код ... С первой половиной согласен — 6 тактов, вторая половина могла бы уложиться в 5 без лишних сдвигов. Итого 11 тактов против 15. Код uint8_t rsb(uint8_t a) { a = ((a & 0x55) << 1) | ((a & 0xAA) >> 1); return __swap_nibbles(a); a = ((a & 0x66) | (a & 0x99)); }
mov r17,r16 lsr r17 andi r17,0x55 lsr r16 andi r16,0xAA or r16,r17 mov r17,r16 swap r17 andi r17,0x66 andi r16,0x99 or r16,r17 (ret)
|
|
|
|
|
Apr 27 2010, 07:35
|

Гуру
     
Группа: Свой
Сообщений: 13 372
Регистрация: 27-11-04
Из: Riga, Latvia
Пользователь №: 1 244

|
Цитата(Vny4ek @ Apr 27 2010, 07:02)  sigmaN, спасибо большое. То что написали после вас вообще не понятно мне т.к. я на Си учусь писать. И уже не первый год http://electronix.ru/forum/index.php?showt...=57082&st=0 все о битах спрашиваете. Ну очень "эффективно" идет процесс  . Может, наконец-то возьмете в руки букварь? А то просто ничего кроме сказанного здесь http://electronix.ru/forum/index.php?showt...=55513&st=0 SasaVitebsk по поводу очередного Вашего "вопроса": Цитата Блин. Во что лень делает.... сказать уже не могу  .
--------------------
Feci, quod potui, faciant meliora potentes
|
|
|
|
|
Apr 27 2010, 09:06
|

Беспросветный оптимист
     
Группа: Свой
Сообщений: 4 640
Регистрация: 26-12-07
Из: Н.Новгород
Пользователь №: 33 646

|
Цитата(demiurg_spb @ Apr 27 2010, 00:59)  А ещё кто-то предлагал соединить два 8-ми битных порта перемычками крест-накрест и инвертировать за 2-3 такта: Код out PORTB, R16 nop in R17,PORTD Я вот не помню, AVR умеет свопить полубайты? Тогда можно одним портом обойтись с чуть большим количеством тактов
--------------------
Программирование делится на системное и бессистемное. ©Моё :) — а для кого-то БГ — это Bill Gilbert =)
|
|
|
|
|
Apr 27 2010, 20:58
|
дятел
    
Группа: Свой
Сообщений: 1 681
Регистрация: 13-05-06
Из: Питер
Пользователь №: 17 065

|
Цитата(x736C @ Apr 27 2010, 05:53)  С первой половиной согласен — 6 тактов, вторая половина могла бы уложиться в 5 без лишних сдвигов. Итого 11 тактов против 15. Код uint8_t rsb(uint8_t a) { a = ((a & 0x55) << 1) | ((a & 0xAA) >> 1); return __swap_nibbles(a); a = ((a & 0x66) | (a & 0x99)); }
mov r17,r16 lsr r17 andi r17,0x55 lsr r16 andi r16,0xAA or r16,r17 mov r17,r16 swap r17 andi r17,0x66 andi r16,0x99 or r16,r17 (ret) у Вас какая-то полная фигня в асм тексте(и в С тоже) после lsr r17 и lsr r16 и неиспользования в дальнейшем флага С Вы младший бит ужо потеряли короче, меньше 13 тактов и не надейтесь получить  эта я Вам как "крупный специалист по перекладыванию битиков" гарантирую...
|
|
|
|
|
  |
1 чел. читают эту тему (гостей: 1, скрытых пользователей: 0)
Пользователей: 0
|
|
|