Задачка об уникальных тетрадах

Тема в разделе "WASM.A&O", создана пользователем Black_mirror, 11 мар 2010.

  1. edemko

    edemko New Member

    Публикаций:
    0
    Регистрация:
    25 ноя 2009
    Сообщения:
    454
    Black_mirror,
    На выходе не восстанавливает mm0..mm2.
    Последним flags пишет, \not eax\ - используйте jcc.

    Код (Text):
    1. proc p1; v1,v2
    2.         mov     eax,[esp+4]
    3.         movd    mm0,eax
    4.         shr     eax,4
    5.         movd    mm1,eax
    6.         punpcklbw mm0,mm1
    7.  
    8.         mov     eax,[esp+8]
    9.         movd    mm1,eax
    10.         shr     eax,4
    11.         movd    mm2,eax
    12.         punpcklbw mm1,mm2
    13.  
    14.         pcmpeqb mm0,mm1
    15.         movq    [esp+4],mm0
    16.         movd    eax,mm0
    17.         or      eax,[esp+8]
    18.         jz      @f
    19.         or      eax,-1
    20.   @@:   not     eax
    21.         ret     8
    22. endp
     
  2. edemko

    edemko New Member

    Публикаций:
    0
    Регистрация:
    25 ноя 2009
    Сообщения:
    454
    ...вот только не помню, меняет ли not flags - используйте neg.
     
  3. edemko

    edemko New Member

    Публикаций:
    0
    Регистрация:
    25 ноя 2009
    Сообщения:
    454
    not flags не пишет - переделайте чутку
     
  4. Black_mirror

    Black_mirror Active Member

    Публикаций:
    0
    Регистрация:
    14 окт 2002
    Сообщения:
    1.035
    KeSqueer
    XOR EDX,EDX
    BTS EDX,EAX <- здесь устанавливает бит соответствующий первой тетраде
    MOV CL,4

    ROL EAX,CL
    BTS EDX,EAX
    SBB EBX,EBX <- а здесь счётчик совпавших тетрад устанавливаем в -1, если совпали две первых проверенных тетрады

    ROL EAX,CL
    BTS EDX,EAX
    ADC EBX,EBX <- ну а тут сдвигаем счётчик и добавляем к нему очередной флаг, таких блоков 6 штук
    ...
    На самом деле BTS берёт не 4 бита, а 5, из-за этого лишнего бита, флаг может установиться как в младшей половине edx, так и в старшей, это проверяется следующим кодом:
    SHLD EBX,EDX,10
    AND BX,DX
    Данный код требует 7 байт, но bts edx,eax на 1 байт короче bts dx,ax, а поскольку команд bts у нас 8 штук, то в итоге мы экономим один байт.
     
  5. KeSqueer

    KeSqueer Сергей

    Публикаций:
    0
    Регистрация:
    19 июл 2007
    Сообщения:
    1.183
    Адрес:
    Москва
    Black_mirror
    Почему бы не использовать xor ebx, ebx и 8 раз adc ebx, ebx? Далее если ebx не 0, то есть одинаковые тетрады.
     
  6. Black_mirror

    Black_mirror Active Member

    Публикаций:
    0
    Регистрация:
    14 окт 2002
    Сообщения:
    1.035
    KeSqueer
    Потому что код оптимизируем по размеру, первый раз adc можно не использовать потому что перенос невозможен в принципе, а второй adc и xor можно заменить на sbb с таким же успехом.
     
  7. Black_mirror

    Black_mirror Active Member

    Публикаций:
    0
    Регистрация:
    14 окт 2002
    Сообщения:
    1.035
    Serg50
    Немного почистил ваш код, 70 байт, всего на 1 байт длинее варианта с битовой таблицей(вернее на 2, потому что в варианте с таблицей not можно заменить на cmc), на правильность пока не тестировал:
    Код (Text):
    1.     mov ebx,11111111h
    2.     mov cl,4
    3.     mov ebp,eax
    4.    
    5.     rol eax,cl
    6.     mov edx,eax
    7.     rol eax,cl
    8.     mov esi,eax
    9.     rol eax,cl
    10.     mov edi,eax
    11.     rol eax,cl
    12.    
    13.     xor eax,ebp
    14.     xor edx,ebp
    15.     xor esi,ebp
    16.     xor edi,ebp
    17.    
    18.     push edi
    19.     push esi
    20.     push edx
    21.     push eax
    22.    
    23.     sub eax,ebx
    24.     sbb edx,ebx
    25.     sbb esi,ebx
    26.     sbb edi,ebx
    27.     sbb al,0
    28.    
    29.     pop ebp
    30.     xor eax,ebp
    31.     pop ebp
    32.     xor edx,ebp
    33.     pop ebp
    34.     xor esi,ebp
    35.     pop ebp
    36.     xor edi,ebp
    37.    
    38.     and eax,edx
    39.     and eax,esi
    40.     and eax,edi
    41.     and eax,ebx
    42.     cmp eax,ebx
    43.     cmc
    44.     sbb eax,eax
    edemko
    Ваш код я пока совсем не понял, вообще для mmx я предлагал решать задачку с 8 байтами, а не тетрадами.
     
  8. edemko

    edemko New Member

    Публикаций:
    0
    Регистрация:
    25 ноя 2009
    Сообщения:
    454
    Код (Text):
    1. ; v1 = первый dword, к примеру $1234abcd
    2. ; v2 = второй dword, к примеру $1234abcd
    3. proc p1; v1,v2
    4.         mov     eax,[esp+4] ; $1234abcd
    5.         movd    mm0,eax
    6.         shr     eax,4
    7.         movd    mm1,eax             ; $01234abc>>d
    8.         punpcklbw mm0,mm1           ; $01122334'4aabbccd
    9.  
    10.         mov     eax,[esp+8]         ; то же проделываем со вторым набором тетрад v2
    11.         movd    mm1,eax
    12.         shr     eax,4
    13.         movd    mm2,eax
    14.         punpcklbw mm1,mm2
    15.        
    16.         push    $0f0f0f0f $0f0f0f0f ; не обязательно, но более понятно
    17.         pand    mm0,[esp]           ; $01020304'0a0b0c0d
    18.         pand    mm1,[esp]           ; $01020304'0a0b0c0d
    19.  
    20.         pcmpeqb mm0,mm1             ; сравнить побайтно, если равно, - mm0.x = $ff, иначе $00
    21.         movq    mm1,mm0             ; нам нужна только старшая часть результата сравнения...
    22.         psrlq   mm1,32              ; ...получили
    23.         por     mm0,mm1             ; старшая часть нас уже не волнует
    24.         movd    eax,mm0             ; сохраняем, если eax=0, совпадений нет вовсе
    25.         ret     8                  
    26. endp
    Black_mirror, таким способом для байт нужно брать xmm.
    Процедуру переписывал без OllyDbg(я не дома), должно работать.
    Часто сам не понимаю, чего перо выкинет...
     
  9. edemko

    edemko New Member

    Публикаций:
    0
    Регистрация:
    25 ноя 2009
    Сообщения:
    454
    странное форматирование получилось с notepad++, используйте fasmw.exe
     
  10. edemko

    edemko New Member

    Публикаций:
    0
    Регистрация:
    25 ноя 2009
    Сообщения:
    454
    еще, там, где необязательно, нужно возвратить esp в исходное значение
     
  11. Black_mirror

    Black_mirror Active Member

    Публикаций:
    0
    Регистрация:
    14 окт 2002
    Сообщения:
    1.035
    edemko
    Задачка у нас не в сравнении тетрад двух слов, задачка у нас в сравнении между собой всех тетрад одного слова. Если хотя бы две из них равны, то устанавливаем eax=0, а если все различны, то eax=-1. Ту же самую задачку только уже не с тетрадами, а с байтами предлагается решить для rax или mm0, результат нужно оставить в них же.
     
  12. edemko

    edemko New Member

    Публикаций:
    0
    Регистрация:
    25 ноя 2009
    Сообщения:
    454
    эта прока сравнивает соответствующие 4 бита каждого dword'a, то есть 8 за 1 проход.
     
  13. edemko

    edemko New Member

    Публикаций:
    0
    Регистрация:
    25 ноя 2009
    Сообщения:
    454
    ...вам остается лишь сравнить eax=0 и переиначить условие(обработку результата).
     
  14. edemko

    edemko New Member

    Публикаций:
    0
    Регистрация:
    25 ноя 2009
    Сообщения:
    454
    Попробуйте поганять под OllyDbg, поизменяйте значения параметров v1,v2.
     
  15. murder

    murder Member

    Публикаций:
    0
    Регистрация:
    3 июн 2007
    Сообщения:
    628
    edemko
    Надо примерно так
    Код (Text):
    1. eax:=0;
    2. for i:=0 to 6 do
    3.     for j:=i+1 to 7 do
    4.         if mm0[i]=mm0[j] then
    5.             goto 1;
    6. dec(eax);
    7. 1:
     
  16. edemko

    edemko New Member

    Публикаций:
    0
    Регистрация:
    25 ноя 2009
    Сообщения:
    454
    murder[/m], почему
    for i:=0 to 6
    может 7?
     
  17. persicum

    persicum New Member

    Публикаций:
    0
    Регистрация:
    2 фев 2007
    Сообщения:
    947
    edemko
    Для семого байта где пару найти?
     
  18. Medstrax

    Medstrax Забанен

    Публикаций:
    0
    Регистрация:
    18 июл 2006
    Сообщения:
    673
    Без цикла, 62 байта
    Код (Text):
    1. xor edx,edx
    2. mov cl,4
    3.  
    4. bts dx,ax
    5. rcr eax,cl
    6.  
    7. bts dx,ax
    8. rcr eax,cl
    9.  
    10. bts dx,ax
    11. rcr eax,cl
    12.  
    13. bts dx,ax
    14. rcr eax,cl
    15.  
    16. bts dx,ax
    17. rcr eax,cl
    18.  
    19. bts dx,ax
    20. rcr eax,cl
    21.  
    22. bts dx,ax
    23. rcr eax,cl
    24.  
    25. bts dx,ax
    26. rcr eax,cl
    27.  
    28. and eax,11111111h
    29. neg eax
    30. cmc
    31. sbb eax,eax
    ЗЫ.
    Используя инструкцию POPCNT, вполне выиграть как с циклом так и без. Однако проверить
    не на чем.
     
  19. murder

    murder Member

    Публикаций:
    0
    Регистрация:
    3 июн 2007
    Сообщения:
    628
    medstrax1
    Красиво.
    Ты главное напиши - мы проверим :)
     
  20. murder

    murder Member

    Публикаций:
    0
    Регистрация:
    3 июн 2007
    Сообщения:
    628
    Код (Text):
    1. neg eax
    2. cmc
    можно заменить на
    Код (Text):
    1. sub eax,1
    но выигрыша в размере не будет