Go to most recent revision | Details | Last modification | View Log | RSS feed
Rev | Author | Line No. | Line |
---|---|---|---|
1408 | serge | 1 | # _memmove() Author: Kees J. Bot 2 Jan 1994 |
2 | |||
3 | # void *_memmove(void *s1, const void *s2, size_t n) |
||
4 | # Copy a chunk of memory. Handle overlap. |
||
5 | |||
6 | .intel_syntax |
||
7 | |||
8 | .globl __memmove, __memcpy |
||
9 | |||
10 | .text |
||
11 | |||
12 | .align 16 |
||
13 | __memmove: |
||
14 | push ebp |
||
15 | mov ebp, esp |
||
16 | |||
17 | push esi |
||
18 | push edi |
||
19 | |||
20 | mov edi, [ebp+8] # String s1 |
||
21 | mov esi, [ebp+12] # String s2 |
||
22 | mov ecx, [ebp+16] # Length |
||
23 | |||
24 | mov eax, edi |
||
25 | sub eax, esi |
||
26 | cmp eax, ecx |
||
27 | jb downwards # if (s2 - s1) < n then copy downwards |
||
28 | __memcpy: |
||
29 | cld # Clear direction bit: upwards |
||
30 | cmp ecx, 16 |
||
31 | jb upbyte # Don't bother being smart with short arrays |
||
32 | |||
33 | mov eax, esi |
||
34 | or eax, edi |
||
35 | testb al, 1 |
||
36 | jnz upbyte # Bit 0 set, use byte copy |
||
37 | |||
38 | testb al, 2 |
||
39 | |||
40 | jnz upword # Bit 1 set, use word copy |
||
41 | uplword: |
||
42 | shrd eax, ecx, 2 # Save low 2 bits of ecx in eax |
||
43 | shr ecx, 2 |
||
44 | rep movsd # Copy longwords. |
||
45 | shld ecx, eax, 2 # Restore excess count |
||
46 | upword: |
||
47 | shr ecx, 1 |
||
48 | rep movsw # Copy words |
||
49 | adc ecx, ecx # One more byte? |
||
50 | upbyte: |
||
51 | rep movsb # Copy bytes |
||
52 | done: |
||
53 | mov eax, [ebp+8] # Absolutely noone cares about this value |
||
54 | pop edi |
||
55 | pop esi |
||
56 | pop ebp |
||
57 | ret |
||
58 | |||
59 | # Handle bad overlap by copying downwards, don't bother to do word copies. |
||
60 | |||
61 | downwards: |
||
62 | std # Set direction bit: downwards |
||
63 | lea esi, [esi+ecx-1] |
||
64 | lea edi, [edi+ecx-1] |
||
65 | rep movsb # Copy bytes |
||
66 | cld |
||
67 | jmp done> |