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.

199 lines
6.0 KiB

  1. page ,132
  2. title strchr - search string for given character
  3. ;***
  4. ;strchr.asm - search a string for a given character
  5. ;
  6. ; Copyright (c) 1985-2001, Microsoft Corporation. All rights reserved.
  7. ;
  8. ;Purpose:
  9. ; defines strchr() - search a string for a character
  10. ;
  11. ;Revision History:
  12. ; 10-27-83 RN initial version
  13. ; 05-17-88 SJM Add model-independent (large model) ifdef
  14. ; 08-04-88 SJM convert to cruntime/ add 32-bit support
  15. ; 08-23-88 JCR 386 cleanup
  16. ; 10-25-88 JCR General cleanup for 386-only code
  17. ; 03-23-90 GJF Changed to _stdcall. Also, fixed the copyright.
  18. ; 05-10-91 GJF Back to _cdecl, sigh...
  19. ; 09-08-94 GJF Smaller and faster.
  20. ; 11-28-95 GJF Much faster version from Intel.
  21. ;
  22. ;*******************************************************************************
  23. .xlist
  24. include cruntime.inc
  25. .list
  26. page
  27. ;***
  28. ;char *strchr(string, chr) - search a string for a character
  29. ;
  30. ;Purpose:
  31. ; Searches a string for a given character, which may be the
  32. ; null character '\0'.
  33. ;
  34. ; Algorithm:
  35. ; char *
  36. ; strchr (string, chr)
  37. ; char *string, chr;
  38. ; {
  39. ; while (*string && *string != chr)
  40. ; string++;
  41. ; if (*string == chr)
  42. ; return(string);
  43. ; return((char *)0);
  44. ; }
  45. ;
  46. ;Entry:
  47. ; char *string - string to search in
  48. ; char chr - character to search for
  49. ;
  50. ;Exit:
  51. ; returns pointer to the first occurence of c in string
  52. ; returns NULL if chr does not occur in string
  53. ;
  54. ;Uses:
  55. ;
  56. ;Exceptions:
  57. ;
  58. ;*******************************************************************************
  59. CODESEG
  60. found_bx:
  61. lea eax,[edx - 1]
  62. pop ebx ; restore ebx
  63. ret ; _cdecl return
  64. align 16
  65. public strchr, __from_strstr_to_strchr
  66. strchr proc
  67. .FPO ( 0, 2, 0, 0, 0, 0 )
  68. xor eax,eax
  69. mov al,[esp + 8] ; al = chr (search char)
  70. __from_strstr_to_strchr label proc
  71. push ebx ; PRESERVE EBX
  72. mov ebx,eax ; ebx = 0/0/0/chr
  73. shl eax,8 ; eax = 0/0/chr/0
  74. mov edx,[esp + 8] ; edx = buffer
  75. test edx,3 ; test if string is aligned on 32 bits
  76. jz short main_loop_start
  77. str_misaligned: ; simple byte loop until string is aligned
  78. mov cl,[edx]
  79. inc edx
  80. cmp cl,bl
  81. je short found_bx
  82. test cl,cl
  83. jz short retnull_bx
  84. test edx,3 ; now aligned ?
  85. jne short str_misaligned
  86. main_loop_start: ; set all 4 bytes of ebx to [chr]
  87. or ebx,eax ; ebx = 0/0/chr/chr
  88. push edi ; PRESERVE EDI
  89. mov eax,ebx ; eax = 0/0/chr/chr
  90. shl ebx,10h ; ebx = chr/chr/0/0
  91. push esi ; PRESERVE ESI
  92. or ebx,eax ; ebx = all 4 bytes = [chr]
  93. ; in the main loop (below), we are looking for chr or for EOS (end of string)
  94. main_loop:
  95. mov ecx,[edx] ; read dword (4 bytes)
  96. mov edi,7efefeffh ; work with edi & ecx for looking for chr
  97. mov eax,ecx ; eax = dword
  98. mov esi,edi ; work with esi & eax for looking for EOS
  99. xor ecx,ebx ; eax = dword xor chr/chr/chr/chr
  100. add esi,eax
  101. add edi,ecx
  102. xor ecx,-1
  103. xor eax,-1
  104. xor ecx,edi
  105. xor eax,esi
  106. add edx,4
  107. and ecx,81010100h ; test for chr
  108. jnz short chr_is_found ; chr probably has been found
  109. ; chr was not found, check for EOS
  110. and eax,81010100h ; is any flag set ??
  111. jz short main_loop ; EOS was not found, go get another dword
  112. and eax,01010100h ; is it in high byte?
  113. jnz short retnull ; no, definitely found EOS, return failure
  114. and esi,80000000h ; check was high byte 0 or 80h
  115. jnz short main_loop ; it just was 80h in high byte, go get
  116. ; another dword
  117. retnull:
  118. pop esi
  119. pop edi
  120. retnull_bx:
  121. pop ebx
  122. xor eax,eax
  123. ret ; _cdecl return
  124. chr_is_found:
  125. mov eax,[edx - 4] ; let's look one more time on this dword
  126. cmp al,bl ; is chr in byte 0?
  127. je short byte_0
  128. test al,al ; test if low byte is 0
  129. je retnull
  130. cmp ah,bl ; is it byte 1
  131. je short byte_1
  132. test ah,ah ; found EOS ?
  133. je retnull
  134. shr eax,10h ; is it byte 2
  135. cmp al,bl
  136. je short byte_2
  137. test al,al ; if in al some bits were set, bl!=bh
  138. je retnull
  139. cmp ah,bl
  140. je short byte_3
  141. test ah,ah
  142. jz retnull
  143. jmp short main_loop ; neither chr nor EOS found, go get
  144. ; another dword
  145. byte_3:
  146. pop esi
  147. pop edi
  148. lea eax,[edx - 1]
  149. pop ebx ; restore ebx
  150. ret ; _cdecl return
  151. byte_2:
  152. lea eax,[edx - 2]
  153. pop esi
  154. pop edi
  155. pop ebx
  156. ret ; _cdecl return
  157. byte_1:
  158. lea eax,[edx - 3]
  159. pop esi
  160. pop edi
  161. pop ebx
  162. ret ; _cdecl return
  163. byte_0:
  164. lea eax,[edx - 4]
  165. pop esi ; restore esi
  166. pop edi ; restore edi
  167. pop ebx ; restore ebx
  168. ret ; _cdecl return
  169. strchr endp
  170. end