eb93f89d2305551144b2efa258a9d1c06857b1f7
[reactos.git] / sdk / lib / rtl / i386 / rtlmem.s
1 /*
2 * COPYRIGHT: GNU GPL - See COPYING in the top level directory
3 * PROJECT: ReactOS Run-Time Library
4 * PURPOSE: Memory functions
5 * FILE: lib/rtl/i386/rtlmem.s
6 * PROGRAMER: Alex Ionescu (alex.ionescu@reactos.org)
7 */
8
9 #include <asm.inc>
10
11 /* GLOBALS *******************************************************************/
12
13 PUBLIC _RtlCompareMemory@12
14 PUBLIC _RtlCompareMemoryUlong@12
15 PUBLIC _RtlFillMemory@12
16 PUBLIC _RtlFillMemoryUlong@12
17 PUBLIC _RtlMoveMemory@12
18 PUBLIC _RtlZeroMemory@8
19
20 /* FUNCTIONS *****************************************************************/
21 .code
22
23 _RtlCompareMemory@12:
24
25 /* Save volatiles */
26 push esi
27 push edi
28
29 /* Clear direction flag and load pointers and size in ULONGs */
30 cld
31 mov esi, [esp+12]
32 mov edi, [esp+16]
33 mov ecx, [esp+20]
34 shr ecx, 2
35 jz NoUlongs
36
37 /* Compare the ULONGs */
38 repe cmpsd
39 jnz NotEqual
40
41 NoUlongs:
42
43 /* Compare what's left */
44 mov ecx, [esp+20]
45 and ecx, 3
46 jz NoneLeft
47 repe cmpsb
48 jnz NotEqual2
49
50 NoneLeft:
51
52 /* We're done, return full count */
53 mov eax, [esp+20]
54 pop edi
55 pop esi
56 ret 12
57
58 NotEqual:
59 /* Compare the last ULONG */
60 sub esi, 4
61 sub edi, 4
62 mov ecx, 5
63 repe cmpsb
64
65 NotEqual2:
66
67 /* Remember how many matched */
68 dec esi
69 sub esi, [esp+12]
70
71 /* Return count */
72 mov eax, esi
73 pop edi
74 pop esi
75 ret 12
76
77
78 _RtlCompareMemoryUlong@12:
79
80 /* Get pointers and size in ULONGs */
81 push edi
82 mov edi, [esp+8]
83 mov ecx, [esp+12]
84 mov eax, [esp+16]
85 shr ecx, 2
86
87 /* Do the compare and check result */
88 repe scasd
89 jz Done
90 sub edi, 4
91
92 /* Return count */
93 Done:
94 sub edi, [esp+8]
95 mov eax, edi
96 pop edi
97 ret 12
98
99
100 _RtlFillMemory@12:
101
102 /* Get pointers and size */
103 push edi
104 mov edi, [esp+8]
105 mov ecx, [esp+12]
106
107 /* Get pattern */
108 mov al, [esp+16]
109 mov ah, al
110 shl eax, 16
111 mov al, [esp+16]
112 mov ah, al
113
114 /* Clear direction flag and set ULONG size and UCHAR remainder */
115 cld
116 mov edx, ecx
117 and edx, 3
118 shr ecx, 2
119
120 /* Do the fill */
121 rep stosd
122 or ecx, edx
123 jnz ByteFill
124
125 /* Return */
126 pop edi
127 ret 12
128
129 ByteFill:
130 /* Fill what's left */
131 rep stosb
132 pop edi
133 ret 12
134
135
136 _RtlFillMemoryUlong@12:
137
138 /* Get pointer, size and pattern */
139 push edi
140 mov edi, [esp+8]
141 mov ecx, [esp+12]
142 mov eax, [esp+16]
143 shr ecx, 2
144
145 /* Do the fill and return */
146 rep stosd
147 pop edi
148 ret 12
149
150
151 _RtlFillMemoryUlonglong@16:
152
153 /* Save volatiles */
154 push edi
155 push esi
156
157 /* Get pointer, size and pattern */
158 mov ecx, [esp+16]
159 mov esi, [esp+12]
160 mov eax, [esp+20]
161 shr ecx, 2
162 sub ecx, 2
163
164 /* Save the first part */
165 mov [esi], eax
166
167 /* Read second part */
168 mov eax, [esp+24]
169 lea edi, [esi+8]
170 mov [esi+4], eax
171
172 /* Do the fill and return */
173 rep movsd
174 pop esi
175 pop edi
176 ret 16
177
178
179 _RtlZeroMemory@8:
180
181 /* Get pointers and size */
182 push edi
183 mov edi, [esp+8]
184 mov ecx, [esp+12]
185
186 /* Get pattern */
187 xor eax, eax
188
189 /* Clear direction flag and set ULONG size and UCHAR remainder */
190 cld
191 mov edx, ecx
192 and edx, 3
193 shr ecx, 2
194
195 /* Do the fill */
196 rep stosd
197 or ecx, edx
198 jnz ByteZero
199
200 /* Return */
201 pop edi
202 ret 8
203
204 ByteZero:
205 /* Fill what's left */
206 rep stosb
207 pop edi
208 ret 8
209
210
211 _RtlMoveMemory@12:
212 push ebp
213 mov ebp, esp
214
215 /* Save non-volatiles */
216 push esi
217 push edi
218
219 /* Get pointers and size */
220 mov edi, [ebp + 8]
221 mov esi, [ebp + 12]
222 mov ecx, [ebp + 16]
223
224 /* Use downward copy if source < dest and overlapping */
225 cmp edi, esi
226 jbe .CopyUp
227 mov eax, ecx
228 add eax, esi
229 cmp edi, eax
230 jb .CopyDown
231
232 .CopyUp:
233 cld
234
235 /* Check for small moves */
236 cmp ecx, 16
237 jb .CopyUpBytes
238
239 /* Check if its already aligned */
240 mov edx, ecx
241 test edi, 3
242 je .CopyUpDwords
243
244 /* Make the destination dword aligned */
245 mov ecx, edi
246 and ecx, 3
247 sub ecx, 5
248 not ecx
249 sub edx, ecx
250 rep movsb
251 mov ecx, edx
252
253 .CopyUpDwords:
254 shr ecx, 2
255 rep movsd
256 mov ecx, edx
257 and ecx, 3
258
259 .CopyUpBytes:
260 test ecx, ecx
261 je .CopyUpEnd
262 rep movsb
263
264 .CopyUpEnd:
265 mov eax, [ebp + 8]
266 pop edi
267 pop esi
268 pop ebp
269 ret 12
270
271 .CopyDown:
272 std
273
274 /* Go to the end of the region */
275 add edi, ecx
276 add esi, ecx
277
278 /* Check for small moves */
279 cmp ecx, 16
280 jb .CopyDownSmall
281
282 /* Check if its already aligned */
283 mov edx, ecx
284 test edi, 3
285 je .CopyDownAligned
286
287 /* Make the destination dword aligned */
288 mov ecx, edi
289 and ecx, 3
290 sub edx, ecx
291 dec esi
292 dec edi
293 rep movsb
294 mov ecx, edx
295 sub esi, 3
296 sub edi, 3
297
298 .CopyDownDwords:
299 shr ecx, 2
300 rep movsd
301 mov ecx, edx
302 and ecx, 3
303 je .CopyDownEnd
304 add esi, 3
305 add edi, 3
306
307 .CopyDownBytes:
308 rep movsb
309
310 .CopyDownEnd:
311 cld
312 mov eax, [ebp + 8]
313 pop edi
314 pop esi
315 pop ebp
316 ret 12
317
318 .CopyDownAligned:
319 sub edi, 4
320 sub esi, 4
321 jmp .CopyDownDwords
322
323 .CopyDownSmall:
324 test ecx, ecx
325 je .CopyDownEnd
326 dec esi
327 dec edi
328 jmp .CopyDownBytes
329
330 END