Source code of Windows XP (NT5)
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.

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