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