Subversion Repositories Kolibri OS

Rev

Rev 1408 | Blame | Compare with Previous | Last modification | View Log | Download | RSS feed

  1. /*      memcmp()                                        Author: Kees J. Bot */
  2. /*                                                              2 Jan 1994 */
  3.  
  4. /* int memcmp(const void *s1, const void *s2, size_t n) */
  5. /*      Compare two chunks of memory. */
  6. /* */
  7. #include "asm.h"
  8.  
  9. ENTRY(memcmp)
  10.         cld
  11.         push    %ebp
  12.         movl    %esp, %ebp
  13.         push    %esi
  14.         push    %edi
  15.         movl    8(%ebp), %esi   /* String s1 */
  16.         movl    12(%ebp), %edi  /* String s2 */
  17.         movl    16(%ebp), %ecx  /* Length */
  18.         cmpl    $16, %ecx
  19.         jb      cbyte   /* Don't bother being smart with short arrays */
  20.         movl    %esi, %eax
  21.         orl     %edi, %eax
  22.         testb   $1, %al
  23.         jne     cbyte   /* Bit 0 set, use byte compare */
  24.         testb   $2, %al
  25.         jne     cword   /* Bit 1 set, use word compare */
  26. clword:
  27.         shrdl   $2, %ecx, %eax  /* Save low two bits of ecx in eax */
  28.         shrl    $2, %ecx
  29.  
  30.         repe cmpsl      /* Compare longwords */
  31.         subl    $4, %esi
  32.         subl    $4, %edi
  33.         incl    %ecx    /* Recompare the last longword */
  34.         shldl   $2, %eax, %ecx  /* And any excess bytes */
  35.         jmp     last
  36. cword:
  37.         shrdl   $1, %ecx, %eax  /* Save low bit of ecx in eax */
  38.         shrl    $1, %ecx
  39.  
  40.         repe cmpsw      /* Compare words */
  41.         subl    $2, %esi
  42.         subl    $2, %edi
  43.         incl    %ecx    /* Recompare the last word */
  44.         shldl   $1, %eax, %ecx  /* And one more byte? */
  45. cbyte:
  46.         testl   %ecx, %ecx      /* Set 'Z' flag if ecx = 0 */
  47. last:
  48.         repe cmpsb      /* Look for the first differing byte */
  49.         seta    %al     /* al = (s1 > s2) */
  50.         setb    %ah     /* ah = (s1 < s2) */
  51.         subb    %ah, %al
  52.         movsbl  %al, %eax       /* eax = (s1 > s2) - (s1 < s2), i.e. -1, 0, 1 */
  53.         movl    %esi, %edx      /* For bcmp() to play with */
  54.         pop     %edi
  55.         pop     %esi
  56.         pop     %ebp
  57.         ret
  58.