home *** CD-ROM | disk | FTP | other *** search
/ Tricks of the Windows Gam…ming Gurus (2nd Edition) / Disc2.iso / vc98 / crt / src / platform / memcmp.asm < prev    next >
Assembly Source File  |  1998-06-17  |  5KB  |  183 lines

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