summaryrefslogtreecommitdiffstats
path: root/private/crt32/string/i386/memicmp.asm
blob: e8742766052767483d18afebf1eeb0da4b39d074 (plain) (blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
	page	,132
	title	memicmp - compare blocks of memory, ignore case
;***
;memicmp.asm - compare memory, ignore case
;
;	Copyright (c) 1985-1991, Microsoft Corporation. All rights reserved.
;
;Purpose:
;	defines _memicmp() - compare two blocks of memory for lexical
;	order.	Case is ignored in the comparison.
;
;Revision History:
;	05-16-83  RN	initial version
;	05-17-88  SJM	Add model-independent (large model) ifdef
;	08-04-88  SJM	convert to cruntime/ add 32-bit support
;	08-23-88  JCR	Cleanup...
;	10-25-88  JCR	General cleanup for 386-only code
;	03-23-90  GJF	Changed to _stdcall. Also, fixed the copyright.
;	01-17-91  GJF	ANSI naming.
;	05-10-91  GJF	Back to _cdecl, sigh...
;
;*******************************************************************************

	.xlist
	include cruntime.inc
	.list

page
;***
;int _memicmp(first, last, count) - compare two blocks of memory, ignore case
;
;Purpose:
;	Compares count bytes of the two blocks of memory stored at first
;	and last.  The characters are converted to lowercase before
;	comparing (not permanently), so case is ignored in the search.
;
;	Algorithm:
;	int
;	_memicmp (first, last, count)
;	      char *first, *last;
;	      unsigned count;
;	      {
;	      if (!count)
;		      return(0);
;	      while (--count && tolower(*first) == tolower(*last))
;		      {
;		      first++;
;		      last++;
;		      }
;	      return(tolower(*first) - tolower(*last));
;	      }
;
;Entry:
;	char *first, *last - memory buffers to compare
;	unsigned count - maximum length to compare
;
;Exit:
;	returns <0 if first < last
;	returns 0 if first == last
;	returns >0 if first > last
;
;Uses:
;
;Exceptions:
;
;*******************************************************************************

	CODESEG

	public	_memicmp
_memicmp proc \
	uses edi esi ebx, \
	first:ptr byte, \
	last:ptr byte, \
	count:IWORD

	mov	esi,[first]	; si = first
	mov	edi,[last]	; di = last

	mov	ecx,[count]	; cx = count
	jecxz	short toend	; if count=0, nothing to do

	mov	bh,'A'
	mov	bl,'Z'
	mov	dh,'a'-'A'	; add to cap to make lower

lupe:
	mov	ah,[esi]	; ah = *first
	mov	al,[edi]	; al = *last
	inc	esi		; first++
	inc	edi		; last++
	cmp	ah,bh		; ah < 'A' ??
	jb	short skip1

	cmp	ah,bl		; ah > 'Z' ??
	ja	short skip1

	add	ah,dh		; make lower case

skip1:
	cmp	al,bh		; al < 'A' ??
	jb	short skip2

	cmp	al,bl		; al > 'Z' ??
	ja	short skip2

	add	al,dh		; make lower case

skip2:
	cmp	ah,al		; *first == *last ??
	jne	short differ	; nope, found mismatched chars

	loop	lupe
	jmp	short toend	; cx = 0, return 0

differ:
	mov	ecx,-1		; assume last is bigger
				; *** can't use "or ecx,-1" due to flags ***
	jb	short toend	; last is, in fact, bigger (return -1)
	neg	ecx		; first is bigger (return 1)

toend:
	mov	eax,ecx 	; move return value to ax

ifdef	_STDCALL_
	ret	2*DPSIZE + ISIZE ; _stdcall return
else
	ret			; _cdecl return
endif

_memicmp endp
	end