Есть такая задача по проверке байт строки..

Тема в разделе "WASM.ASSEMBLER", создана пользователем Asterix, 13 авг 2004.

  1. Asterix

    Asterix New Member

    Публикаций:
    0
    Регистрация:
    25 фев 2003
    Сообщения:
    3.576
    В текущем месте строки, указатель на которую находится в esi

    нужно проверить байты по адресу [esi-1] , [esi] и [esi+1] на равенство

    их нулю и выполнить переход по условию

    if BYTE [esi-1]==0 && BYTE [esi]==0 || BYTE [esi]==0 && BYTE [esi+1]==0

    то делать jmp @exit

    elseif BYTE [esi-1]==0 || BYTE [esi]==0

    то делать jmp @1

    else делать jmp @2

    желательно ограничиться одним прыжком, регистры можно использовать любые

    кроме esi,edi,ebp и esp конечно.
     
  2. masquer

    masquer wasm.ru

    Публикаций:
    0
    Регистрация:
    13 сен 2002
    Сообщения:
    890
    Адрес:
    Николаев
    типа того, если я правильно условие понял :) но код не проверял.
    Код (Text):
    1. mov eax, [esi-1]
    2. mov edx, eax
    3. and edx, 0ffffh
    4. shr eax, 8
    5. and eax, 0ffffh
    6. sub edx, 1
    7. sbb edx, edx
    8. sub eax, 1
    9. sbb eax, eax
    10. not edx
    11. not eax
    12. add eax, edx
    13. not eax
    14. lea edx, @@lookup_table
    15. jmp dword ptr [edx+eax*4]
    16. ...
    17. @@lookup_table:
    18. dd offset @@exit
    19. dd offset @1
    20. dd offset @2
     
  3. Asterix

    Asterix New Member

    Публикаций:
    0
    Регистрация:
    25 фев 2003
    Сообщения:
    3.576
    masquer

    Я вобще планировал что будет jmp reg32, хотя про один регистр это я зря написал, вобщем нужен оптимальный по скорости вариант.
     
  4. green

    green New Member

    Публикаций:
    0
    Регистрация:
    15 июл 2003
    Сообщения:
    1.217
    Адрес:
    Ukraine
    imho, можно ещё так:



    mov eax, [esi-1]

    xor edx, edx

    neg al

    adc dl, dh

    neg ah

    adc dl, dh

    jmp dword ptr @@lookup_table[edx * 4]

    @@lookup_table:

    dd offset @@exit

    dd offset @1

    dd offset @2
     
  5. S_T_A_S_

    S_T_A_S_ New Member

    Публикаций:
    0
    Регистрация:
    27 окт 2003
    Сообщения:
    1.754
    Код не проверял, т.к. не уверен, что условие правильно понял..
    Код (Text):
    1. <font face="monospace]xor  ebx,ebx
    2.  
    3. xor  eax,eax
    4. cmp  bl,[esi-1]
    5. rcl  eax,1
    6. cmp  bl,[esi]
    7. rcl  eax,1
    8. cmp  bl,[esi+1]
    9. rcl  eax,1
    10. jmp  [jt+eax*4]
    11.  
    12. align 16
    13. jt: ; esi   -1 0 +1
    14. dd  @exit    0 0 0
    15. dd  @exit    0 0 1
    16. dd  @1       0 1 0
    17. dd  @1       0 1 1
    18. dd  @exit    1 0 0
    19. dd  @1       1 0 1
    20. dd  @2       1 1 0
    21. dd  @2       1 1 1</font><!--face-->
     
  6. Black_mirror

    Black_mirror Active Member

    Публикаций:
    0
    Регистрация:
    14 окт 2002
    Сообщения:
    1.035
    Asterix

    Это ты таким методом двойной ноль ищешь? - Забудь про ЯВУ!



    Самый простой вариант(возможно и самый быстрый):
    Код (Text):
    1.   mov eax,[esi-1]
    2.   test eax,0ffffh
    3.   jz .exit
    4.   cmp al,0
    5.   jz .l1
    6.   test eax,0ffff00h
    7.   jz .exit
    8.   cmp ah,0
    9.   jz .l1
    10. .l2:
     
  7. Asterix

    Asterix New Member

    Публикаций:
    0
    Регистрация:
    25 фев 2003
    Сообщения:
    3.576
    green

    А где проверка третьего байта строки?





    S_T_A_S_

    > т.к. не уверен, что условие правильно понял..



    Неужели я невнятно объяснил условие? :derisive:

    Но в твоём коде мы три раза читаем байты в памяти, мне кажется это будет медленнее чем прочитать один раз одним DWORD'ом.
     
  8. Asterix

    Asterix New Member

    Публикаций:
    0
    Регистрация:
    25 фев 2003
    Сообщения:
    3.576
    Black_mirror

    > Забудь про ЯВУ!



    Это я лишь для условия написал :)



    > Это ты таким методом двойной ноль ищешь?

    Да, это продолжение той задачи :derisive:



    > cmp al,0



    А почему не

    test al,al

    нельзя что-ли?
     
  9. S_T_A_S_

    S_T_A_S_ New Member

    Публикаций:
    0
    Регистрация:
    27 окт 2003
    Сообщения:
    1.754
    Как сказать..

    Проц всё равно будет по 16/32 байта читать, а дальше данные будут из кеша браться.

    Байты можно смело читать с любого адреса, а DWORD'ы рекомендуется только с кратных 4.

    Тем более если ещё и партиальные регистры (ah) задействуются..

    Переделать читая DWORD'ы проблем нет.

    Я в таком виде написАл, что бы понятней было как работает.

    Но пока так и не уверн, подходит ли это под твою кучу IF/ELSE, т.к. я в них запутался %)



    PS: align лучше 32 делать.
     
  10. Black_mirror

    Black_mirror Active Member

    Публикаций:
    0
    Регистрация:
    14 окт 2002
    Сообщения:
    1.035
    Asterix

    cmp al,0 можно и так оставить, а вот cmp ah,0 точно на test нужно заменить.



    А почему бы не сделать условием окончания цикла "прочитана пустая строка"?



    PS: Твой "HLL" никому не понятен 8)))

    PPS: Исправлено в связи с протестом Володи.
     
  11. volodya

    volodya wasm.ru

    Публикаций:
    0
    Регистрация:
    22 апр 2003
    Сообщения:
    1.169
    Твой HLL никому не понятен



    Я протестую. Это не HLL. Эта фигня недостойна звания HLL! :)
     
  12. Asterix

    Asterix New Member

    Публикаций:
    0
    Регистрация:
    25 фев 2003
    Сообщения:
    3.576
    Black_mirror

    Твой код неправильный, есть возможность попасть на .l1 раньше чем на .exit
     
  13. Black_mirror

    Black_mirror Active Member

    Публикаций:
    0
    Регистрация:
    14 окт 2002
    Сообщения:
    1.035
    Asterix

    Ну тогда так:
    Код (Text):
    1.   mov eax,[esi-1]
    2.   test eax,0ffffh
    3.   jz .exit
    4.   test eax,0ffff00h
    5.   jz .exit
    6.   test al,al
    7.   jz .l1
    8.   test ah,ah
    9.   jz .l1
    10. .l2:
     
  14. Asterix

    Asterix New Member

    Публикаций:
    0
    Регистрация:
    25 фев 2003
    Сообщения:
    3.576
    Да ладно вам к моему HLL придираться то, вот вам чистый синтаксис masm'а:
    Код (Text):
    1. .IF (BYTE PTR [esi-1]==0 && BYTE PTR [esi]==0) || (BYTE PTR [esi]==0 && BYTE PTR [esi+1]==0)
    2.   jmp @exit
    3. .ELSEIF BYTE PTR [esi-1]==0 || BYTE PTR [esi]==0
    4.   jmp @1
    5. .ELSE
    6.   jmp @2
    7. .ENDIF
     
  15. Asterix

    Asterix New Member

    Публикаций:
    0
    Регистрация:
    25 фев 2003
    Сообщения:
    3.576
    Black_mirror

    > А почему бы не сделать условием окончания цикла "прочитана пустая строка"?



    Потому что я всё-равно должен отлавливать конец каждой подстроки и тут же нужно проверять а не конец ли это всей строки.
     
  16. Black_mirror

    Black_mirror Active Member

    Публикаций:
    0
    Регистрация:
    14 окт 2002
    Сообщения:
    1.035
    Asterix

    Посчитай сколько символов в моем коде и сколько в твоем. Мой код даже набрать быстрее 8)

    А о том, сколько переходов будет сгенерировано, мне даже страшно подумать ...







    В начале же извлекаеся имя сигнатуры, вот после того, как его извлекли можно и проверку такую сделать. Или в буфере должна последняя сигнатура остаться?
     
  17. Asterix

    Asterix New Member

    Публикаций:
    0
    Регистрация:
    25 фев 2003
    Сообщения:
    3.576
    Black_mirror

    И всё-таки мне кажется что раз прыжки парами в одно и то же место то в каждой паре по одному прыжку можно сократить, проверив условие как-нибудь по хитрому..
     
  18. Black_mirror

    Black_mirror Active Member

    Публикаций:
    0
    Регистрация:
    14 окт 2002
    Сообщения:
    1.035
    Asterix

    Если хочешь один переход, то тебе сюда
     
  19. Asterix

    Asterix New Member

    Публикаций:
    0
    Регистрация:
    25 фев 2003
    Сообщения:
    3.576
    Black_mirror

    > В начале же извлекаеся имя сигнатуры, вот после того, как его извлекли можно и проверку такую сделать. Или в буфере должна последняя сигнатура остаться?



    После того как с сигнатурой поработает моя процедура сигнатура мне уже не нужна.

    Но из-за того что мы осуществляем набор 4-х байтов в eax для работы твоей hextonum, конец получается как бы плавающий, т.е. ноль может прийти в процессе набора байтов в eax или набор байтов окончится впритык к этому нулю, и поэтому всё-равно проверка сильно простой не получится, почему бы тогда уж и на конец строки(0,0) не проверить, сейчас код для набора байтов у меня такой:
    Код (Text):
    1. @loop3:
    2.   xor edx,edx
    3.   mov ecx,4
    4. @@:
    5.   shl eax, 8
    6.   test edx,edx
    7.   jnz @done
    8. @skip:
    9.   lodsb
    10.   test al, al
    11.   jnz @ok
    12.   inc edx
    13. @ok:
    14.   cmp al, 20h
    15.   je @skip
    16.   cmp al, 09h
    17.   je @skip
    18. @done:
    19.   loop @B
    20.   call hextonum
     
  20. masquer

    masquer wasm.ru

    Публикаций:
    0
    Регистрация:
    13 сен 2002
    Сообщения:
    890
    Адрес:
    Николаев


    ну так поточнее надо быть тогда, сколько тактов, etc.

    А то получается как в объявлении - "требуются маги и предсказатели. оплата высокая. куда и когда приходить - вы и сами знаете" :)

    А чем тебя тут скорость не нравится?