Алгоритм заполнения 8-битного массива 7-битными значениями

Тема в разделе "WASM.BEGINNERS", создана пользователем Xerx, 7 фев 2007.

  1. Xerx

    Xerx Алексей

    Публикаций:
    0
    Регистрация:
    17 фев 2005
    Сообщения:
    528
    Адрес:
    Russia
    Собственно, предложите эффективный алгоритм по subj. (оптимизация по скорости выполнения) для i80386 (можно выше ;) ).
    Если не совсем корректно высказался, то объясняю подробнее:
    Есть массив байт. Его общая длина (в битах) кратна 7. Нужно последовательно заполнить его 7-битными значениями. Все дело в последнем бите каждого байта, которого приходится "забирать" из каждого следующего добавляемого 7-битного байта.
     
  2. HoBleen

    HoBleen New Member

    Публикаций:
    0
    Регистрация:
    15 янв 2007
    Сообщения:
    77
    Забей сначала массив из 7 байт, а потом копируй из него через регистры - как раз 7 штук =)
     
  3. EvilsInterrupt

    EvilsInterrupt Постигающий азы дзена

    Публикаций:
    0
    Регистрация:
    28 окт 2003
    Сообщения:
    2.428
    Адрес:
    Russia
    Ничего не понял :dntknw:
     
  4. Kirillxskynet

    Kirillxskynet New Member

    Публикаций:
    0
    Регистрация:
    11 окт 2006
    Сообщения:
    30
    Вот это место еще раз и по-подробней.
     
  5. HoBleen

    HoBleen New Member

    Публикаций:
    0
    Регистрация:
    15 янв 2007
    Сообщения:
    77
    Ну просто проблемма в том, что любой байт будет состоять из двух частей (ну или экземпляров) этих 7 бит. Можно еще поиграться с флагом переноса.
     
  6. det

    det New Member

    Публикаций:
    0
    Регистрация:
    31 янв 2007
    Сообщения:
    31
    Xerx
    ты не чего не путаешь, смысл бегимота в холодильник засовывать..
     
  7. vdk

    vdk New Member

    Публикаций:
    0
    Регистрация:
    18 дек 2003
    Сообщения:
    18
    Код (Text):
    1. char m[] = "ASCII";
    2. unsigned l = strlen(m);
    3. unsigned i; for(i = 0; i < l; i++){
    4.         unsigned k = i-i/8;
    5.         m[k] = m[i];
    6.         m[k] >>= i%8;
    7.         m[k] |= m[i+1] << (7 - i%8);
    8. }
    coding pdu Xerx?
     
  8. Xerx

    Xerx Алексей

    Публикаций:
    0
    Регистрация:
    17 фев 2005
    Сообщения:
    528
    Адрес:
    Russia
    Так, давайте поподробнее расскажу. Во первых, на ассемблере (наиболее эллегантно должно получиться)!
    Вход (только для примера, может быть как угодно по другому):

    .data?
    buffer BYTE 14 dup (?) ; буфер, в который будут записываться 7-битные значения. размер буфера (число БИТ) кратен 7. Ну понятно, что это приведет (почти всегда) к неиспользованию части бит последнего байта в буфере, но не в том дело.

    В этот буфер нужно записывать значения из диапазона 00h .. 7Fh. Т.е. после записи чисел XXX XXXXb и YYY YYYYb буфер будет выглядеть так: XXXX XXXY YYYY YY00 ......

    Конечно можно все это сделать в лоб с итерацией значения сдвига для "выталкивания" бит из байта, но я слишком начитался книжки "Уоррен Генри, мл. Алгоритмические трюки для программистов" и хочется найти более эллегантное и быстрое решение (если такое есть :dntknw: ).
     
  9. Xerx

    Xerx Алексей

    Публикаций:
    0
    Регистрация:
    17 фев 2005
    Сообщения:
    528
    Адрес:
    Russia
    Кстати, в принципе можно использовать и алгоритм побитного заполнения массива. Так даже лучше будет.
     
  10. varnie

    varnie New Member

    Публикаций:
    0
    Регистрация:
    2 янв 2005
    Сообщения:
    1.785
    еще можно для удобства воспользоваться контейнерным классом bitset, что в STL.
     
  11. vdk

    vdk New Member

    Публикаций:
    0
    Регистрация:
    18 дек 2003
    Сообщения:
    18
    значения из диапазона 00h .. 7Fh - char m[] = "ASCII"
    Т.е. после записи чисел bXXX XXXX и bYYY YYYY буфер будет выглядеть так: XXXX XXXY YYYY YY00 - после цикла, m[] будет выглядеть именно так, только завершаюшие нули ...
     
  12. Xerx

    Xerx Алексей

    Публикаций:
    0
    Регистрация:
    17 фев 2005
    Сообщения:
    528
    Адрес:
    Russia
    varnie
    Я же написал, что на ASM и МАКСИМАЛЬНО быстро! Да и STL с "быстро" как-то не очень друг с другом соотносятся.

    vdk
    Мне нужно программное заполнение. Кстати,
    Код (Text):
    1. char m[] = "ASCII"
    - это заполнение ВОСЬМИБИТНЫМИ байтами, и
    Код (Text):
    1. XXXX XXXY YYYY YY00
    2. ^ младший бит
    тут НИКАК нельзя сделать ;) В данном случае получится
    Код (Text):
    1. XXXX XXX0 YYYY YYY0 ...
    2. ^ младший бит
    А это не то. Я ж вроде все понятно написал!
     
  13. Nouzui

    Nouzui New Member

    Публикаций:
    0
    Регистрация:
    17 ноя 2006
    Сообщения:
    856
    ну какое тут может быть "максимально быстро"?
    побитовые операции..
     
  14. Nouzui

    Nouzui New Member

    Публикаций:
    0
    Регистрация:
    17 ноя 2006
    Сообщения:
    856
    Код (Text):
    1. lodsb
    2. shrd edx, eax, 7
    3. lodsb
    4. shrd edx, eax, 7
    5. lodsb
    6. shrd edx, eax, 7
    7. lodsb
    8. shrd edx, eax, 7
    9. lodsb
    10. shrd edx, eax, 4
    11. ror eax, 7
    12. lodsb
    13. ror eax, 7
    14. lodsb
    15. ror eax, 7
    16. lodsb
    17. ror eax, 7
    18. shr eax, 8
    19. mov [edi], edx
    20. mov [edi+4], eax
    21. add edi, 7
    итд..

    где-то так
     
  15. Xerx

    Xerx Алексей

    Публикаций:
    0
    Регистрация:
    17 фев 2005
    Сообщения:
    528
    Адрес:
    Russia
    У меня сейчас такой алгоритм:

    src - массив байт, из которого будут извлекаться отдельные биты (их номера перечислены в shift) и записываться в результирующий массив dst. Биты берутся из src вразнобой (например так: 3, 58, 12, 17, 1 и т.д.)

    Код (Text):
    1.     mov     esi,    src
    2.     mov     edi,    dst
    3.     lea     ebx,    shift
    4.  
    5.     // инициализация цикла с итератором в EDX
    6.     xor     edx,    edx
    7.  
    8.     // CH накапливает текущее значение для "выталкивания" в DST ("накопитель")
    9.     xor     ch,     ch
    10.  
    11. @@loop:
    12.  
    13.     xor     eax,    eax
    14.     mov     al,     dh
    15.     shl     al,     3
    16.     or      al,     dl
    17.     mov     al,     byte ptr [ebx+eax]
    18.     dec     al
    19.  
    20.     // в AL нужный номер бита
    21.     mov     cl,     al
    22.     mov     al,     cl
    23.     and     cl,     7
    24.     neg     cl
    25.     add     cl,     7
    26.     shr     al,     3
    27.  
    28.     // получаю нужный бит
    29.     mov     al,     byte ptr [esi+eax]
    30.     shr     al,     cl
    31.     and     al,     1
    32.  
    33.     // записываю в результат
    34.     shl     ch,     1
    35.     or      ch,     al
    36.  
    37.     // проверка на необходимость "выталкивания" байта
    38.     cmp     dl,     7
    39.     jne     @@next
    40.  
    41.         // записываю в выходной буфер
    42.         mov     byte ptr [edi], ch
    43.         inc     edi
    44.         xor     ch,     ch  // очистка "накопителя"
    45.         xor     dl,     dl  // сброс счетчика бит до -1, ...
    46.         dec     dl          // ... чтобы "inc dl" ниже дал 0
    47.         inc     dh          // инкремент счетчика байт
    48.  
    49.         cmp     dh,     BYTES_TO_PROCESS
    50.         je      @@exit                 
    51.  
    52.     @@next:
    53.         inc     dl
    54.         jmp     @@loop
    55.            
    56. @@exit:
    Мне такой код не очень-то и нравится. Вот и спрашиваю, кто предложит лучше.