The Principle and Implementation of the Memory Copy Function memcpy in Embedded C

I am Lao Wen, an embedded engineer who loves learning.Follow me, and let’s become better together!

The Memory Copy Function memcpy

memcpy is short for memory copy, which means copying memory. We often use it when writing C programs. Its function prototype is as follows:

void *memcpy(void *dest, const void *src, size_t n);

Its function is to copy n bytes of data from the starting position of src to dest. If there is data in dest, it will be overwritten. The return value of the memcpy function is a pointer to dest. The memcpy function is defined in the string.h header file.When implementing it yourself, the simplest method is to use pointers to copy byte by byte. However, the performance is too low:

  • First, copying one byte at a time is inefficient; the address bus is generally 32 bits, which can carry 4 bytes at a time, so copying one byte at a time is definitely too slow;
  • Second, when the memory areas overlap, confusion can occur.

Next, we will consider improving the performance of the memcpy function based on the above two aspects.First, consider speed; we can copy data according to the CPU word width for higher efficiency. The code is as follows:

void * Memcpy1(void *dst, const void *src, size_t num)
{
int nchunks = num/sizeof(dst);   /* Copy according to CPU word width */

cout<<"sizeof(dst) is:"<<sizeof(dst)<<endl;

int slice =   num%sizeof(dst);   /* Copy the remaining bytes */

unsigned long * s = (unsigned long *)src;
unsigned long * d = (unsigned long *)dst;

while(nchunks--)
     *d++ = *s++;
     
while (slice--)
     *((char *)d++) =*((char *)s++);
     
return dst;
}

sizeof(dst) is 4, meaning that most data is copied 4 bytes at a time, and the remaining bytes are copied individually. However, this method cannot avoid memory confusion when the memory areas overlap.The following method can avoid the memory overlap bug. The code is as follows:

void *Memcpy2(void *dest, const void *src, size_t count)  
{  
char *d;  
const char *s;  
   
if (((int)dest > ((int)src+count)) || (dest < src))  
    {  
    d = (char*)dest;  
    s = (char*)src;  
    while (count--)  
        *d++ = *s++;          
    }  
else/* overlap */  
    {  
    d = (char *)((int)dest + count - 1); /* Start copying from the end, note the offset */  
    s = (char *)((int)src + count - 1);  
    while (count --)  
        *d-- = *s--;  
    }  
    
return dest;  
}  

If overlapping memory areas are detected, copying is performed byte by byte starting from the end.However, when the data volume is large, the speed is slow. By combining the two methods, we can improve the performance of the copy function. The code is as follows:

void *Memcpy(void *dest, const void *src, size_t count)  
{  
   cout<<"sizeof(dest) is:"<<sizeof(dest)<<endl;
   int bytelen=count/sizeof(dest); /* Copy according to CPU word width */  
   int slice=count%sizeof(dest); /* Copy the remaining bytes */  
   unsigned int* d = (unsigned int*)dest;  
    unsigned int* s = (unsigned int*)src;  

if (((int)dest > ((int)src+count)) || (dest < src))  
    {  
      while (bytelen--)  
        *d++ = *s++;  
      while (slice--)  
        *(char *)d++ = *(char *)s++; 
    }  
else/* overlap */  
    {  
    d = (unsigned int*)((unsigned int)dest + count - 4); /* Start copying from the end, note the offset */  
    s = (unsigned int*)((unsigned int)src + count - 4);  
    while (bytelen --)  
        *d-- = *s--;  
 d++;s++;
char * d1=(char *)d;
char * s1=(char *)s;
 d1--;s1--;
while (slice --)  
        *(char *)d1-- = *(char *)s1--; 
    }  
return dest;  
}  

Let’s compare the test code as follows:

int main(){
 char a[20]="1133224466558877990";
// Memcpy1(a+2,a,5);
// Memcpy2(a+2,a,5);
 Memcpy(a+2,a,5);
 cout<<a<<endl;
 cin.get();
}

The results are:

Memcpy1:<span><span>1111333466558877990</span></span>Memcpy2:<span><span>1111332466558877990</span></span>Memcpy:<span><span>1111332466558877990 </span></span>

The last two methods are correct, while the first method cannot avoid the memory overlap bug during copying.

Original text: https://blog.csdn.net/wyk71456/article/details/108424816

-END-

Previous recommendations: Click the image to readThe Principle and Implementation of the Memory Copy Function memcpy in Embedded C

Embedded devices in industrial sites can be terrifying if they are hacked or attacked online!

The Principle and Implementation of the Memory Copy Function memcpy in Embedded C

Bad habits in embedded software development that engineers should avoid!

The Principle and Implementation of the Memory Copy Function memcpy in Embedded C

In addition to coding and hardware design, what other aspects are important for excellent embedded products?

I am Lao Wen, an embedded engineer who loves learning.Follow me, and let’s become better together!

Leave a Comment