аналог Си-шной функции srtcmp. Возвращает 0 если строки равны, -1 если первая строка меньше второй и 1 если первая строка больше второй Код (Text): .data string1 db 'мама мыла Раму',0 string2 db 'мама мыла Кришну',0 .code start: mov esi,offset string1 mov edi,offset string2 call strcmp mov esi,offset string2 mov edi,offset string1 call strcmp mov esi,offset string1 mov edi,offset string1 call strcmp . . . strcmp proc @@: lodsd;mov eax,[esi] esi+=4 scasb;cmp al,[edi] edi++ jnz short a3 or al,al jz short @f xchg ah,al scasb;cmp al,[edi] edi++ jnz short a3 or al,al jz short @f shr eax,10h scasb;cmp al,[edi] edi++ jnz short a3 or al,al jz short @f xchg ah,al scasb;cmp ah,[edi] edi++ jnz short a3 or al,al jnz short @b @@: xor eax,eax retn a3: sbb eax,eax or al,1 retn strcmp endp
Blackbeam Огласите весь список, пожалуйста (с) С радостью, но хотелось бы уточнить с чем разобраться?
для начала все функции, которые могут пригодиться в работе со строками полезно для изучаюсчих програмирование и вообще... это больше похоже на програмирование, чем то, что им сейчас считают
Blackbeam И всё-таки хотелось бы уточнить: strcat, strlen, strcpy,...? C MMX, SSE, ...? по скорсти, по компактности?
не надо ммх и ссе компактность особого значения не имеет, обычно хорошо бы сделать библиотеку типа масм32либ, с комментариями на великом и могучем =============== ( а может ктонить перевести комментарии в масм32либ и написать справочник по ней? )
Blackbeam Масм32либ в большинстве случаев следует изучать только в качестве примера как _не_ надо программировать на асме Так что лучше осваивай mmx/sse и приёмы низкоуровневой оптимизации
проверяется каждый байт тупо-последовательно метод Монте-Карло для длинных строк пробовали? для такой функции нужно указывать размер памяти, отведённой под строку, однако в блоке памяти может быть несколько строк и если найдёт не тот конец ...
Blackbeam Это довольно простой код который можно оформить в виде макроса и вставлять где потребуется для быстрого подсчета длин коротких строк. Не будете же вы применять навороченную функцию для подсчета длин строк гарантировано меньших 4 Кб (к примеру)
разумеется, но навороченная тоже нужна, уверен что она где-то есть, и значит исследовался вопрос об оптимальной стратегии поиска конца предлагаю проверить первый байт, на всякий случай, а потом байт на 3\4 возможной длины, а потом...? столкнулся с проблемой - написал довольно таки большую функцию если сделать макрос - компилятор просто подставит его в нужных местах и я планировал, что функция будет записана только один раз и будет вызываться по мере необходимости однако размер дистрибутива не изменился ...
Mikl___ у меня есть 16 битный аналог так вот оказалось полезным практически в случае разницы выдавать вместо 0 разницу между кодами символов в строках
Blackbeam Небольшие изменения размера кода могут и не сказаться на размере exe из-за выравнивания секций, а оптитимизация поиска конца строки, когда этих концов в буфере много уже бурно осуждалась.
strlen и strcmp можно и короче сделать: Код (Text): ; Сравниет строки из DS:SI и ES:DI str_cmp: lodsb test al, al jz @f scasb je str_cmp @@: ret ; На выходе можно использовать условный переход как с обычным cmp. Например je equals или jb below ; Возращает длину строки DS:SI в CX str_len: xor al, al mov cx, -1 repne scasb neg cx dec cx ; Заменить на sub cx, 2, если надо узнать длину строки без завершающего нуля ret А вот ещё две полезные функции: strcpy и strcpyl: Код (Text): ; Копирование строки DS:SI в ES:DI strcpy: lodsb stosb test al, al jnz strcpy ret ; Копирование строки DS:SI в ES:DI, но не более CX символов strcpyl: lodsb dec cx jz @f test al, al jz @f stosb jmp strcpyl @@: xor al, al stosb ret А функции топикстартера совсем не крошечные, а наоборот.
KIV если выбросить 16 битку и переписать для 32 бит, то Код (Text): xor al, al; 2 bytes mov ecx, -1;5 bytes repne scasb;2 bytes neg ecx;2 bytes dec ecx;1 bytes -итого 12 байт, если оптимизировать еще по размеру Код (Text): xor al, al; 2 bytes or ecx, -1;3 bytes repne scasb;2 bytes neg ecx;2 bytes dec ecx;1 bytes -итого 9 байт. минусы. должен строго использоваться регистр edi. плюсы. при переходе к unicode размер увеличивается на 1 байт. теперь мое Код (Text): macro strlen string, counter xor counter, counter;2 bytes xor edx, edx;2 bytes @@: cmp dl, string[counter];3 bytes if string in register else 6 bytes inc counter;1 byte jnz @b;2 bytes endm -итого 10 байт если указатель на строку находится в регистре и 13 байт, если используется offset32. плюсы. результат операции получается в любом из регистров позволяющем адресоваться к памяти. строка располагается в любом из регистров позволяющем адресоваться к памяти. при переходе к unicode размер увеличивается на 1 байт
по ссылке у_мура задача немного другая задача для 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