Перестановка бит

Тема в разделе "WASM.ASSEMBLER", создана пользователем sarin, 2 май 2018.

Метки:
  1. sarin

    sarin New Member

    Публикаций:
    0
    Регистрация:
    2 июн 2005
    Сообщения:
    28
    Имеем 32-битное значение abcdabcd abcdabcd abcdabcd abcdabcd,
    где a,b,c,d = биты 0 или 1.
    Нужно преобразовать в aaaaaaaa bbbbbbbb cccccccc dddddddd.
    Интересуют варианты для 32- и 16-битного кода.
    Делалость это поочередным сдвигом - RCR/RCL с использованием разных регистров.
    Каки есть ещё варианты? Как это можно сделать наиболее быстро?
     
  2. Indy_

    Indy_ Well-Known Member

    Публикаций:
    4
    Регистрация:
    29 апр 2011
    Сообщения:
    1.826
    sarin,

    Таблицей зашить, эффективнее варианта нет.
     
  3. acckiitvar

    acckiitvar Member

    Публикаций:
    0
    Регистрация:
    26 сен 2011
    Сообщения:
    68
    Если я вас правильно понял, то есть некий паттерн из 4 бит повторный восемь раз? Тогда взять его и заполнить по нему регистр.
     
  4. SadKo

    SadKo Владимир Садовников

    Публикаций:
    8
    Регистрация:
    4 июн 2007
    Сообщения:
    1.345
    Адрес:
    г. Санкт-Петербург
    Не, человек, как понимаю, имеет в виду упакованые биты.
    a0 b0 c0 d0 a1 b1 c1 d1 a2 b2 c2 d2 a3 b3 c3 d3 a4 b4 c4 d4 a5 b5 c5 d5 a6 b6 c6 d6 a7 b7 c7 d7

    Путь это хранится здесь:
    uint32_t x;

    Делаем раз: x = (x & 0xa5a5a5a5) | ((x & 0x0a0a0a0a) << 3) | ((x & 0x50505050) >> 3);

    Получаем: a0 a1 c0 c1 b0 b1 d0 d1 a2 a3 c2 c3 b2 b3 d2 d3 a4 a5 c4 c5 b4 b5 d4 d5 a6 a7 c6 c7 b6 b7 d6 d7

    Делаем два: x = (x & 0xcc33cc33) | ((x & 0x33003300) >> 4) | ((x & 0x00cc00cc) << 4);

    Получаем: a0 a1 a2 a3 b0 b1 b2 b3 c0 c1 c2 c3 d0 d1 d2 d3 a4 a5 a6 a7 b4 b5 b6 b7 c4 c5 c6 c7 d4 d5 d6 d7

    Делаем три: x = (x & 0xf0f00f0f) | ((x & 0x0f0f0000) >> 8) | ((x & 0x0000f0f0) << 8);

    Получаем: a0 a1 a2 a3 a4 a5 a6 a7 c0 c1 c2 c3 c4 c5 c6 c7 b0 b1 b2 b3 b4 b5 b6 b7 d0 d1 d2 d3 d4 d5 d6 d7

    Ну и последний шаг: x = (x & 0xff0000ff) | ((x & 0x00ff0000) >> 8) | ((x & 0x0000ff00) << 8);

    Получаем: a0 a1 a2 a3 a4 a5 a6 a7 b0 b1 b2 b3 b4 b5 b6 b7 c0 c1 c2 c3 c4 c5 c6 c7 d0 d1 d2 d3 d4 d5 d6 d7

    Должно быть всё ОК, если где-то с масками не налажал.
     
    acckiitvar и Mikl___ нравится это.