egcs-1.1 in SCOV5 changes memcpy() into buggy SCO bcopy()
Eric Dumazet
dumazet@cosmosbay.com
Thu Sep 17 00:38:00 GMT 1998
Hello Robert,
I discovered one problem with egcs-1.1 on SCO5, at least the one I use
at work.
When a C program uses memcpy(), the assembly generated calls bcopy().
example try.c :
#include <string.h>
void mycopy(char *dst, const char *src, size_t len)
{memcpy(dst, src, len) ;}
egcs -O2 -S try.c generates :
.globl mycopy
.type mycopy,@function
mycopy:
pushl %ebp
movl %esp,%ebp
movl 8(%ebp),%eax
movl 12(%ebp),%ecx
movl 16(%ebp),%edx
pushl %edx
pushl %eax
pushl %ecx
call bcopy
movl %ebp,%esp
popl %ebp
ret
But bcopy in SCO is a wrapper to memmove() function :
0x8061990 <bcopy>: pushl %ebp
0x8061991 <bcopy+1>: movl %esp,%ebp
0x8061993 <bcopy+3>: movl 0x10(%ebp),%edx
0x8061996 <bcopy+6>: movl 0x8(%ebp),%ecx
0x8061999 <bcopy+9>: pushl %edx
0x806199a <bcopy+10>: pushl %ecx
0x806199b <bcopy+11>: movl 0xc(%ebp),%eax
0x806199e <bcopy+14>: pushl %eax
0x806199f <bcopy+15>: call 0x8048ecc <memmove>
0x80619a4 <bcopy+20>: addl $0xc,%esp
0x80619a7 <bcopy+23>: movl %ebp,%esp
0x80619a9 <bcopy+25>: popl %ebp
0x80619aa <bcopy+26>: ret
OK, price in performance you could say, becaus memmove MUST check the
pointers, and memcpy do not have this constraint.
But ... memmove is very very slow in SCO.. you already know that ? (in
SCO 4.2, it was buggy...)
0x80045a00 <memmove>: pushl %ebp
0x80045a01 <memmove+1>: movl %esp,%ebp
0x80045a03 <memmove+3>: subl $0x8,%esp
0x80045a06 <memmove+6>: pushl %edi
0x80045a07 <memmove+7>: movl 0x10(%ebp),%edi
0x80045a0a <memmove+10>: pushl %esi
0x80045a0b <memmove+11>: testl %edi,%edi
0x80045a0d <memmove+13>: je 0x80045a26 <memmove+38>
0x80045a0f <memmove+15>: movl 0x8(%ebp),%ecx
0x80045a12 <memmove+18>: movl 0xc(%ebp),%esi
0x80045a15 <memmove+21>: cmpl %esi,%ecx
0x80045a17 <memmove+23>: jbe 0x80045a30 <memmove+48>
0x80045a19 <memmove+25>: addl %edi,%esi
0x80045a1b <memmove+27>: addl %edi,%ecx
0x80045a1d <memmove+29>: decl %esi
0x80045a1e <memmove+30>: decl %ecx
0x80045a1f <memmove+31>: movb (%esi),%dl
0x80045a21 <memmove+33>: movb %dl,(%ecx)
0x80045a23 <memmove+35>: decl %edi
0x80045a24 <memmove+36>: jne 0x80045a1d <memmove+29>
0x80045a26 <memmove+38>: movl 0x8(%ebp),%eax
0x80045a29 <memmove+41>: popl %esi
0x80045a2a <memmove+42>: popl %edi
0x80045a2b <memmove+43>: movl %ebp,%esp
0x80045a2d <memmove+45>: popl %ebp
0x80045a2e <memmove+46>: ret
0x80045a2f <memmove+47>: nop
0x80045a30 <memmove+48>: movb (%esi),%dl
0x80045a32 <memmove+50>: incl %esi
0x80045a33 <memmove+51>: movb %dl,(%ecx)
0x80045a35 <memmove+53>: incl %ecx
0x80045a36 <memmove+54>: decl %edi
0x80045a37 <memmove+55>: jne 0x80045a30 <memmove+48>
0x80045a39 <memmove+57>: jmp 0x80045a26 <memmove+38>
memcpy is speed/perfect (however, frame pointer is not set)
0x800197a8 <memcpy>: movl %edi,%edx
0x800197aa <memcpy+2>: pushl %esi
0x800197ab <memcpy+3>: movl 0x8(%esp,1),%edi
0x800197af <memcpy+7>: movl 0xc(%esp,1),%esi
0x800197b3 <memcpy+11>: movl 0x10(%esp,1),%ecx
0x800197b7 <memcpy+15>: movl %edi,%eax
0x800197b9 <memcpy+17>: shrl $0x2,%ecx
0x800197bc <memcpy+20>: repz movsl %ds:(%esi),%es:(%edi)
0x800197be <memcpy+22>: movl 0x10(%esp,1),%ecx
0x800197c2 <memcpy+26>: andl $0x3,%ecx
0x800197c5 <memcpy+29>: repz movsb %ds:(%esi),%es:(%edi)
0x800197c7 <memcpy+31>: popl %esi
0x800197c8 <memcpy+32>: movl %edx,%edi
0x800197ca <memcpy+34>: ret
What can I do in C programs if I want to call the real memcpy instead of
bcopy ?
I could code a ASM bcopy function that can be put in libgcc.a but I
would prefer a native call.
Thanks
Eric Dumazet
More information about the Gcc
mailing list