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.

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