ПОЖЖАЛУЙСТА! Разъясните страшную функцию... (strstr)
От: Последний Чайник Россия  
Дата: 01.10.03 11:09
Оценка:
Вообще-то, я пишу под MFC, но мне хотелось узнать алгоритм, который использует метод CString::Find. Воспользовавшись автотрассировкой я дошла до этого (внизу) ужаса:



        title   strstr - search for one string inside another
;***
;strstr.asm - search for one string inside another
;
;       Copyright (c) 1985-1997, Microsoft Corporation. All rights reserved.
;
;Purpose:
;       defines strstr() - search for one string inside another
;
;*******************************************************************************

        .xlist
        include cruntime.inc
        .list

page
;***
;char *strstr(str1, str2) - search for str2 in str1
;
;Purpose:
;       finds the first occurrence of str2 in str1
;
;Entry:
;       char *str1 - string to search in
;       char *str2 - string to search for
;
;Exit:
;       returns a pointer to the first occurrence of string2 in
;       string1, or NULL if string2 does not occur in string1
;
;Uses:
;
;Exceptions:
;
;*******************************************************************************


__from_strstr_to_strchr proto

        CODESEG

        public  strstr

strstr  proc

        mov     ecx,[esp + 8]       ; str2 (the string to be searched for)

        push    edi                 ; Preserve edi, ebx and esi
        push    ebx
        push    esi

        mov     dl,[ecx]            ; dl contains first char from str2

        mov     edi,[esp + 10h]     ; str1 (the string to be searched)

        test    dl,dl               ; is str2 empty?
        jz      empty_str2

        mov     dh,[ecx + 1]        ; second char from str2
        test    dh,dh               ; is str2 a one-character string?
        jz      strchr_call         ; if so, go use strchr code

; length of str2 is now known to be > 1 (used later)
; dl contains first char from str2
; dh contains second char from str2
; edi holds str1

findnext:
        mov     esi,edi             ; esi = edi = pointers to somewhere in str1
        mov     ecx,[esp + 14h]     ; str2

;use edi instead of esi to eliminate AGI
        mov     al,[edi]            ; al is next char from str1

        inc     esi                 ; increment pointer into str1

        cmp     al,dl
        je      first_char_found

        test    al,al               ; end of str1?
        jz      not_found           ; yes, and no match has been found

loop_start:
        mov     al,[esi]            ; put next char from str1 into al
        inc     esi                 ; increment pointer in str1
in_loop:
        cmp     al,dl
        je      first_char_found

        test    al,al               ; end of str1?
        jnz     loop_start          ; no, go get another char from str1

not_found:
        pop     esi
        pop     ebx
        pop     edi
        xor     eax,eax
        ret

; recall that dh contains the second char from str2

first_char_found:
        mov     al,[esi]            ; put next char from str1 into al
        inc     esi

        cmp     al,dh               ; compare second chars
        jnz     in_loop             ; no match, continue search

two_first_chars_equal:
        lea     edi,[esi - 1]       ; store position of last read char in str1

compare_loop:
        mov     ah,[ecx + 2]        ; put next char from str2 into ah
        test    ah,ah               ; end of str2?
        jz      match               ; if so, then a match has been found

        mov     al,[esi]            ; get next char from str1
        add     esi,2               ; bump pointer into str1 by 2

        cmp     al,ah               ; are chars from str1 and str2 equal?
        jne     findnext            ; no

; do one more iteration

        mov     al,[ecx + 3]        ; put the next char from str2 into al
        test    al,al               ; end of str2
        jz      match               ; if so, then a match has been found

        mov     ah,[esi - 1]        ; get next char from str1
        add     ecx,2               ; bump pointer in str1 by 2
        cmp     al,ah               ; are chars from str1 and str2 equal?
        je      compare_loop

; no match. test some more chars (to improve execution time for bad strings).

        jmp     findnext

; str2 string contains only one character so it's like the strchr functioin

strchr_call:
        xor     eax,eax
        pop     esi
        pop     ebx
        pop     edi
        mov     al,dl
        jmp     __from_strstr_to_strchr

;
;
; Match!  Return (ebx - 1)
;
match:
        lea     eax,[edi - 1]
        pop     esi
        pop     ebx
        pop     edi
        ret

empty_str2:           ; empty target string, return src (ANSI mandated)
        mov     eax,edi
        pop     esi
        pop     ebx
        pop     edi
        ret

strstr  endp
        end


С ассемблером я не знакома. Все, что мне требуется знать — выполняет ли мой "ужас" простой поиск (т.е. сдвиг = 1 символ при любом несовпадении искомой подстроки с той, в которой ищут) или нет. Будьте добры, подскажите!!! Благодарю заранее
Re: ПОЖЖАЛУЙСТА! Разъясните страшную функцию... (strstr)
От: Valerio Россия linkedin.com/in/boronin
Дата: 01.10.03 11:13
Оценка: :)
Здравствуйте, Последний Чайник, Вы писали:

ПЧ>Вообще-то, я пишу под MFC, но мне хотелось узнать алгоритм, который использует метод CString::Find. Воспользовавшись автотрассировкой я дошла до этого (внизу) ужаса:

наверное проще указать путь до исходников MFC и посмотреть не на этот страшный ассемблерный код?
... << RSDN@Home 1.1 beta 2 >>
Valery A. Boronin, RSDN Team, linkedin.com\in\boronin
R&D Mgmt & Security. AppSec & SDL. Data Protection and Systems Programming. FDE, DLP, Incident Management. Windows Filesystems and Drivers.
Re: ПОЖЖАЛУЙСТА! Разъясните страшную функцию... (strstr)
От: IPv6 Казахстан  
Дата: 01.10.03 11:27
Оценка: 2 (1)
Здравствуйте, Последний Чайник, Вы писали:

ПЧ>Вообще-то, я пишу под MFC, но мне хотелось узнать алгоритм, который использует метод CString::Find. Воспользовавшись автотрассировкой я дошла до этого (внизу) ужаса:



ПЧ>

ПЧ>strstr  endp
***
ПЧ>        end
ПЧ>


ПЧ>С ассемблером я не знакома. Все, что мне требуется знать — выполняет ли мой "ужас" простой поиск (т.е. сдвиг = 1 символ при любом несовпадении искомой подстроки с той, в которой ищут) или нет. Будьте добры, подскажите!!! Благодарю заранее


выполняет. если справа один символ то поиск идет по урощенной схеме (strchr), если не один то ищется первый сивол, после него смотрится второй символ, если совпало то проверка продолжается, если нет — дальнейший поиск первого символа
а нафига все это надо?
Re[2]: ПОЖЖАЛУЙСТА! Разъясните страшную функцию... (strstr)
От: Последний Чайник Россия  
Дата: 01.10.03 11:47
Оценка:
Здравствуйте, Valerio, Вы писали:

V>наверное проще указать путь до исходников MFC и посмотреть не на этот страшный ассемблерный код?


Со-огласна! Пишу: vc98\mfc\strex.cpp. Только он не ищет, а зовет tchar.h, этот — mbssr.c, а последний в свою очередь содержит незабвенную строку return strstr(str1, str2). А вот "ужас" — это последний в цепочке strstr.asm.
Re[2]: ПОЖЖАЛУЙСТА! Разъясните страшную функцию... (strstr)
От: Последний Чайник Россия  
Дата: 01.10.03 11:51
Оценка:
Здравствуйте, IPv6, Вы писали:

IP>выполняет. если справа один символ то поиск идет по урощенной схеме (strchr), если не один то ищется первый сивол...

IP>а нафига все это надо?
Очень важно было. Спаисбо большое!
P.S. А что такое упрощенная схема (Бойер-Мур?)
Re[3]: ПОЖЖАЛУЙСТА! Разъясните страшную функцию... (strstr)
От: Andrew S Россия http://alchemy-lab.com
Дата: 01.10.03 13:49
Оценка:
Мдя. Печально как все. А заглянуть в статьи на сайте лень?
http://www.rsdn.ru/?article/alg/textsearch.xml
Автор(ы): Андрей Боровский
Дата: 28.01.2002


ПЧ>P.S. А что такое упрощенная схема (Бойер-Мур?)
http://www.rusyaz.ru/pr — стараемся писАть по-русски
 
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.