крошечный аналог strcmp

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

  1. Mikl___

    Mikl___ Супермодератор Команда форума

    Публикаций:
    14
    Регистрация:
    25 июн 2008
    Сообщения:
    3.792
    аналог Си-шной функции srtcmp. Возвращает 0 если строки равны, -1 если первая строка меньше второй и 1 если первая строка больше второй
    Код (Text):
    1. .data
    2. string1 db 'мама мыла Раму',0
    3. string2 db 'мама мыла Кришну',0
    4. .code
    5. start:  mov esi,offset string1
    6.         mov edi,offset string2
    7.     call strcmp
    8.         mov esi,offset string2
    9.         mov edi,offset string1
    10.     call strcmp
    11.     mov esi,offset string1
    12.         mov edi,offset string1
    13.     call strcmp
    14.     . . .
    15. strcmp  proc
    16. @@: lodsd;mov eax,[esi] esi+=4
    17.     scasb;cmp al,[edi] edi++
    18.     jnz short a3
    19.     or al,al
    20.     jz short @f
    21.     xchg ah,al
    22.     scasb;cmp al,[edi] edi++
    23.     jnz short a3
    24.     or al,al
    25.     jz short @f
    26.     shr eax,10h
    27.     scasb;cmp al,[edi] edi++
    28.     jnz short a3
    29.     or al,al
    30.     jz short @f
    31.     xchg ah,al
    32.     scasb;cmp ah,[edi] edi++
    33.     jnz short a3
    34.     or al,al
    35.     jnz short @b
    36. @@: xor eax,eax
    37.     retn
    38. a3: sbb eax,eax
    39.     or al,1
    40.     retn
    41. strcmp  endp
     
  2. Rel

    Rel Well-Known Member

    Публикаций:
    2
    Регистрация:
    11 дек 2008
    Сообщения:
    5.323
    исправь на strcmp)))
     
  3. xh4ck

    xh4ck New Member

    Публикаций:
    0
    Регистрация:
    6 мар 2005
    Сообщения:
    60
    Адрес:
    Russia
    а зачем это?
     
  4. Blackbeam

    Blackbeam New Member

    Публикаций:
    0
    Регистрация:
    28 дек 2008
    Сообщения:
    960
    это надо, спасибо Mikl___

    хорошо бы и с остальными разобраться, по мере возможности
     
  5. Mikl___

    Mikl___ Супермодератор Команда форума

    Публикаций:
    14
    Регистрация:
    25 июн 2008
    Сообщения:
    3.792
  6. Blackbeam

    Blackbeam New Member

    Публикаций:
    0
    Регистрация:
    28 дек 2008
    Сообщения:
    960
    для начала все функции, которые могут пригодиться в работе со строками

    полезно для изучаюсчих програмирование и вообще... это больше похоже на програмирование, чем то, что им сейчас считают
     
  7. Mikl___

    Mikl___ Супермодератор Команда форума

    Публикаций:
    14
    Регистрация:
    25 июн 2008
    Сообщения:
    3.792
    Blackbeam
    И всё-таки хотелось бы уточнить: strcat, strlen, strcpy,...? C MMX, SSE, ...? по скорсти, по компактности?
     
  8. Blackbeam

    Blackbeam New Member

    Публикаций:
    0
    Регистрация:
    28 дек 2008
    Сообщения:
    960
    не надо ммх и ссе

    компактность особого значения не имеет, обычно

    хорошо бы сделать библиотеку типа масм32либ, с комментариями на великом и могучем

    ===============

    ( а может ктонить перевести комментарии в масм32либ и написать справочник по ней? )
     
  9. Y_Mur

    Y_Mur Active Member

    Публикаций:
    0
    Регистрация:
    6 сен 2006
    Сообщения:
    2.494
    Blackbeam
    Масм32либ в большинстве случаев следует изучать только в качестве примера как _не_ надо программировать на асме :) Так что лучше осваивай mmx/sse и приёмы низкоуровневой оптимизации ;)
     
  10. max7C4

    max7C4 New Member

    Публикаций:
    0
    Регистрация:
    17 мар 2008
    Сообщения:
    1.203
    ну про strlen возможно уже писали

    xor eax, eax
    xor edx, edx
    @@:
    cmp dl, string[eax]
    inc eax
    jb @b
     
  11. Blackbeam

    Blackbeam New Member

    Публикаций:
    0
    Регистрация:
    28 дек 2008
    Сообщения:
    960
    проверяется каждый байт тупо-последовательно

    метод Монте-Карло для длинных строк пробовали?
    для такой функции нужно указывать размер памяти, отведённой под строку, однако
    в блоке памяти может быть несколько строк и если найдёт не тот конец ...
     
  12. max7C4

    max7C4 New Member

    Публикаций:
    0
    Регистрация:
    17 мар 2008
    Сообщения:
    1.203
    Blackbeam
    Это довольно простой код который можно оформить в виде макроса и вставлять где потребуется для быстрого подсчета длин коротких строк. Не будете же вы применять навороченную функцию для подсчета длин строк гарантировано меньших 4 Кб (к примеру)
     
  13. Blackbeam

    Blackbeam New Member

    Публикаций:
    0
    Регистрация:
    28 дек 2008
    Сообщения:
    960
    разумеется, но навороченная тоже нужна, уверен что она где-то есть, и значит исследовался вопрос об оптимальной стратегии поиска конца
    предлагаю проверить первый байт, на всякий случай, а потом байт на 3\4 возможной длины, а потом...?

    столкнулся с проблемой - написал довольно таки большую функцию
    если сделать макрос - компилятор просто подставит его в нужных местах и я планировал, что функция будет записана только один раз и будет вызываться по мере необходимости
    однако размер дистрибутива не изменился ...
     
  14. Rockphorr

    Rockphorr Well-Known Member

    Публикаций:
    0
    Регистрация:
    9 июн 2004
    Сообщения:
    2.622
    Адрес:
    Russia
    Mikl___
    у меня есть 16 битный аналог
    так вот оказалось полезным практически в случае разницы выдавать вместо 0 разницу между кодами символов в строках
     
  15. Y_Mur

    Y_Mur Active Member

    Публикаций:
    0
    Регистрация:
    6 сен 2006
    Сообщения:
    2.494
    Blackbeam
    Небольшие изменения размера кода могут и не сказаться на размере exe из-за выравнивания секций, а оптитимизация поиска конца строки, когда этих концов в буфере много уже бурно осуждалась.
     
  16. Blackbeam

    Blackbeam New Member

    Публикаций:
    0
    Регистрация:
    28 дек 2008
    Сообщения:
    960
    Y_Mur спасибо, поизучаю, напостили 5 страницъ...
     
  17. KIV

    KIV Member

    Публикаций:
    0
    Регистрация:
    16 июл 2009
    Сообщения:
    231
    strlen и strcmp можно и короче сделать:
    Код (Text):
    1. ; Сравниет строки из DS:SI и ES:DI
    2. str_cmp:
    3.     lodsb
    4.     test al, al
    5.     jz @f
    6.     scasb
    7.     je str_cmp
    8. @@:
    9.     ret ; На выходе можно использовать условный переход как с обычным cmp. Например je equals или jb below
    10. ; Возращает длину строки DS:SI в CX
    11. str_len:
    12.     xor al, al
    13.     mov cx, -1
    14.     repne scasb
    15.     neg cx
    16.     dec cx ; Заменить на sub cx, 2, если надо узнать длину строки без завершающего нуля
    17.     ret
    А вот ещё две полезные функции: strcpy и strcpyl:
    Код (Text):
    1. ; Копирование строки DS:SI в ES:DI
    2. strcpy:
    3.     lodsb
    4.     stosb
    5.     test al, al
    6.     jnz strcpy
    7.     ret
    8. ; Копирование строки DS:SI в ES:DI, но не более CX символов
    9. strcpyl:
    10.     lodsb
    11.     dec cx
    12.     jz @f
    13.     test al, al
    14.     jz @f
    15.     stosb
    16.     jmp strcpyl
    17. @@:
    18.     xor al, al
    19.     stosb
    20.     ret
    А функции топикстартера совсем не крошечные, а наоборот.
     
  18. max7C4

    max7C4 New Member

    Публикаций:
    0
    Регистрация:
    17 мар 2008
    Сообщения:
    1.203
    KIV
    если выбросить 16 битку и переписать для 32 бит, то
    Код (Text):
    1. xor al, al; 2 bytes
    2. mov ecx, -1;5 bytes
    3. repne scasb;2 bytes
    4. neg ecx;2 bytes
    5. dec ecx;1 bytes
    -итого 12 байт, если оптимизировать еще по размеру
    Код (Text):
    1. xor al, al; 2 bytes
    2. or ecx, -1;3 bytes
    3. repne scasb;2 bytes
    4. neg ecx;2 bytes
    5. dec ecx;1 bytes
    -итого 9 байт. минусы. должен строго использоваться регистр edi. плюсы. при переходе к unicode размер увеличивается на 1 байт. теперь мое
    Код (Text):
    1. macro strlen string, counter
    2. xor counter, counter;2 bytes
    3. xor edx, edx;2 bytes
    4. @@:
    5. cmp dl, string[counter];3 bytes if string in register else 6 bytes
    6. inc counter;1 byte
    7. jnz @b;2 bytes
    8. endm
    -итого 10 байт если указатель на строку находится в регистре и 13 байт, если используется offset32. плюсы. результат операции получается в любом из регистров позволяющем адресоваться к памяти. строка располагается в любом из регистров позволяющем адресоваться к памяти. при переходе к unicode размер увеличивается на 1 байт
     
  19. Blackbeam

    Blackbeam New Member

    Публикаций:
    0
    Регистрация:
    28 дек 2008
    Сообщения:
    960
    по ссылке у_мура задача немного другая

    задача для strlen - найти конец строки, строк в блоке памяти может быть несколько:

    пре алгоритм:

    ; в esi - указатель на первый байт строки
    ; в edi - максимальный размер строки

    @@:
    shr edi,1
    add esi,edi
    movzx eax, byte ptr [esi]
    cmp al, 0 ; это вроде можно сделать оптимальней
    jne @B ; как ограничить количество циклов? иначе Ахилл никогда не догонит черепаху. или догонит?
    ; sub esi,edi
    ; дальше не думал, 0 не дальше чем текущее esi+edi
     
  20. Blackbeam

    Blackbeam New Member

    Публикаций:
    0
    Регистрация:
    28 дек 2008
    Сообщения:
    960
    для строковых функций оптимизация по размеру не имеет особого значения, мне кажется