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.

197 lines
4.6 KiB

  1. page ,132
  2. title memcmp - compare to blocks of memory
  3. ;***
  4. ;memcmp.asm - compare two blocks of memory
  5. ;
  6. ; Copyright (c) 1985-2001, Microsoft Corporation. All rights reserved.
  7. ;
  8. ;Purpose:
  9. ; defines memcmp() - compare two memory blocks lexically and
  10. ; find their order.
  11. ;
  12. ;Revision History:
  13. ; 05-16-83 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. ; 05-09-95 GJF Replaced a bad ret with a good jz retnull (my editing
  23. ; error, not Intel's).
  24. ; 11-06-95 GJF Corrected order in which esi and edi are saved.
  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. ;int memcmp(buf1, buf2, count) - compare memory for lexical order
  34. ;
  35. ;Purpose:
  36. ; Compares count bytes of memory starting at buf1 and buf2
  37. ; and find if equal or which one is first in lexical order.
  38. ;
  39. ; Algorithm:
  40. ; int
  41. ; memcmp (buf1, buf2, count)
  42. ; char *buf1, *buf2;
  43. ; unsigned count;
  44. ; {
  45. ; if (!count)
  46. ; return(0);
  47. ; while (--count && *buf1 == *buf2)
  48. ; {
  49. ; buf1++;
  50. ; buf2++;
  51. ; }
  52. ; return(*buf1 - *buf2);
  53. ; }
  54. ;
  55. ;Entry:
  56. ; char *buf1, *buf2 - pointers to memory sections to compare
  57. ; unsigned count - length of sections to compare
  58. ;
  59. ;Exit:
  60. ; returns -1 if buf1 < buf2
  61. ; returns 0 if buf1 == buf2
  62. ; returns +1 if buf1 > buf2
  63. ;
  64. ;Uses:
  65. ;
  66. ;Exceptions:
  67. ;
  68. ;*******************************************************************************
  69. CODESEG
  70. public memcmp
  71. memcmp proc
  72. .FPO ( 0, 3, 0, 0, 0, 0 )
  73. mov eax,[esp+0ch] ; eax = counter
  74. test eax,eax ; test if counter is zero
  75. jz short retnull ; return 0
  76. mov edx,[esp+4] ; edx = buf1
  77. push esi
  78. push edi
  79. mov esi,edx ; esi = buf1
  80. mov edi,[esp+10h] ; edi = buf2
  81. ; Check for dword (32 bit) alignment
  82. or edx,edi
  83. and edx,3 ; edx=0 iff buf1 are buf2 are aligned
  84. jz short dwords
  85. ; Strings are not aligned. If the caller knows the strings (buf1 and buf2) are
  86. ; different, the function may be called with length like -1. The difference
  87. ; may be found in the last dword of aligned string, and because the other
  88. ; string is misaligned it may cause page fault. So, to be safe. the comparison
  89. ; must be done byte by byte.
  90. test eax,1
  91. jz short main_loop
  92. mov cl,[esi]
  93. cmp cl,[edi]
  94. jne short not_equal
  95. add esi,1
  96. add edi,1
  97. sub eax,1
  98. jz short done ; eax is already 0
  99. main_loop:
  100. mov cl,[esi]
  101. mov dl,[edi]
  102. cmp cl,dl
  103. jne short not_equal
  104. mov cl,[esi+1]
  105. mov dl,[edi+1]
  106. cmp cl,dl
  107. jne short not_equal
  108. add edi,2
  109. add esi,2
  110. sub eax,2
  111. jnz short main_loop
  112. done:
  113. pop edi
  114. pop esi
  115. retnull:
  116. ret ; _cdecl return
  117. dwords:
  118. mov ecx,eax
  119. and eax,3 ; eax= counter for tail loop
  120. shr ecx,2
  121. jz short tail_loop_start
  122. ; counter was >=4 so may check one dword
  123. rep cmpsd
  124. jz short tail_loop_start
  125. ; in last dword was difference
  126. mov ecx,[esi-4] ; load last dword from buf1 to ecx
  127. mov edx,[edi-4] ; load last dword from buf2 to edx
  128. cmp cl,dl ; test first bytes
  129. jne short difference_in_tail
  130. cmp ch,dh ; test seconds bytes
  131. jne short difference_in_tail
  132. shr ecx,10h
  133. shr edx,10h
  134. cmp cl,dl ; test third bytes
  135. jne short difference_in_tail
  136. cmp ch,dh ; they are different, but each one is bigger?
  137. ; jmp short difference_in_tail
  138. difference_in_tail:
  139. mov eax,0
  140. ; buf1 < buf2 buf1 > buf2
  141. not_equal:
  142. sbb eax,eax ; AX=-1, CY=1 AX=0, CY=0
  143. pop edi ; counter
  144. sbb eax,-1 ; AX=-1 AX=1
  145. pop esi
  146. ret ; _cdecl return
  147. ; in tail loop we test last three bytes (esi and edi are aligned on dword
  148. ; boundary)
  149. tail_loop_start:
  150. test eax,eax ; eax is counter%4 (number of bytes for tail
  151. ; loop)
  152. jz short done ; taken if there is no tail bytes
  153. mov edx,[esi] ; load dword from buf1
  154. mov ecx,[edi] ; load dword from buf2
  155. cmp dl,cl ; test first bytes
  156. jne short difference_in_tail
  157. sub eax,1 ; counter--
  158. jz short tail_done
  159. cmp dh,ch ; test second bytes
  160. jne short difference_in_tail
  161. sub eax,1 ; counter--
  162. jz short tail_done
  163. and ecx,00ff0000h ; test third bytes
  164. and edx,00ff0000h
  165. cmp edx,ecx
  166. jne short difference_in_tail
  167. sub eax,1
  168. tail_done:
  169. pop edi
  170. pop esi
  171. ret ; _cdecl return
  172. memcmp endp
  173. end