Rev 1408 | Show entire file | Regard whitespace | Details | Blame | Last modification | View Log | RSS feed
Rev 1408 | Rev 1627 | ||
---|---|---|---|
Line 1... | Line 1... | ||
1 | # memcmp() Author: Kees J. Bot |
1 | /* memcmp() Author: Kees J. Bot */ |
2 | # 2 Jan 1994 |
2 | /* 2 Jan 1994 */ |
Line 3... | Line 3... | ||
3 | 3 | ||
4 | # int memcmp(const void *s1, const void *s2, size_t n) |
4 | /* int memcmp(const void *s1, const void *s2, size_t n) */ |
5 | # Compare two chunks of memory. |
5 | /* Compare two chunks of memory. */ |
- | 6 | /* */ |
|
Line 6... | Line -... | ||
6 | # |
- | |
7 | - | ||
8 | .intel_syntax |
- | |
9 | - | ||
10 | .globl _memcmp |
- | |
11 | - | ||
12 | .text |
7 | #include "asm.h" |
13 | .align 16 |
8 | |
14 | _memcmp: |
9 | ENTRY(memcmp) |
15 | cld |
10 | cld |
16 | push ebp |
11 | push %ebp |
17 | mov ebp, esp |
12 | movl %esp, %ebp |
18 | push esi |
13 | push %esi |
19 | push edi |
14 | push %edi |
20 | mov esi, [8+ebp] # String s1 |
15 | movl 8(%ebp), %esi /* String s1 */ |
21 | mov edi, [12+ebp] # String s2 |
16 | movl 12(%ebp), %edi /* String s2 */ |
22 | mov ecx, [16+ebp] # Length |
17 | movl 16(%ebp), %ecx /* Length */ |
23 | cmp ecx, 16 |
18 | cmpl $16, %ecx |
24 | jb cbyte # Don't bother being smart with short arrays |
19 | jb cbyte /* Don't bother being smart with short arrays */ |
25 | mov eax, esi |
20 | movl %esi, %eax |
26 | or eax, edi |
21 | orl %edi, %eax |
27 | testb al, 1 |
22 | testb $1, %al |
28 | jnz cbyte # Bit 0 set, use byte compare |
23 | jne cbyte /* Bit 0 set, use byte compare */ |
- | 24 | testb $2, %al |
|
29 | testb al, 2 |
25 | jne cword /* Bit 1 set, use word compare */ |
30 | jnz cword # Bit 1 set, use word compare |
26 | clword: |
31 | clword: shrd eax, ecx, 2 # Save low two bits of ecx in eax |
27 | shrdl $2, %ecx, %eax /* Save low two bits of ecx in eax */ |
32 | shr ecx, 2 |
28 | shrl $2, %ecx |
33 | repe |
29 | |
34 | cmpsd # Compare longwords |
30 | repe cmpsl /* Compare longwords */ |
35 | sub esi, 4 |
31 | subl $4, %esi |
36 | sub edi, 4 |
32 | subl $4, %edi |
37 | inc ecx # Recompare the last longword |
33 | incl %ecx /* Recompare the last longword */ |
- | 34 | shldl $2, %eax, %ecx /* And any excess bytes */ |
|
38 | shld ecx, eax, 2 # And any excess bytes |
35 | jmp last |
39 | jmp last |
36 | cword: |
40 | cword: shrd eax, ecx, 1 # Save low bit of ecx in eax |
37 | shrdl $1, %ecx, %eax /* Save low bit of ecx in eax */ |
41 | shr ecx, 1 |
38 | shrl $1, %ecx |
42 | repe |
39 | |
43 | cmpsw # Compare words |
40 | repe cmpsw /* Compare words */ |
44 | sub esi, 2 |
41 | subl $2, %esi |
45 | sub edi, 2 |
42 | subl $2, %edi |
- | 43 | incl %ecx /* Recompare the last word */ |
|
46 | inc ecx # Recompare the last word |
44 | shldl $1, %eax, %ecx /* And one more byte? */ |
47 | shld ecx, eax, 1 # And one more byte? |
45 | cbyte: |
48 | cbyte: test ecx, ecx # Set 'Z' flag if ecx = 0 |
46 | testl %ecx, %ecx /* Set 'Z' flag if ecx = 0 */ |
49 | last: repe |
47 | last: |
50 | cmpsb # Look for the first differing byte |
48 | repe cmpsb /* Look for the first differing byte */ |
51 | seta al # al = (s1 > s2) |
49 | seta %al /* al = (s1 > s2) */ |
52 | setb ah # ah = (s1 < s2) |
50 | setb %ah /* ah = (s1 < s2) */ |
53 | subb al, ah |
51 | subb %ah, %al |
54 | movsxb eax, al # eax = (s1 > s2) - (s1 < s2), i.e. -1, 0, 1 |
52 | movsbl %al, %eax /* eax = (s1 > s2) - (s1 < s2), i.e. -1, 0, 1 */ |
55 | mov edx, esi # For bcmp() to play with |
53 | movl %esi, %edx /* For bcmp() to play with */ |
56 | pop edi |
54 | pop %edi |
57 | pop esi |
55 | pop %esi |