xref: /reactos/sdk/lib/ucrt/string/i386/strncmp.s (revision 94eb4751)
1*94eb4751STimo Kreuzer#include <asm.inc>
2*94eb4751STimo Kreuzer#if 0
34fec953eSTimo Kreuzer        page    ,132
44fec953eSTimo Kreuzer        title   strncmp.asm - compare two strings
54fec953eSTimo Kreuzer;***
64fec953eSTimo Kreuzer;strcmp.asm - routine to compare two strings (for equal, less, or greater)
74fec953eSTimo Kreuzer;
84fec953eSTimo Kreuzer;       Copyright (c) Microsoft Corporation. All rights reserved.
94fec953eSTimo Kreuzer;
104fec953eSTimo Kreuzer;Purpose:
114fec953eSTimo Kreuzer;       strncmp compares two strings and returns an integer
124fec953eSTimo Kreuzer;       to indicate whether the first is less than the second, the two are
134fec953eSTimo Kreuzer;       equal, or whether the first is greater than the second, respectively.
144fec953eSTimo Kreuzer;       Comparison is done byte by byte on an UNSIGNED basis, which is to
154fec953eSTimo Kreuzer;       say that Null (0) is less than any other character (1-255).
164fec953eSTimo Kreuzer;
174fec953eSTimo Kreuzer;*******************************************************************************
184fec953eSTimo Kreuzer
194fec953eSTimo Kreuzer        .xlist
204fec953eSTimo Kreuzer        include cruntime.inc
214fec953eSTimo Kreuzer        .list
224fec953eSTimo Kreuzer
234fec953eSTimo Kreuzerpage
244fec953eSTimo Kreuzer;***
254fec953eSTimo Kreuzer;strncmp - compare two strings, returning less than, equal to, or greater than
264fec953eSTimo Kreuzer;
274fec953eSTimo Kreuzer;Purpose:
284fec953eSTimo Kreuzer;       Compares two string, determining their lexical order.  Unsigned
294fec953eSTimo Kreuzer;       comparison is used.
304fec953eSTimo Kreuzer;
314fec953eSTimo Kreuzer;       Algorithm:
324fec953eSTimo Kreuzer;          int strncmp (
334fec953eSTimo Kreuzer;              const char *first,
344fec953eSTimo Kreuzer;              const char *last,
354fec953eSTimo Kreuzer;              size_t      count
364fec953eSTimo Kreuzer;          )
374fec953eSTimo Kreuzer;          {
384fec953eSTimo Kreuzer;              size_t x;
394fec953eSTimo Kreuzer;              int ret = 0 ;
404fec953eSTimo Kreuzer;
414fec953eSTimo Kreuzer;              for (x = 0; x < count; x++)
424fec953eSTimo Kreuzer;              {
434fec953eSTimo Kreuzer;                  if (*first == 0 || *first != *last)
444fec953eSTimo Kreuzer;                  {
454fec953eSTimo Kreuzer;                      int ret = (*(unsigned char *)first - *(unsigned char *)last);
464fec953eSTimo Kreuzer;                      if ( ret < 0 )
474fec953eSTimo Kreuzer;                          ret = -1 ;
484fec953eSTimo Kreuzer;                      else if ( ret > 0 )
494fec953eSTimo Kreuzer;                          ret = 1 ;
504fec953eSTimo Kreuzer;                      return ret;
514fec953eSTimo Kreuzer;                  }
524fec953eSTimo Kreuzer;                  ++first;
534fec953eSTimo Kreuzer;                  ++last;
544fec953eSTimo Kreuzer;              }
554fec953eSTimo Kreuzer;
564fec953eSTimo Kreuzer;              return 0;
574fec953eSTimo Kreuzer;          }
584fec953eSTimo Kreuzer;
594fec953eSTimo Kreuzer;Entry:
604fec953eSTimo Kreuzer;       const char * first - string for left-hand side of comparison
614fec953eSTimo Kreuzer;       const char * last  - string for right-hand side of comparison
624fec953eSTimo Kreuzer;       size_t count       - maximum number of characters to compare; if
634fec953eSTimo Kreuzer;                             strings equal to that point consider them equal
644fec953eSTimo Kreuzer;
654fec953eSTimo Kreuzer;Exit:
664fec953eSTimo Kreuzer;       EAX < 0, 0, or >0, indicating whether the first string is
674fec953eSTimo Kreuzer;       Less than, Equal to, or Greater than the second string.
684fec953eSTimo Kreuzer;
694fec953eSTimo Kreuzer;       Note: For compatibility with other versions of this routine
704fec953eSTimo Kreuzer;       the returned value is limited to {-1, 0, 1}.
714fec953eSTimo Kreuzer;
724fec953eSTimo Kreuzer;Uses:
734fec953eSTimo Kreuzer;       ECX, EDX
744fec953eSTimo Kreuzer;
754fec953eSTimo Kreuzer;Exceptions:
764fec953eSTimo Kreuzer;
774fec953eSTimo Kreuzer;*******************************************************************************
78*94eb4751STimo Kreuzer#endif
794fec953eSTimo Kreuzer
80*94eb4751STimo Kreuzer        .code
814fec953eSTimo Kreuzer
82*94eb4751STimo Kreuzer#define CHAR_TYPE BYTE
83*94eb4751STimo Kreuzer#define CHAR_PTR BYTE PTR
84*94eb4751STimo Kreuzer#define CHAR_SIZE 1 // = sizeof CHAR_TYPE
854fec953eSTimo Kreuzer
86*94eb4751STimo Kreuzer#define BLK_TYPE DWORD
87*94eb4751STimo Kreuzer#define BLK_PTR DWORD PTR
88*94eb4751STimo Kreuzer#define BLK_SIZE 4 // = sizeof BLK_TYPE
89*94eb4751STimo Kreuzer#define BLK_CHARS 4 // = BLK_SIZE / CHAR_SIZE
904fec953eSTimo Kreuzer
91*94eb4751STimo KreuzerPAGE_SIZE = HEX(1000)
92*94eb4751STimo KreuzerPAGE_MASK = PAGE_SIZE - 1       // mask for offset in MM page
93*94eb4751STimo KreuzerPAGE_SAFE_BLK = PAGE_SIZE - BLK_SIZE // maximum offset for safe block compare
944fec953eSTimo Kreuzer
95*94eb4751STimo Kreuzer    public  _strncmp
96*94eb4751STimo Kreuzer.PROC _strncmp
97*94eb4751STimo Kreuzer        // uses ebx esi, \
98*94eb4751STimo Kreuzer        // str1:ptr byte, \
99*94eb4751STimo Kreuzer        // str2:ptr byte, \
100*94eb4751STimo Kreuzer        // count:IWORD
1014fec953eSTimo Kreuzer
102*94eb4751STimo Kreuzer    //OPTION PROLOGUE:NONE, EPILOGUE:NONE
1034fec953eSTimo Kreuzer
1044fec953eSTimo Kreuzer    push      ebx
1054fec953eSTimo Kreuzer    push      esi
1064fec953eSTimo Kreuzer
107*94eb4751STimo Kreuzer//   .FPO (cdwLocals, cdwParams, cbProlog, cbRegs, fUseBP, cbFrame)
108*94eb4751STimo Kreuzer    FPO      0, 3, ($ - _strncmp), 2, 0, 0
1094fec953eSTimo Kreuzer
110*94eb4751STimo Kreuzer    mov       ecx,[esp + 12]   // ecx = str1
111*94eb4751STimo Kreuzer    mov       edx,[esp + 16]   // edx = str2
112*94eb4751STimo Kreuzer    mov       ebx,[esp + 20]   // ebx = count
1134fec953eSTimo Kreuzer
114*94eb4751STimo Kreuzer// Check for a limit of zero characters.
115*94eb4751STimo Kreuzer    test      ebx, HEX(0FFFFFFFF)
1164fec953eSTimo Kreuzer    jz        return_equal
1174fec953eSTimo Kreuzer
1184fec953eSTimo Kreuzer    sub       ecx, edx
1194fec953eSTimo Kreuzer
1204fec953eSTimo Kreuzer    test      edx, (BLK_SIZE - 1)
1214fec953eSTimo Kreuzer    jz        dword_loop_begin
1224fec953eSTimo Kreuzer
1234fec953eSTimo Kreuzercomp_head_loop_begin:
1244fec953eSTimo Kreuzer    movzx     eax, CHAR_PTR[ecx+edx]
1254fec953eSTimo Kreuzer    cmp       al, CHAR_PTR[edx]
1264fec953eSTimo Kreuzer    jnz       return_not_equal
1274fec953eSTimo Kreuzer
1284fec953eSTimo Kreuzer    test      eax, eax
1294fec953eSTimo Kreuzer    jz        return_equal
1304fec953eSTimo Kreuzer
1314fec953eSTimo Kreuzer    inc       edx
1324fec953eSTimo Kreuzer
1334fec953eSTimo Kreuzer    sub       ebx, 1
1344fec953eSTimo Kreuzer    jbe       return_equal
1354fec953eSTimo Kreuzer
1364fec953eSTimo Kreuzer    test      dl, (BLK_SIZE - 1)
1374fec953eSTimo Kreuzer    jnz       comp_head_loop_begin
1384fec953eSTimo Kreuzer
1394fec953eSTimo Kreuzerdword_loop_begin:
1404fec953eSTimo Kreuzer    lea       eax, [ecx+edx]
1414fec953eSTimo Kreuzer    and       eax, PAGE_MASK
1424fec953eSTimo Kreuzer    cmp       eax, PAGE_SAFE_BLK
1434fec953eSTimo Kreuzer    ja        comp_head_loop_begin
1444fec953eSTimo Kreuzer
1454fec953eSTimo Kreuzer    mov       eax, BLK_PTR[ecx+edx]
1464fec953eSTimo Kreuzer    cmp       eax, BLK_PTR[edx]
1474fec953eSTimo Kreuzer    jne       comp_head_loop_begin
1484fec953eSTimo Kreuzer
1494fec953eSTimo Kreuzer    sub       ebx, BLK_CHARS
1504fec953eSTimo Kreuzer    jbe       return_equal
1514fec953eSTimo Kreuzer
152*94eb4751STimo Kreuzer    lea       esi, [eax+HEX(0fefefeff)]
1534fec953eSTimo Kreuzer    add       edx, BLK_SIZE
1544fec953eSTimo Kreuzer    not       eax
1554fec953eSTimo Kreuzer    and       eax, esi
156*94eb4751STimo Kreuzer    test      eax, HEX(80808080)
1574fec953eSTimo Kreuzer    jz        dword_loop_begin
1584fec953eSTimo Kreuzer
1594fec953eSTimo Kreuzerreturn_equal:
1604fec953eSTimo Kreuzer    xor       eax, eax
1614fec953eSTimo Kreuzer    pop       esi
1624fec953eSTimo Kreuzer    pop       ebx
1634fec953eSTimo Kreuzer    ret
1644fec953eSTimo Kreuzer
1654fec953eSTimo Kreuzer    align     16
1664fec953eSTimo Kreuzer
1674fec953eSTimo Kreuzerreturn_not_equal:
168*94eb4751STimo Kreuzer    sbb       eax, eax  // AX=-1, CY=1 AX=0, CY=0
1694fec953eSTimo Kreuzer    or        eax, 1
1704fec953eSTimo Kreuzer    pop       esi
1714fec953eSTimo Kreuzer    pop       ebx
1724fec953eSTimo Kreuzer    ret
1734fec953eSTimo Kreuzer
174*94eb4751STimo Kreuzer.ENDP // _strncmp
1754fec953eSTimo Kreuzer
1764fec953eSTimo Kreuzer    end
177