-
Notifications
You must be signed in to change notification settings - Fork 3
/
Copy pathmemchr.asm
180 lines (152 loc) · 4.89 KB
/
memchr.asm
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
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
page ,132
title memchr - search memory for a given character
;***
;memchr.asm - search block of memory for a given character
;
; Copyright (c) Microsoft Corporation. All rights reserved.
;
;Purpose:
; defines memchr() - search memory until a character is
; found or a limit is reached.
;
;*******************************************************************************
.xlist
include vcruntime.inc
.list
page
;***
;char *memchr(buf, chr, cnt) - search memory for given character.
;
;Purpose:
; Searched at buf for the given character, stopping when chr is
; first found or cnt bytes have been searched through.
;
; Algorithm:
; char *
; memchr (buf, chr, cnt)
; char *buf;
; int chr;
; unsigned cnt;
; {
; while (cnt && *buf++ != c)
; cnt--;
; return(cnt ? --buf : NULL);
; }
;
;Entry:
; char *buf - memory buffer to be searched
; char chr - character to search for
; unsigned cnt - max number of bytes to search
;
;Exit:
; returns pointer to first occurence of chr in buf
; returns NULL if chr not found in the first cnt bytes
;
;Uses:
;
;Exceptions:
;
;*******************************************************************************
CODESEG
public memchr
memchr proc \
buf:ptr byte, \
chr:byte, \
cnt:dword
OPTION PROLOGUE:NONE, EPILOGUE:NONE
.FPO ( 0, 1, 0, 0, 0, 0 )
mov eax,[esp+0ch] ; eax = count
push ebx ; Preserve ebx
test eax,eax ; check if count=0
jz short retnull ; if count=0, leave
mov edx,[esp+8] ; edx = buffer
xor ebx,ebx
mov bl,[esp+0ch] ; bl = search char
test edx,3 ; test if string is aligned on 32 bits
jz short main_loop_start
str_misaligned: ; simple byte loop until string is aligned
mov cl,byte ptr [edx]
add edx,1
xor cl,bl
je short found
sub eax,1 ; counter--
jz short retnull
test edx,3 ; already aligned ?
jne short str_misaligned
main_loop_start:
sub eax,4
jb short tail_less_then_4
; set all 4 bytes of ebx to [value]
push edi ; Preserve edi
mov edi,ebx ; edi=0/0/0/char
shl ebx,8 ; ebx=0/0/char/0
add ebx,edi ; ebx=0/0/char/char
mov edi,ebx ; edi=0/0/char/char
shl ebx,10h ; ebx=char/char/0/0
add ebx,edi ; ebx = all 4 bytes = [search char]
jmp short main_loop_entry ; ecx >=0
return_from_main:
pop edi
tail_less_then_4:
add eax,4
jz retnull
tail_loop: ; 0 < eax < 4
mov cl,byte ptr [edx]
add edx,1
xor cl,bl
je short found
sub eax,1
jnz short tail_loop
retnull:
pop ebx
ret ; _cdecl return
main_loop:
sub eax,4
jb short return_from_main
main_loop_entry:
mov ecx,dword ptr [edx] ; read 4 bytes
xor ecx,ebx ; ebx is byte\byte\byte\byte
mov edi,7efefeffh
add edi,ecx
xor ecx,-1
xor ecx,edi
add edx,4
and ecx,81010100h
je short main_loop
; found zero byte in the loop?
char_is_found:
mov ecx,[edx - 4]
xor cl,bl ; is it byte 0
je short byte_0
xor ch,bl ; is it byte 1
je short byte_1
shr ecx,10h ; is it byte 2
xor cl,bl
je short byte_2
xor ch,bl ; is it byte 3
je short byte_3
jmp short main_loop ; taken if bits 24-30 are clear and bit
; 31 is set
byte_3:
pop edi ; restore edi
found:
lea eax,[edx - 1]
pop ebx ; restore ebx
ret ; _cdecl return
byte_2:
lea eax,[edx - 2]
pop edi
pop ebx
ret ; _cdecl return
byte_1:
lea eax,[edx - 3]
pop edi
pop ebx
ret ; _cdecl return
byte_0:
lea eax,[edx - 4]
pop edi ; restore edi
pop ebx ; restore ebx
ret ; _cdecl return
memchr endp
end