Перейти к содержанию
    

поменять местами биты в байте

я проще себе это представлял, не знаю только как на языке реализовать:

Все плохо, Вы, как оказалось, не только написать не можете, но и прочитать уже написанное :(. Ибо все варианты с циклом в таком стиле и делают.

Надо учить язык.

 

 

Насчёт 0x01: не корректно. Потому что компилятор умудряется считать результат до исполнения :) .

Вообще-то причина не в этом, а том, что цикл будет прерван как только закончатся единичные биты в старшей части байта.

оказывается что даже инструкции специальные для этого бывают :) ).

А когда не бывают, можно сопроцессор :) поставить. Много лет назад, когда по ошибке разработчиков периферийного оборудования (несколько стативов) на CPU на шустром (аж целых 12MHz) 80286 сыпались 32 последовательных потока из развернутых байт, поставил в помощь к процессору 8bit регистр с выходами перекрестно запаралеленными на входы. Записал в него байт и считал развернутым.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Для 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

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Для AVR все равно быстрее так

А что, кто-то для общего случая разворота битов, возражал?

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Все плохо, Вы, как оказалось, не только написать не можете, но и прочитать уже написанное sad.gif. Ибо все варианты с циклом в таком стиле и делают.

Надо учить язык.

да я с этим полностью согласен, вроде принцип реализации правильно изложил, а на практике написать не могу, если бы на русском ткнули в учебник где можно было понять, как извлечь бит из байта, как установить 0 или 1 в нужном месте байта был бы признателен. Инфы много, но то что читаю либо не содержит такие вещи либо уже идет слишком сложно и не могу просто понять.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Инфы много, но то что читаю либо не содержит такие вещи либо уже идет слишком сложно и не могу просто понять.

Да фиг с ними с учебниками, Вы тему-то свою с начала до конца внимательно перечитайте. Как перечитаете выберите один из предложенных вариантов, перечитайте его еще раз, попытайтесь понять, затем задайте вопросы, если что-то останется непонятным.

Изменено пользователем smac

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Vny4ek вот как-то так:

установить бит в байте

b |= 1 << bit_number;

сбросить бит в ноль

b &= ~(1 << bit_number);

bit_number, естественно от 0 до 7, 15 или 31 или даже 63 в зависимости от типа переменных :)

*Для типов подлиннее(длиннее int) придётся указать явное приведение к нужному типу, иначе то, что в скобках - будет приводиться к int(в общем случае).

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Даже если на асм написать развернутый цикл со сдвигом через перенос получится 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

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Для 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)

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

sigmaN, спасибо большое. То что написали после вас вообще не понятно мне т.к. я на Си учусь писать.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Я по простому сделал (как и сказали, при помощи таблицы):

http://forum.vingrad.ru/index.php?showtopi...t&p=2081873

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

sigmaN, спасибо большое. То что написали после вас вообще не понятно мне т.к. я на Си учусь писать.

И уже не первый год http://electronix.ru/forum/index.php?showt...=57082&st=0 все о битах спрашиваете. Ну очень "эффективно" идет процесс :(. Может, наконец-то возьмете в руки букварь? А то просто ничего кроме

сказанного здесь http://electronix.ru/forum/index.php?showt...=55513&st=0 SasaVitebsk по поводу очередного Вашего "вопроса":

Блин. Во что лень делает....

сказать уже не могу :(.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

А ещё кто-то предлагал соединить два 8-ми битных порта перемычками крест-накрест и инвертировать за 2-3 такта:

out PORTB, R16
nop
in R17,PORTD

Я вот не помню, AVR умеет свопить полубайты?

Тогда можно одним портом обойтись с чуть большим количеством тактов

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

С первой половиной согласен — 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 тактов и не надейтесь получить :)

эта я Вам как "крупный специалист по перекладыванию битиков" гарантирую... :)

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Блин крутые специалисты, вы проблему решаете или пиписьками меряетесь? Я указал конкретное решение трабла. Без всяких ассемблеров и всякой пурги (см. проблемы с переносимостью). Взял, скопипастил и пользуешься...

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Присоединяйтесь к обсуждению

Вы можете написать сейчас и зарегистрироваться позже. Если у вас есть аккаунт, авторизуйтесь, чтобы опубликовать от имени своего аккаунта.

Гость
Ответить в этой теме...

×   Вставлено с форматированием.   Вставить как обычный текст

  Разрешено использовать не более 75 эмодзи.

×   Ваша ссылка была автоматически встроена.   Отображать как обычную ссылку

×   Ваш предыдущий контент был восстановлен.   Очистить редактор

×   Вы не можете вставлять изображения напрямую. Загружайте или вставляйте изображения по ссылке.

×
×
  • Создать...