Leaked source code of windows server 2003
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

184 lines
5.6 KiB

  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-2001, Microsoft Corporation. All rights reserved.
  7. ;
  8. ;Purpose:
  9. ; defines strstr() - search for one string inside another
  10. ;
  11. ;Revision History:
  12. ; 02-02-88 SKS Rewritten from scratch. Now works correctly with
  13. ; strings > 32 KB in length. Also smaller and faster.
  14. ; 03-01-88 SKS Ensure that ES = DS right away (Small/Medium models)
  15. ; 05-18-88 SJM Add model-independent (large model) ifdef
  16. ; 08-04-88 SJM convert to cruntime/ add 32-bit support
  17. ; 08-18-88 PHG Corrected return value when src is empty string
  18. ; to conform with ANSI.
  19. ; 08-23-88 JCR Minor 386 cleanup
  20. ; 10-26-88 JCR General cleanup for 386-only code
  21. ; 03-26-90 GJF Changed to _stdcall. Also, fixed the copyright.
  22. ; 05-10-91 GJF Back to _cdecl, sigh...
  23. ; 12-19-94 GJF Revised to improve performance a bit.
  24. ; 12-04-95 GJF Much faster version from Intel.
  25. ; 06-12-01 PML inc->add 1, dec->sub 1 for Pentium 4 perf (vs7#267015)
  26. ;
  27. ;*******************************************************************************
  28. .xlist
  29. include cruntime.inc
  30. .list
  31. page
  32. ;***
  33. ;char *strstr(str1, str2) - search for str2 in str1
  34. ;
  35. ;Purpose:
  36. ; finds the first occurrence of str2 in str1
  37. ;
  38. ;Entry:
  39. ; char *str1 - string to search in
  40. ; char *str2 - string to search for
  41. ;
  42. ;Exit:
  43. ; returns a pointer to the first occurrence of string2 in
  44. ; string1, or NULL if string2 does not occur in string1
  45. ;
  46. ;Uses:
  47. ;
  48. ;Exceptions:
  49. ;
  50. ;*******************************************************************************
  51. __from_strstr_to_strchr proto
  52. CODESEG
  53. public strstr
  54. strstr proc
  55. mov ecx,[esp + 8] ; str2 (the string to be searched for)
  56. push edi ; Preserve edi, ebx and esi
  57. push ebx
  58. push esi
  59. mov dl,[ecx] ; dl contains first char from str2
  60. mov edi,[esp + 10h] ; str1 (the string to be searched)
  61. test dl,dl ; is str2 empty?
  62. jz empty_str2
  63. mov dh,[ecx + 1] ; second char from str2
  64. test dh,dh ; is str2 a one-character string?
  65. jz strchr_call ; if so, go use strchr code
  66. ; length of str2 is now known to be > 1 (used later)
  67. ; dl contains first char from str2
  68. ; dh contains second char from str2
  69. ; edi holds str1
  70. findnext:
  71. mov esi,edi ; esi = edi = pointers to somewhere in str1
  72. mov ecx,[esp + 14h] ; str2
  73. ;use edi instead of esi to eliminate AGI
  74. mov al,[edi] ; al is next char from str1
  75. add esi,1 ; increment pointer into str1
  76. cmp al,dl
  77. je first_char_found
  78. test al,al ; end of str1?
  79. jz not_found ; yes, and no match has been found
  80. loop_start:
  81. mov al,[esi] ; put next char from str1 into al
  82. add esi,1 ; increment pointer in str1
  83. in_loop:
  84. cmp al,dl
  85. je first_char_found
  86. test al,al ; end of str1?
  87. jnz loop_start ; no, go get another char from str1
  88. not_found:
  89. pop esi
  90. pop ebx
  91. pop edi
  92. xor eax,eax
  93. ret
  94. ; recall that dh contains the second char from str2
  95. first_char_found:
  96. mov al,[esi] ; put next char from str1 into al
  97. add esi,1
  98. cmp al,dh ; compare second chars
  99. jnz in_loop ; no match, continue search
  100. two_first_chars_equal:
  101. lea edi,[esi - 1] ; store position of last read char in str1
  102. compare_loop:
  103. mov ah,[ecx + 2] ; put next char from str2 into ah
  104. test ah,ah ; end of str2?
  105. jz match ; if so, then a match has been found
  106. mov al,[esi] ; get next char from str1
  107. add esi,2 ; bump pointer into str1 by 2
  108. cmp al,ah ; are chars from str1 and str2 equal?
  109. jne findnext ; no
  110. ; do one more iteration
  111. mov al,[ecx + 3] ; put the next char from str2 into al
  112. test al,al ; end of str2
  113. jz match ; if so, then a match has been found
  114. mov ah,[esi - 1] ; get next char from str1
  115. add ecx,2 ; bump pointer in str1 by 2
  116. cmp al,ah ; are chars from str1 and str2 equal?
  117. je compare_loop
  118. ; no match. test some more chars (to improve execution time for bad strings).
  119. jmp findnext
  120. ; str2 string contains only one character so it's like the strchr functioin
  121. strchr_call:
  122. xor eax,eax
  123. pop esi
  124. pop ebx
  125. pop edi
  126. mov al,dl
  127. jmp __from_strstr_to_strchr
  128. ;
  129. ;
  130. ; Match! Return (ebx - 1)
  131. ;
  132. match:
  133. lea eax,[edi - 1]
  134. pop esi
  135. pop ebx
  136. pop edi
  137. ret
  138. empty_str2: ; empty target string, return src (ANSI mandated)
  139. mov eax,edi
  140. pop esi
  141. pop ebx
  142. pop edi
  143. ret
  144. strstr endp
  145. end