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

  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-1997, 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. ;*******************************************************************************
  13.  
  14.         .xlist
  15.         include cruntime.inc
  16.         .list
  17.  
  18. page
  19. ;***
  20. ;char *memchr(buf, chr, cnt) - search memory for given character.
  21. ;
  22. ;Purpose:
  23. ;       Searched at buf for the given character, stopping when chr is
  24. ;       first found or cnt bytes have been searched through.
  25. ;
  26. ;       Algorithm:
  27. ;       char *
  28. ;       memchr (buf, chr, cnt)
  29. ;               char *buf;
  30. ;               int chr;
  31. ;               unsigned cnt;
  32. ;       {
  33. ;               while (cnt && *buf++ != c)
  34. ;                       cnt--;
  35. ;               return(cnt ? --buf : NULL);
  36. ;       }
  37. ;
  38. ;Entry:
  39. ;       char *buf - memory buffer to be searched
  40. ;       char chr - character to search for
  41. ;       unsigned cnt - max number of bytes to search
  42. ;
  43. ;Exit:
  44. ;       returns pointer to first occurence of chr in buf
  45. ;       returns NULL if chr not found in the first cnt bytes
  46. ;
  47. ;Uses:
  48. ;
  49. ;Exceptions:
  50. ;
  51. ;*******************************************************************************
  52.  
  53.         CODESEG
  54.  
  55.         public  memchr
  56. memchr  proc
  57.  
  58.         .FPO    ( 0, 1, 0, 0, 0, 0 )
  59.  
  60.         mov     eax,[esp+0ch]   ; eax = count
  61.         push    ebx             ; Preserve ebx
  62.  
  63.         test    eax,eax         ; check if count=0
  64.         jz      short retnull   ; if count=0, leave
  65.  
  66.         mov     edx,[esp+8]     ; edx = buffer
  67.         xor     ebx,ebx
  68.  
  69.         mov     bl,[esp+0ch]    ; bl = search char
  70.  
  71.         test    edx,3           ; test if string is aligned on 32 bits
  72.         jz      short main_loop_start
  73.  
  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.  
  84. main_loop_start:
  85.         sub     eax,4
  86.         jb      short tail_less_then_4
  87.  
  88. ; set all 4 bytes of ebx to [value]
  89.         push    edi             ; Preserve edi
  90.         mov     edi,ebx         ; edi=0/0/0/char
  91.         shl     ebx,8           ; ebx=0/0/char/0
  92.         add     ebx,edi         ; ebx=0/0/char/char
  93.         mov     edi,ebx         ; edi=0/0/char/char
  94.         shl     ebx,10h         ; ebx=char/char/0/0
  95.         add     ebx,edi         ; ebx = all 4 bytes = [search char]
  96.         jmp     short main_loop_entry   ; ecx >=0
  97.  
  98. return_from_main:
  99.         pop     edi
  100.  
  101. tail_less_then_4:
  102.         add     eax,4
  103.         jz      retnull
  104.  
  105. tail_loop:                      ; 0 < eax < 4
  106.         mov     cl,byte ptr [edx]
  107.         inc     edx
  108.         xor     cl,bl
  109.         je      short found
  110.         dec     eax
  111.         jnz     short tail_loop
  112. retnull:
  113.         pop     ebx
  114.         ret                     ; _cdecl return
  115.  
  116. main_loop:
  117.         sub     eax,4
  118.         jb      short return_from_main
  119. main_loop_entry:
  120.         mov     ecx,dword ptr [edx]     ; read 4 bytes
  121.  
  122.         xor     ecx,ebx         ; ebx is byte\byte\byte\byte
  123.         mov     edi,7efefeffh
  124.  
  125.         add     edi,ecx
  126.         xor     ecx,-1
  127.  
  128.         xor     ecx,edi
  129.         add     edx,4
  130.  
  131.         and     ecx,81010100h
  132.         je      short main_loop
  133.  
  134. ; found zero byte in the loop?
  135. char_is_found:
  136.         mov     ecx,[edx - 4]
  137.         xor     cl,bl           ; is it byte 0
  138.         je      short byte_0
  139.         xor     ch,bl           ; is it byte 1
  140.         je      short byte_1
  141.         shr     ecx,10h         ; is it byte 2
  142.         xor     cl,bl
  143.         je      short byte_2
  144.         xor     ch,bl           ; is it byte 3
  145.         je      short byte_3
  146.         jmp     short main_loop ; taken if bits 24-30 are clear and bit
  147.                                 ; 31 is set
  148.  
  149. byte_3:
  150.         pop     edi             ; restore edi
  151. found:
  152.         lea     eax,[edx - 1]
  153.         pop     ebx             ; restore ebx
  154.         ret                     ; _cdecl return
  155.  
  156. byte_2:
  157.         lea     eax,[edx - 2]
  158.         pop     edi
  159.         pop     ebx
  160.         ret                     ; _cdecl return
  161.  
  162. byte_1:
  163.         lea     eax,[edx - 3]
  164.         pop     edi
  165.         pop     ebx
  166.         ret                     ; _cdecl return
  167.  
  168. byte_0:
  169.         lea     eax,[edx - 4]
  170.         pop     edi             ; restore edi
  171.         pop     ebx             ; restore ebx
  172.         ret                     ; _cdecl return
  173.  
  174. memchr  endp
  175.         end
  176.