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.

186 lines
3.7 KiB

  1. page ,132
  2. title memchr - search memory for a given character
  3. ;***
  4. ;memchr.asm - search block of memory for a given character
  5. ;
  6. ; Copyright (c) 1985-2001, Microsoft Corporation. All rights reserved.
  7. ;
  8. ;Purpose:
  9. ; defines memchr() - search memory until a character is
  10. ; found or a limit is reached.
  11. ;
  12. ;Revision History:
  13. ; 05-16-84 RN initial version
  14. ; 07-20-87 SKS rewritten for speed
  15. ; 05-17-88 SJM Add model-independent (large model) ifdef
  16. ; 08-04-88 SJM convert to cruntime/ add 32-bit support
  17. ; 08-23-88 JCR 386 cleanup
  18. ; 10-25-88 JCR General cleanup for 386-only code
  19. ; 03-23-90 GJF Changed to _stdcall. Also, fixed the copyright.
  20. ; 05-10-91 GJF Back to _cdecl, sigh...
  21. ; 05-01-95 GJF New, faster version from Intel!
  22. ;
  23. ;*******************************************************************************
  24. .xlist
  25. include cruntime.inc
  26. .list
  27. page
  28. ;***
  29. ;char *memchr(buf, chr, cnt) - search memory for given character.
  30. ;
  31. ;Purpose:
  32. ; Searched at buf for the given character, stopping when chr is
  33. ; first found or cnt bytes have been searched through.
  34. ;
  35. ; Algorithm:
  36. ; char *
  37. ; memchr (buf, chr, cnt)
  38. ; char *buf;
  39. ; int chr;
  40. ; unsigned cnt;
  41. ; {
  42. ; while (cnt && *buf++ != c)
  43. ; cnt--;
  44. ; return(cnt ? --buf : NULL);
  45. ; }
  46. ;
  47. ;Entry:
  48. ; char *buf - memory buffer to be searched
  49. ; char chr - character to search for
  50. ; unsigned cnt - max number of bytes to search
  51. ;
  52. ;Exit:
  53. ; returns pointer to first occurence of chr in buf
  54. ; returns NULL if chr not found in the first cnt bytes
  55. ;
  56. ;Uses:
  57. ;
  58. ;Exceptions:
  59. ;
  60. ;*******************************************************************************
  61. CODESEG
  62. public memchr
  63. memchr proc
  64. .FPO ( 0, 1, 0, 0, 0, 0 )
  65. mov eax,[esp+0ch] ; eax = count
  66. push ebx ; Preserve ebx
  67. test eax,eax ; check if count=0
  68. jz short retnull ; if count=0, leave
  69. mov edx,[esp+8] ; edx = buffer
  70. xor ebx,ebx
  71. mov bl,[esp+0ch] ; bl = search char
  72. test edx,3 ; test if string is aligned on 32 bits
  73. jz short main_loop_start
  74. str_misaligned: ; simple byte loop until string is aligned
  75. mov cl,byte ptr [edx]
  76. inc edx
  77. xor cl,bl
  78. je short found
  79. dec eax ; counter--
  80. jz short retnull
  81. test edx,3 ; already aligned ?
  82. jne short str_misaligned
  83. main_loop_start:
  84. sub eax,4
  85. jb short tail_less_then_4
  86. ; set all 4 bytes of ebx to [value]
  87. push edi ; Preserve edi
  88. mov edi,ebx ; edi=0/0/0/char
  89. shl ebx,8 ; ebx=0/0/char/0
  90. add ebx,edi ; ebx=0/0/char/char
  91. mov edi,ebx ; edi=0/0/char/char
  92. shl ebx,10h ; ebx=char/char/0/0
  93. add ebx,edi ; ebx = all 4 bytes = [search char]
  94. jmp short main_loop_entry ; ecx >=0
  95. return_from_main:
  96. pop edi
  97. tail_less_then_4:
  98. add eax,4
  99. jz retnull
  100. tail_loop: ; 0 < eax < 4
  101. mov cl,byte ptr [edx]
  102. inc edx
  103. xor cl,bl
  104. je short found
  105. dec eax
  106. jnz short tail_loop
  107. retnull:
  108. pop ebx
  109. ret ; _cdecl return
  110. main_loop:
  111. sub eax,4
  112. jb short return_from_main
  113. main_loop_entry:
  114. mov ecx,dword ptr [edx] ; read 4 bytes
  115. xor ecx,ebx ; ebx is byte\byte\byte\byte
  116. mov edi,7efefeffh
  117. add edi,ecx
  118. xor ecx,-1
  119. xor ecx,edi
  120. add edx,4
  121. and ecx,81010100h
  122. je short main_loop
  123. ; found zero byte in the loop?
  124. char_is_found:
  125. mov ecx,[edx - 4]
  126. xor cl,bl ; is it byte 0
  127. je short byte_0
  128. xor ch,bl ; is it byte 1
  129. je short byte_1
  130. shr ecx,10h ; is it byte 2
  131. xor cl,bl
  132. je short byte_2
  133. xor ch,bl ; is it byte 3
  134. je short byte_3
  135. jmp short main_loop ; taken if bits 24-30 are clear and bit
  136. ; 31 is set
  137. byte_3:
  138. pop edi ; restore edi
  139. found:
  140. lea eax,[edx - 1]
  141. pop ebx ; restore ebx
  142. ret ; _cdecl return
  143. byte_2:
  144. lea eax,[edx - 2]
  145. pop edi
  146. pop ebx
  147. ret ; _cdecl return
  148. byte_1:
  149. lea eax,[edx - 3]
  150. pop edi
  151. pop ebx
  152. ret ; _cdecl return
  153. byte_0:
  154. lea eax,[edx - 4]
  155. pop edi ; restore edi
  156. pop ebx ; restore ebx
  157. ret ; _cdecl return
  158. memchr endp
  159. end