home *** CD-ROM | disk | FTP | other *** search
/ Tricks of the Windows Gam…ming Gurus (2nd Edition) / Disc2.iso / vc98 / crt / src / platform / strstr.asm < prev    next >
Assembly Source File  |  1998-06-17  |  5KB  |  169 lines

  1.         page    ,132
  2.         title   strstr - search for one string inside another
  3. ;***
  4. ;strstr.asm - search for one string inside another
  5. ;
  6. ;       Copyright (c) 1985-1997, Microsoft Corporation. All rights reserved.
  7. ;
  8. ;Purpose:
  9. ;       defines strstr() - search for one string inside another
  10. ;
  11. ;*******************************************************************************
  12.  
  13.         .xlist
  14.         include cruntime.inc
  15.         .list
  16.  
  17. page
  18. ;***
  19. ;char *strstr(str1, str2) - search for str2 in str1
  20. ;
  21. ;Purpose:
  22. ;       finds the first occurrence of str2 in str1
  23. ;
  24. ;Entry:
  25. ;       char *str1 - string to search in
  26. ;       char *str2 - string to search for
  27. ;
  28. ;Exit:
  29. ;       returns a pointer to the first occurrence of string2 in
  30. ;       string1, or NULL if string2 does not occur in string1
  31. ;
  32. ;Uses:
  33. ;
  34. ;Exceptions:
  35. ;
  36. ;*******************************************************************************
  37.  
  38.  
  39. __from_strstr_to_strchr proto
  40.  
  41.         CODESEG
  42.  
  43.         public  strstr
  44.  
  45. strstr  proc
  46.  
  47.         mov     ecx,[esp + 8]       ; str2 (the string to be searched for)
  48.  
  49.         push    edi                 ; Preserve edi, ebx and esi
  50.         push    ebx
  51.         push    esi
  52.  
  53.         mov     dl,[ecx]            ; dl contains first char from str2
  54.  
  55.         mov     edi,[esp + 10h]     ; str1 (the string to be searched)
  56.  
  57.         test    dl,dl               ; is str2 empty?
  58.         jz      empty_str2
  59.  
  60.         mov     dh,[ecx + 1]        ; second char from str2
  61.         test    dh,dh               ; is str2 a one-character string?
  62.         jz      strchr_call         ; if so, go use strchr code
  63.  
  64. ; length of str2 is now known to be > 1 (used later)
  65. ; dl contains first char from str2
  66. ; dh contains second char from str2
  67. ; edi holds str1
  68.  
  69. findnext:
  70.         mov     esi,edi             ; esi = edi = pointers to somewhere in str1
  71.         mov     ecx,[esp + 14h]     ; str2
  72.  
  73. ;use edi instead of esi to eliminate AGI
  74.         mov     al,[edi]            ; al is next char from str1
  75.  
  76.         inc     esi                 ; increment pointer into str1
  77.  
  78.         cmp     al,dl
  79.         je      first_char_found
  80.  
  81.         test    al,al               ; end of str1?
  82.         jz      not_found           ; yes, and no match has been found
  83.  
  84. loop_start:
  85.         mov     al,[esi]            ; put next char from str1 into al
  86.         inc     esi                 ; increment pointer in str1
  87. in_loop:
  88.         cmp     al,dl
  89.         je      first_char_found
  90.  
  91.         test    al,al               ; end of str1?
  92.         jnz     loop_start          ; no, go get another char from str1
  93.  
  94. not_found:
  95.         pop     esi
  96.         pop     ebx
  97.         pop     edi
  98.         xor     eax,eax
  99.         ret
  100.  
  101. ; recall that dh contains the second char from str2
  102.  
  103. first_char_found:
  104.         mov     al,[esi]            ; put next char from str1 into al
  105.         inc     esi
  106.  
  107.         cmp     al,dh               ; compare second chars
  108.         jnz     in_loop             ; no match, continue search
  109.  
  110. two_first_chars_equal:
  111.         lea     edi,[esi - 1]       ; store position of last read char in str1
  112.  
  113. compare_loop:
  114.         mov     ah,[ecx + 2]        ; put next char from str2 into ah
  115.         test    ah,ah               ; end of str2?
  116.         jz      match               ; if so, then a match has been found
  117.  
  118.         mov     al,[esi]            ; get next char from str1
  119.         add     esi,2               ; bump pointer into str1 by 2
  120.  
  121.         cmp     al,ah               ; are chars from str1 and str2 equal?
  122.         jne     findnext            ; no
  123.  
  124. ; do one more iteration
  125.  
  126.         mov     al,[ecx + 3]        ; put the next char from str2 into al
  127.         test    al,al               ; end of str2
  128.         jz      match               ; if so, then a match has been found
  129.  
  130.         mov     ah,[esi - 1]        ; get next char from str1
  131.         add     ecx,2               ; bump pointer in str1 by 2
  132.         cmp     al,ah               ; are chars from str1 and str2 equal?
  133.         je      compare_loop
  134.  
  135. ; no match. test some more chars (to improve execution time for bad strings).
  136.  
  137.         jmp     findnext
  138.  
  139. ; str2 string contains only one character so it's like the strchr functioin
  140.  
  141. strchr_call:
  142.         xor     eax,eax
  143.         pop     esi
  144.         pop     ebx
  145.         pop     edi
  146.         mov     al,dl
  147.         jmp     __from_strstr_to_strchr
  148.  
  149. ;
  150. ;
  151. ; Match!  Return (ebx - 1)
  152. ;
  153. match:
  154.         lea     eax,[edi - 1]
  155.         pop     esi
  156.         pop     ebx
  157.         pop     edi
  158.         ret
  159.  
  160. empty_str2:           ; empty target string, return src (ANSI mandated)
  161.         mov     eax,edi
  162.         pop     esi
  163.         pop     ebx
  164.         pop     edi
  165.         ret
  166.  
  167. strstr  endp
  168.         end
  169.