Собственно, предложите эффективный алгоритм по subj. (оптимизация по скорости выполнения) для i80386 (можно выше ). Если не совсем корректно высказался, то объясняю подробнее: Есть массив байт. Его общая длина (в битах) кратна 7. Нужно последовательно заполнить его 7-битными значениями. Все дело в последнем бите каждого байта, которого приходится "забирать" из каждого следующего добавляемого 7-битного байта.
Ну просто проблемма в том, что любой байт будет состоять из двух частей (ну или экземпляров) этих 7 бит. Можно еще поиграться с флагом переноса.
Код (Text): char m[] = "ASCII"; unsigned l = strlen(m); unsigned i; for(i = 0; i < l; i++){ unsigned k = i-i/8; m[k] = m[i]; m[k] >>= i%8; m[k] |= m[i+1] << (7 - i%8); } coding pdu Xerx?
Так, давайте поподробнее расскажу. Во первых, на ассемблере (наиболее эллегантно должно получиться)! Вход (только для примера, может быть как угодно по другому): .data? buffer BYTE 14 dup (?) ; буфер, в который будут записываться 7-битные значения. размер буфера (число БИТ) кратен 7. Ну понятно, что это приведет (почти всегда) к неиспользованию части бит последнего байта в буфере, но не в том дело. В этот буфер нужно записывать значения из диапазона 00h .. 7Fh. Т.е. после записи чисел XXX XXXXb и YYY YYYYb буфер будет выглядеть так: XXXX XXXY YYYY YY00 ...... Конечно можно все это сделать в лоб с итерацией значения сдвига для "выталкивания" бит из байта, но я слишком начитался книжки "Уоррен Генри, мл. Алгоритмические трюки для программистов" и хочется найти более эллегантное и быстрое решение (если такое есть ).
значения из диапазона 00h .. 7Fh - char m[] = "ASCII" Т.е. после записи чисел bXXX XXXX и bYYY YYYY буфер будет выглядеть так: XXXX XXXY YYYY YY00 - после цикла, m[] будет выглядеть именно так, только завершаюшие нули ...
varnie Я же написал, что на ASM и МАКСИМАЛЬНО быстро! Да и STL с "быстро" как-то не очень друг с другом соотносятся. vdk Мне нужно программное заполнение. Кстати, Код (Text): char m[] = "ASCII" - это заполнение ВОСЬМИБИТНЫМИ байтами, и Код (Text): XXXX XXXY YYYY YY00 ^ младший бит тут НИКАК нельзя сделать В данном случае получится Код (Text): XXXX XXX0 YYYY YYY0 ... ^ младший бит А это не то. Я ж вроде все понятно написал!
Код (Text): lodsb shrd edx, eax, 7 lodsb shrd edx, eax, 7 lodsb shrd edx, eax, 7 lodsb shrd edx, eax, 7 lodsb shrd edx, eax, 4 ror eax, 7 lodsb ror eax, 7 lodsb ror eax, 7 lodsb ror eax, 7 shr eax, 8 mov [edi], edx mov [edi+4], eax add edi, 7 итд.. где-то так
У меня сейчас такой алгоритм: src - массив байт, из которого будут извлекаться отдельные биты (их номера перечислены в shift) и записываться в результирующий массив dst. Биты берутся из src вразнобой (например так: 3, 58, 12, 17, 1 и т.д.) Код (Text): mov esi, src mov edi, dst lea ebx, shift // инициализация цикла с итератором в EDX xor edx, edx // CH накапливает текущее значение для "выталкивания" в DST ("накопитель") xor ch, ch @@loop: xor eax, eax mov al, dh shl al, 3 or al, dl mov al, byte ptr [ebx+eax] dec al // в AL нужный номер бита mov cl, al mov al, cl and cl, 7 neg cl add cl, 7 shr al, 3 // получаю нужный бит mov al, byte ptr [esi+eax] shr al, cl and al, 1 // записываю в результат shl ch, 1 or ch, al // проверка на необходимость "выталкивания" байта cmp dl, 7 jne @@next // записываю в выходной буфер mov byte ptr [edi], ch inc edi xor ch, ch // очистка "накопителя" xor dl, dl // сброс счетчика бит до -1, ... dec dl // ... чтобы "inc dl" ниже дал 0 inc dh // инкремент счетчика байт cmp dh, BYTES_TO_PROCESS je @@exit @@next: inc dl jmp @@loop @@exit: Мне такой код не очень-то и нравится. Вот и спрашиваю, кто предложит лучше.