Leaked source code of windows server 2003
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

172 lines
5.6 KiB

  1. page ,132
  2. title strnicmp - compare n chars of strings, ignore case
  3. ;***
  4. ;strnicmp.asm - compare n chars of strings, ignoring case
  5. ;
  6. ; Copyright (c) 1986-2001, Microsoft Corporation. All rights reserved.
  7. ;
  8. ;Purpose:
  9. ; defines __ascii_strnicmp() - Compares at most n characters of two
  10. ; strings, without regard to case.
  11. ;
  12. ;Revision History:
  13. ; 04-04-85 RN initial version
  14. ; 07-11-85 TC zeroed cx, to allow correct return value if not equal
  15. ; 05-18-88 SJM Add model-independent (large model) ifdef
  16. ; 08-04-88 SJM convert to cruntime/ add 32-bit support
  17. ; 08-23-88 JCR 386 cleanup and improved return value sequence
  18. ; 10-26-88 JCR General cleanup for 386-only code
  19. ; 03-23-90 GJF Changed to _stdcall. Also, fixed the copyright.
  20. ; 01-18-91 GJF ANSI naming.
  21. ; 05-10-91 GJF Back to _cdecl, sigh...
  22. ; 10-20-94 GJF Made locale sensitive (i.e., now works for all
  23. ; single-byte character locales). Made multi-thread
  24. ; safe. Also, deleted obsolete _STDCALL_ code.
  25. ; 10-27-94 GJF Adapted above change for Win32S.
  26. ; 11-12-94 GJF Must avoid volatile regs or save them across function
  27. ; calls.
  28. ; 11-22-94 GJF Forgot to increment pointers in non-C locales.
  29. ; 07-03-95 CFW Changed offset of _lc_handle[LC_CTYPE], added sanity check
  30. ; to crtlib.c to catch changes to win32s.h that modify offset.
  31. ; 09-22-95 GJF Fixed first line at label differ2 to loaded -1 into
  32. ; ecx (same as code a label differ).
  33. ; 10-03-95 GJF New locale locking scheme.
  34. ; 07-17-96 GJF Added lock prefix to increment and decrement of
  35. ; __unguarded_readlc_active
  36. ; 07-18-96 GJF Fixed race condition.
  37. ; 09-10-98 GJF All locale and multithread support moved up to
  38. ; strnicmp.c. Renamed this file to _strnicm.asm.
  39. ; 06-12-01 PML inc->add 1, dec->sub 1 for Pentium 4 perf (vs7#267015)
  40. ;
  41. ;*******************************************************************************
  42. .xlist
  43. include cruntime.inc
  44. .list
  45. page
  46. ;***
  47. ;int __ascii_strnicmp(first, last, count) - compares count char of strings,
  48. ; ignore case
  49. ;
  50. ;Purpose:
  51. ; Compare the two strings for lexical order. Stops the comparison
  52. ; when the following occurs: (1) strings differ, (2) the end of the
  53. ; strings is reached, or (3) count characters have been compared.
  54. ; For the purposes of the comparison, upper case characters are
  55. ; converted to lower case.
  56. ;
  57. ; Algorithm:
  58. ; int
  59. ; _strncmpi (first, last, count)
  60. ; char *first, *last;
  61. ; unsigned int count;
  62. ; {
  63. ; int f,l;
  64. ; int result = 0;
  65. ;
  66. ; if (count) {
  67. ; do {
  68. ; f = tolower(*first);
  69. ; l = tolower(*last);
  70. ; first++;
  71. ; last++;
  72. ; } while (--count && f && l && f == l);
  73. ; result = f - l;
  74. ; }
  75. ; return(result);
  76. ; }
  77. ;
  78. ;Entry:
  79. ; char *first, *last - strings to compare
  80. ; unsigned count - maximum number of characters to compare
  81. ;
  82. ;Exit:
  83. ; returns <0 if first < last
  84. ; returns 0 if first == last
  85. ; returns >0 if first > last
  86. ;
  87. ;Uses:
  88. ;
  89. ;Exceptions:
  90. ;
  91. ;*******************************************************************************
  92. CODESEG
  93. public __ascii_strnicmp
  94. __ascii_strnicmp proc \
  95. uses edi esi ebx, \
  96. first:ptr byte, \
  97. last:ptr byte, \
  98. count:IWORD
  99. mov ecx,[count] ; cx = byte count
  100. or ecx,ecx
  101. jz toend ; if count = 0, we are done
  102. mov esi,[first] ; si = first string
  103. mov edi,[last] ; di = last string
  104. mov bh,'A'
  105. mov bl,'Z'
  106. mov dh,'a'-'A' ; add to cap to make lower
  107. align 4
  108. lupe:
  109. mov ah,[esi] ; *first
  110. or ah,ah ; see if *first is null
  111. mov al,[edi] ; *last
  112. jz short eject ; jump if *first is null
  113. or al,al ; see if *last is null
  114. jz short eject ; jump if so
  115. add esi,1 ; first++
  116. add edi,1 ; last++
  117. cmp ah,bh ; 'A'
  118. jb short skip1
  119. cmp ah,bl ; 'Z'
  120. ja short skip1
  121. add ah,dh ; make lower case
  122. skip1:
  123. cmp al,bh ; 'A'
  124. jb short skip2
  125. cmp al,bl ; 'Z'
  126. ja short skip2
  127. add al,dh ; make lower case
  128. skip2:
  129. cmp ah,al ; *first == *last ??
  130. jne short differ
  131. sub ecx,1
  132. jnz short lupe
  133. eject:
  134. xor ecx,ecx
  135. cmp ah,al ; compare the (possibly) differing bytes
  136. je short toend ; both zero; return 0
  137. differ:
  138. mov ecx,-1 ; assume last is bigger (* can't use 'or' *)
  139. jb short toend ; last is, in fact, bigger (return -1)
  140. neg ecx ; first is bigger (return 1)
  141. toend:
  142. mov eax,ecx
  143. ret ; _cdecl return
  144. __ascii_strnicmp endp
  145. end