Хотелось бы оптимизировать..

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

  1. Asterix

    Asterix New Member

    Публикаций:
    0
    Регистрация:
    25 фев 2003
    Сообщения:
    3.576
    Хотелось бы оптимизировать..

    Или может кто предложит другую схему реализации.

    Строка в буфере может быть и длиннее, т.е. флагов может быть больше.

    Естественно код специально написан для примера, но смысл думаю понятен.
    Код (Text):
    1. .DATA
    2.  
    3. Flag  dd 0
    4. Flag1 dd 0
    5. Flag2 dd 0
    6. Flag3 dd 0
    7. Flag4 dd 0
    8.  
    9. Buff db "10000",0
    10.  
    11.  
    12. .CODE
    13. start:
    14.  mov esi, OFFSET Buff
    15.  .IF BYTE PTR [esi] == '1'
    16.     inc Flag1
    17.     inc Flag
    18.  .ENDIF
    19.  .IF BYTE PTR [esi+2] == '1'
    20.     inc Flag2
    21.     inc Flag
    22.  .ENDIF
    23.  .IF BYTE PTR [esi+3] == '1'
    24.     inc Flag3
    25.     inc Flag
    26.  .ENDIF
    27.  .IF BYTE PTR [esi+4] == '1'
    28.     inc Flag4
    29.     inc Flag
    30.  .ENDIF
    31.  .IF (Flag)
    32.     invoke MessageBox, 0, OFFSET Buff, 0, 0
    33.  .ENDIF
     
  2. n0p

    n0p 10010000b

    Публикаций:
    0
    Регистрация:
    7 май 2003
    Сообщения:
    256
    Адрес:
    Новосиbeerск
    Ну вот, особо не вдаваясь в суть:
    Код (Text):
    1.  
    2. Flag dd 0
    3. AllFlag rb maxsize
    4.  
    5. mov esi,buf
    6. xor edx,edx
    7. dec edx
    8. @@:
    9. inc edx
    10. lodsb
    11. sub al,'1'
    12. jnz @B
    13. inc [Flag]
    14. inc byte [AllFlag+edx]
    15. jmp @B
    16.  


    Только надо проверку на размер сделать, а то крутиться до посинения будет. :)
     
  3. Asterix

    Asterix New Member

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

    > особо не вдаваясь в суть



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



    Добавлено

    Ага, исправил уже значит.. :derisive:
     
  4. Black_mirror

    Black_mirror Active Member

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

    Флаги это счётчики или у них всего 2 значения?

    Во втором случае можно хранить флаги в битовом массиве, а для установки MMX или SSE2 использовать:
    Код (Text):
    1. movq mm1,[t]
    2. movq mm0,[buf]
    3. pcmpeqb mm0,mm1
    4. pmovmskb eax,mm0
    5. mov [flags],al
    6. movq mm0,[buf+8]
    7. pcmpeqb mm0,mm1
    8. pmovmskb eax,mm0
    9. mov [flags+1],al
    10. ...
    11.  
    12. t db '11111111'




    Если флагов не более 32 то для проверки Flag можно использовать сравнение flags с 0. А если Flag это счётчик то можно использовать алгоритмы для подсчёта числа бит, которые были на форуме.
     
  5. Asterix

    Asterix New Member

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

    Флаги имеют только два значения TRUE и FALSE.



    ЗЫ: лучше наверно без MMX..
     
  6. n0p

    n0p 10010000b

    Публикаций:
    0
    Регистрация:
    7 май 2003
    Сообщения:
    256
    Адрес:
    Новосиbeerск
    Asterix

    Да, я невнимательно читал твой код и сделал пару концептуальных ашыпок. Исправился. :)
     
  7. S_T_A_S_

    S_T_A_S_ New Member

    Публикаций:
    0
    Регистрация:
    27 окт 2003
    Сообщения:
    1.754
    Код (Text):
    1.  
    2. Flag  db 0
    3. Flag1 db 0
    4. Flag2 db 0
    5. Flag3 db 0
    6. Flag4 db 0
    7.  
    8.      mov  edi, Flag
    9.      mov  esi, Buff
    10.      mov  al,'1'
    11.  
    12.      cmp  byte[esi],al
    13.      setz dl
    14.      mov  [edi+1],dl      ; Flag1
    15.      or   [edi],dl
    16.  
    17.      cmp  byte[esi+2],al
    18.      setz dl
    19.      mov  [edi+2],dl  ; Flag2
    20.      or   [edi],dl
    21.  
    22.      cmp  byte[esi+3],al
    23.      setz dl
    24.      mov  [edi+3],dl  ; Flag3
    25.      or   [edi],dl
    26.  
    27.      cmp  byte[esi+4],al
    28.      setz dl
    29.      mov  [edi+4],dl  ; Flag4
    30.      or   [edi],dl
    31.  
    32.      jz   Flag_false
    33.      invoke MessageBox, 0, Buff, 0, 0
    34. Flag_false:
    35.  




    dl можно заменить на ah.

    Флаги заменены на байты - для экономии :)

    Вообще, напрашивается решение отказаться от всяких +2, +3, +4 и засунуть в цикл, добавив счётчик ecx и адресовать так:


    Код (Text):
    1.  
    2.      cmp  byte[esi+ecx],al
    3.      setz dl
    4.      mov  [edi+ecx],dl  ; Flag NN
    5.      or   [edi],dl
    6.      inc  ecx




    ЗЫ: Что-то я думаю долго, уже понаписали тут :)
     
  8. n0p

    n0p 10010000b

    Публикаций:
    0
    Регистрация:
    7 май 2003
    Сообщения:
    256
    Адрес:
    Новосиbeerск
    Кстати, если длинна строки не превышает 32 символов, то можно регистр под это дело выдать и ему биты менять. Получится красиво и не надо флаги в памяти хранить. Но ограничение по длине. :dntknw:
     
  9. Asterix

    Asterix New Member

    Публикаций:
    0
    Регистрация:
    25 фев 2003
    Сообщения:
    3.576
    Кстати, никто не заметил что я не проверяю BYTE PTR [esi+1] - это не описка, так что цикл меня не особенно устраивает.
     
  10. n0p

    n0p 10010000b

    Публикаций:
    0
    Регистрация:
    7 май 2003
    Сообщения:
    256
    Адрес:
    Новосиbeerск
    Asterix

    Ну можно проверять нулевой, пропускать первый и дальше циклом все остальные :)

    Без цикла не удастся сделать код для неопределенной длины строки.
     
  11. S_T_A_S_

    S_T_A_S_ New Member

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




    Какие проблемы, отдельно проверяй первое условие:
    Код (Text):
    1.  
    2. flag_number = 4
    3. Flag db 0
    4.      rb flag_number
    5.  
    6.      mov  edi, Flag
    7.      mov  esi, Buff
    8.      mov  al,'1'
    9.      mov  ecx,flag_number
    10.  
    11.      cmp  byte[esi],al
    12.      setz dl
    13.      mov  [edi+1],dl      ; Flag1
    14.      or   [edi],dl
    15. loop:
    16.      cmp  byte[esi+ecx+1],al
    17.      setz dl
    18.      mov  [edi+ecx],dl  ; Flag NN
    19.      or   [edi],dl
    20.      dec  ecx
    21.      jnz  loop
    22.      
    23.      cmp  [edi],cl
    24.      jz   Flag_false
    25.      invoke MessageBox, 0, Buff, 0, 0
    26. Flag_false:
    27.  
     
  12. bogrus

    bogrus Active Member

    Публикаций:
    0
    Регистрация:
    24 окт 2003
    Сообщения:
    1.338
    Адрес:
    ukraine
    А зачем вообще эти Flag1-Flag4, сам buffer напрашивается на его использование в качестве флагов, а конкретно для этого кода похоже работает и так:
    Код (Text):
    1. ;===============================================
    2. buffer      db      "10000",0
    3. size        =       $-buffer
    4. ;===============================================
    5.             mov     esi,buffer-1
    6.             mov     ecx,size-1
    7.             mov     byte [esi+2],'0'
    8. @@:         inc     esi
    9.             cmp     byte [esi],'1'
    10.             jz      msgbox
    11.             loop    @B
    12.             ...
    13. msgbox:     invoke  MessageBox,0,buffer,buffer,0
    14. ;===============================================
     
  13. Asterix

    Asterix New Member

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

    > Какие проблемы, отдельно проверяй первое условие



    Всё-равно проблемы есть, т.к. действия между .IF/.ENDIF в моём случае не ограничиваются только лишь установкой флагов, т.е. могут быть дополнительные проверки, вызываться другие функции и лишь после этого выставляться флаги.
     
  14. Asterix

    Asterix New Member

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

    Твой код не удовлетворяет условию, т.к. выход из цикла произойдёт при первом же '1'
     
  15. captain cobalt

    captain cobalt New Member

    Публикаций:
    0
    Регистрация:
    21 дек 2003
    Сообщения:
    222
    Адрес:
    /ru/perm
  16. Asterix

    Asterix New Member

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

    Да, только теперь количество флагов увеличилось и я стал путаться в моём коде, хотелось что-то изменить :derisive:
     
  17. Black_mirror

    Black_mirror Active Member

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





    Сколько же теперь у тебя флагов?
     
  18. Asterix

    Asterix New Member

    Публикаций:
    0
    Регистрация:
    25 фев 2003
    Сообщения:
    3.576
    Сделал вот так, пусть не оптимально, зато наглядно :derisive:
    Код (Text):
    1. Flag   dd 0
    2. Flag1  dd 0
    3. Flag11 dd 0
    4. Flag2  dd 0
    5. Flag3  dd 0
    6. Flag4  dd 0
    7.  
    8. Buff db "10000",0
    9.  
    10. .CODE
    11. start:
    12. mov esi, OFFSET Buff
    13. mov edi, OFFSET Flag
    14. mov ebx, OFFSET Flag1
    15. .IF BYTE PTR [esi] == '1'
    16.   inc DWORD PTR [ebx]
    17.   inc DWORD PTR [edi]
    18. .ENDIF
    19. .IF BYTE PTR [esi+2] == '1'
    20.   inc DWORD PTR [ebx+2*(SIZEOF DWORD)]
    21.   inc DWORD PTR [edi]
    22. .ENDIF
    23. .IF BYTE PTR [esi+3] == '1'
    24.   inc DWORD PTR [ebx+3*(SIZEOF DWORD)]
    25.   inc DWORD PTR [edi]
    26. .ENDIF
    27. .IF BYTE PTR [esi+4] == '1'
    28.   inc DWORD PTR [ebx+4*(SIZEOF DWORD)]
    29.   inc DWORD PTR [edi]
    30. .ENDIF
    31. .IF (DWORD PTR [edi])
    32.   invoke MessageBox, 0, OFFSET Buff, 0, 0
    33. .ENDIF
     
  19. Asterix

    Asterix New Member

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

    > Сколько же теперь у тебя флагов?



    Скажем так, с каждой новой версией программы количество флагов увеличивается, сейчас пока их 7 %)
     
  20. Asterix

    Asterix New Member

    Публикаций:
    0
    Регистрация:
    25 фев 2003
    Сообщения:
    3.576
    А ещё лучше будет так:
    Код (Text):
    1. mov esi, OFFSET Buff
    2. mov edi, OFFSET Flag
    3. mov ebp, OFFSET Flag1
    4. mov bl, '1'
    5. .IF BYTE PTR [esi] == bl
    6.   inc DWORD PTR [ebp]
    7.   inc DWORD PTR [edi]
    8. .ENDIF
    9. .IF BYTE PTR [esi+2] == bl
    10.   inc DWORD PTR [ebp+2*(SIZEOF DWORD)]
    11.   inc DWORD PTR [edi]
    12. .ENDIF
    13. .IF BYTE PTR [esi+3] == bl
    14.   inc DWORD PTR [ebp+3*(SIZEOF DWORD)]
    15.   inc DWORD PTR [edi]
    16. .ENDIF
    17. .IF BYTE PTR [esi+4] == bl
    18.   inc DWORD PTR [ebp+4*(SIZEOF DWORD)]
    19.   inc DWORD PTR [edi]
    20. .ENDIF
    21. .IF (DWORD PTR [edi])
    22.   invoke MessageBox, 0, OFFSET Buff, 0, 0
    23. .ENDIF