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