выбрать данные по маскам

Тема в разделе "WASM.A&O", создана пользователем t00x, 16 мар 2009.

  1. t00x

    t00x New Member

    Публикаций:
    0
    Регистрация:
    15 фев 2007
    Сообщения:
    1.921
    даны шесть бинарных строк (масок состояний), где 1 -- позиция _не_имеет_ значения (0/1), 0 -- однозначно определено.
    Код (Text):
    1.  101 101 101
    2.  111 000 111
    3.  101 001 111
    4.  101 100 111
    5.  111 100 101
    6.  111 001 101
    надо найти минимальный алго перебора этих масок (прямой перебор не предлагать ).
     
  2. qqwe

    qqwe New Member

    Публикаций:
    0
    Регистрация:
    2 янв 2009
    Сообщения:
    2.914
    не совсем понятно задание
     
  3. maxdiver

    maxdiver Max

    Публикаций:
    0
    Регистрация:
    18 июл 2006
    Сообщения:
    308
    Адрес:
    Саратов
    Я правильно понимаю задачу, что мы рассматриваем только те биты, для которых во всех масках стоят единицы? Т.е. задача - найти все маски, в которых в качестве единичных битов могут быть только те, для которых все данные 6 масок содержат единицу? Правда, тогда непонятно, зачем целых 6 масок, если их все в одну можно объединить (поandить).

    Но если задача такая, то это известная задача на перебор всех подмасок данной маски, решается за O(ответа):
    Код (Text):
    1. for (int cur=msk-1; cur>0; cur=(cur-1)&msk)
    2.     добавить_в_ответ_маску_cur;
    Здесь msk - это та маска, все подмаски которой надо получить. Нулевую подмаску надо добавить руками.
     
  4. t00x

    t00x New Member

    Публикаций:
    0
    Регистрация:
    15 фев 2007
    Сообщения:
    1.921
    Код (Text):
    1.  101 101 101
    2.  111 000 111
    3.  101 001 111
    4.  101 100 111
    5.  111 100 101
    6.  111 001 101
    на месте 0 -- значащие биты, на месте 111-ц -- незначащие (потому, что такие начальные условия, на месте значащих битов необходимо отлавливать "0").
    данные (выровненные по 2 байта) хранятся в памяти, надо наименьшим кол-вом операций однозначно определить, проходят данные по маске(хотя бы по одной), или нет.

    P.S. регулярность появления каждой из масок одинакова, поэтому, думаю сначала проверять "серединный" бит.
    как-нибудь так:
    Код (Text):
    1. mov ax, [mem]
    2. and ax, 0x10
    3. jnz @nea
    4. ...
    5. nea:
    P.P.S. и как быть, если вместо битов -- байты (0 / _не_0)?
     
  5. murder

    murder Member

    Публикаций:
    0
    Регистрация:
    3 июн 2007
    Сообщения:
    628
    mask xor data = 111111111b
     
  6. t00x

    t00x New Member

    Публикаций:
    0
    Регистрация:
    15 фев 2007
    Сообщения:
    1.921
    если втупую, получается так:
    Код (Text):
    1.         mov ax, [mem]
    2.         and al, 0x10
    3.         jnz @nea
    4.  
    5.         shr al, 1
    6.         mov bl, al
    7.         ;00110110
    8.         mov al, bl
    9.         and al, 01001001b
    10.         jnz @nea
    11.         ;01100011
    12.         mov al, bl
    13.         and al, 00011100b
    14.         jnz @nea
    15.         ;00100111
    16.         mov al, bl
    17.         and al, 01011000b
    18.         jnz @nea
    19.         ;00110011
    20.         mov al, bl
    21.         and al, 01001100b
    22.         jnz @nea
    23.         ;01110010
    24.         mov al, bl
    25.         and al, 00001101b
    26.         jnz @nea
    27.         ;01100110
    28.         mov al, bl
    29.         and al, 00011001b
    30.         jnz @nea
    31.         ...
    32. nea:
    если сразу избавиться от бита, который всегда "0", сжать сдвигами и инвертировать, тогда можно проверять по таблице...
    Код (Text):
    1.         mov ax, [mem]
    2.         not al
    3.         shr al, 1       ; -
    4.         mov bl, al
    5.         and bl, 1       ; 1-разряд
    6.         shr al, 1
    7.         and al, 0xE
    8.         or bl, al
    9.         and bl, 0xF     ; 5,4,3,1-разряды
    10.         shr al, 1
    11.         and al, 0x10
    12.         or bl, al
    13.         and bl, 0x1F    ; 7,5,3,1-разряды
    14.         bt [table], bl
    15.         jnc @nea
    16.         ...
    17. nea:
    какие ещё предложения?
     
  7. leo

    leo Active Member

    Публикаций:
    0
    Регистрация:
    4 авг 2004
    Сообщения:
    2.542
    Адрес:
    Russia
    t00x
    А че так сложно, если только 7,5,3,1-разряды ;)
    Код (Text):
    1. mov cl, [mem]
    2. test cl,10h
    3. jnz nea;
    4. and cl,10101010b
    5. jz ugu;
    6. mov al,cl
    7. shr cl,5
    8. or cl,al
    9. mov ax,bitmask ;двоичная константа с учетом изменения порядка бит
    10. shr ax,cl
    11. jnc nea
    12. ugu:
     
  8. t00x

    t00x New Member

    Публикаций:
    0
    Регистрация:
    15 фев 2007
    Сообщения:
    1.921
    leo
    так даже лучше (jz ugu; можно убрать)!
    Код (Text):
    1. mov cl, [mem]
    2. test cl,10h
    3. jnz nea;
    4. and cl,10101010b
    5. mov al,cl
    6. shr cl,5
    7. or cl,al
    8. mov ax,bitmask ;двоичная константа с учетом изменения порядка бит
    9. shr ax,cl
    10. jnc nea
    11. ugu:
    8 7 6
    5 4 3
    2 1 0
     
  9. leo

    leo Active Member

    Публикаций:
    0
    Регистрация:
    4 авг 2004
    Сообщения:
    2.542
    Адрес:
    Russia
    t00x
    Не понял. Если на заданных позициях д.б. нули, то cl = 0 удовлетворяет всем маскам, но никакого сдвига не производит и соотв-но CF не устанавливает. Поэтому если экономить на jz, то нужно инвертировать bitmask и юзать jc nea
     
  10. t00x

    t00x New Member

    Публикаций:
    0
    Регистрация:
    15 фев 2007
    Сообщения:
    1.921
    leo
    всё верно.
    однако, cl = 0 (это не все, а ещё одна маска) -- её появление маловероятно, и тратить целый переход неэффективно.
    может предварительно установить CF, чтобы отлавливать этот случай?
    Код (Text):
    1. mov cl, [mem]
    2. test cl,10h
    3. jnz nea;
    4. and cl,10101010b
    5. mov al,cl
    6. shr cl,5
    7. or cl,al
    8. mov ax,bitmask ;двоичная константа с учетом изменения порядка бит
    9. stc
    10. shr ax,cl
    11. jc nea
    12. ugu:
     
  11. leo

    leo Active Member

    Публикаций:
    0
    Регистрация:
    4 авг 2004
    Сообщения:
    2.542
    Адрес:
    Russia
    Ну, не-е ;) Если cl=0 - маловероятно, то и переход jz практически всегда будет предсказываться верно и соотв-но команда jz будет "исполняться" (= "пропускаться") гораздо быстрее, чем тормозная stc.
    Тогда лучше делать как я выше сказал - инвертировать bitmask, чтобы на позициях, удовлетворяющих маскам, стояли нули, а не единицы, и соотв-но делать переход jc nea. В этом сл.после or cl,al флаг CF сам собой очищается и при cl=0 перехода не будет.
    PS: Вроде получается, что в упакованной 4-битной маске допускаются любые комбинации, содержащие 2 нуля. Поэтому значение bitmask для перехода по jc будет равно 111010001000000b
    Код (Text):
    1. mov cl, [mem]
    2. test cl,10h
    3. jnz nea;
    4. and cl,10101010b
    5. mov al,cl
    6. shr cl,5
    7. or cl,al
    8. mov ax,111010001000000b ;если первые 4 бита cl содержат < 2-х нулей, то после shr ax,cl будет CF=1
    9. shr ax,cl
    10. jc nea
     
  12. t00x

    t00x New Member

    Публикаций:
    0
    Регистрация:
    15 фев 2007
    Сообщения:
    1.921
    leo
    так и сделаю, только добавлю в bitmask троек нулевых значащих битов.
    спасибо :)
     
  13. leo

    leo Active Member

    Публикаций:
    0
    Регистрация:
    4 авг 2004
    Сообщения:
    2.542
    Адрес:
    Russia
    Не понял, каких еще "троек" ? В маске #11 единицы стоят на запрещенных позициях, а все остальные являются разрешеными
     
  14. t00x

    t00x New Member

    Публикаций:
    0
    Регистрация:
    15 фев 2007
    Сообщения:
    1.921
    leo
    значение bitmask не смотрел, однако:
    cl=0 - маловероятно, но вероятно и его необходимо обрабатывать отдельно в jxx nea,
    CF ведь не установлен при выполнении shr ax,cl

    P.S. "тройка" - 0001, 0010, 0100, 1000 после or cl,al
     
  15. leo

    leo Active Member

    Публикаций:
    0
    Регистрация:
    4 авг 2004
    Сообщения:
    2.542
    Адрес:
    Russia
    Установлен в 0 после or cl,al (о чем я собс-но уже сказал в #11)

    Все эти "тройки" являются допустимыми для твоих масок из #1 и уже учтены в bitmask = 111010001000000b (им соответствуют нули на соотв-х позициях: 0001 -> 0 в младшем разряде и т.д.)
     
  16. t00x

    t00x New Member

    Публикаций:
    0
    Регистрация:
    15 фев 2007
    Сообщения:
    1.921
    уже понял. как с 0000 быть?
    mov eax, 1 1101000100000001b
    shr eax, 1
    ?

    P.S. поправил bitmask
     
  17. leo

    leo Active Member

    Публикаций:
    0
    Регистрация:
    4 авг 2004
    Сообщения:
    2.542
    Адрес:
    Russia
    Видимо, не понял ;)
    Код (Text):
    1. or cl,al  ;устанавливает CF=0
    2. mov ax,111010001000000b
    3. shr ax,cl  ;при cl=0 флаг CF не изменяется, т.е. остается CF=0
    4. jc nea ;переход по CF=1 только для cl = 0111, 1011, 1110, 1101 и 1111
    Вывод: Вариант #11 - вполне рабочий и ничего поправлять\добавлять в нем не нужно
     
  18. t00x

    t00x New Member

    Публикаций:
    0
    Регистрация:
    15 фев 2007
    Сообщения:
    1.921
    да. запланировал при 0000 переход в nea;
    думаете стоит оставить 0000 на ugu; ?