xref: /reactos/sdk/lib/ucrt/string/amd64/strcmp.s (revision 94eb4751)
1#include <asm.inc>
2#include <ksamd64.inc>
3.code64
4#if 0
5        page    ,132
6        title   strcmp.asm - compare two strings
7;***
8;strcmp.asm - routine to compare two strings (for equal, less, or greater)
9;
10;       Copyright (c) Microsoft Corporation. All rights reserved.
11;
12;Purpose:
13;       STRCMP compares two strings and returns an integer
14;       to indicate whether the first is less than the second, the two are
15;       equal, or whether the first is greater than the second, respectively.
16;       Comparison is done byte by byte on an UNSIGNED basis, which is to
17;       say that Null (0) is less than any other character (1-255).
18;
19;*******************************************************************************
20include ksamd64.inc
21        subttl  "strcmp"
22;***
23;strcmp - compare two strings, returning less than, equal to, or greater than
24;
25;Purpose:
26;       Compares two string, determining their ordinal order.  Unsigned
27;       comparison is used.
28;
29;       Algorithm:
30;          int strcmp ( src , dst )
31;                  unsigned char *src;
32;                  unsigned char *dst;
33;          {
34;                  int ret = 0 ;
35;
36;                  while( ! (ret = *src - *dst) && *dst)
37;                          ++src, ++dst;
38;
39;                  if ( ret < 0 )
40;                          ret = -1 ;
41;                  else if ( ret > 0 )
42;                          ret = 1 ;
43;
44;                  return( ret );
45;          }
46;
47;Entry:
48;       const char * src - string for left-hand side of comparison
49;       const char * dst - string for right-hand side of comparison
50;
51;Exit:
52;       AX < 0, 0, or >0, indicating whether the first string is
53;       Less than, Equal to, or Greater than the second string.
54;
55;Uses:
56;       CX, DX
57;
58;Exceptions:
59;
60;*******************************************************************************
61#endif
62
63#define CHAR_TYPE BYTE
64#define CHAR_PTR BYTE PTR
65#define CHAR_SIZE 1 /* = sizeof CHAR_TYPE */
66
67#define BLK_TYPE QWORD
68#define BLK_PTR QWORD PTR
69#define BLK_SIZE 8 /* = sizeof BLK_TYPE */
70
71//PAGE_SIZE = 1000h
72PAGE_MASK = PAGE_SIZE - 1       // mask for offset in MM page
73PAGE_SAFE_BLK = PAGE_SIZE - BLK_SIZE // maximum offset for safe block compare
74
75LEAF_ENTRY_ARG2 strcmp, _TEXT, str1_ptr_byte, str2_ptr_byte
76
77    //OPTION PROLOGUE:NONE, EPILOGUE:NONE
78
79// rcx = src
80// rdx = dst
81
82    sub     rdx, rcx
83    test    cl, (BLK_SIZE - 1)
84    jz      qword_loop_enter
85
86comp_head_loop_begin:
87    movzx   eax, CHAR_PTR[rcx]
88    cmp     al, CHAR_PTR[rdx+rcx]
89    jnz     return_not_equal
90
91    inc     rcx
92
93    test    al, al
94    jz      return_equal
95
96    test    cl, (BLK_SIZE - 1)
97    jnz     comp_head_loop_begin
98
99qword_loop_enter:
100
101    mov     r11, HEX(8080808080808080)
102    mov     r10, HEX(0fefefefefefefeff)
103
104qword_loop_begin:
105    lea     eax, [edx+ecx]
106    and     eax, PAGE_MASK
107    cmp     eax, PAGE_SAFE_BLK
108    ja      comp_head_loop_begin
109
110    mov     rax, BLK_PTR[rcx]
111    cmp     rax, BLK_PTR[rdx+rcx]
112
113// mismatched string (or maybe null + garbage after)
114    jne     comp_head_loop_begin
115
116// look for null terminator
117    lea     r9, [rax + r10]
118    not     rax
119    add     rcx, BLK_SIZE
120    and     rax, r9
121
122    test    rax, r11       // r11=8080808080808080h
123    jz      qword_loop_begin
124
125return_equal:
126    xor     eax, eax // gets all 64 bits
127    ret
128
129return_not_equal:
130    sbb     rax, rax // AX=-1, CY=1 AX=0, CY=0
131    or      rax, 1
132    ret
133
134LEAF_END strcmp, _TEXT
135end
136