论网站建设技术的作者是谁,网站开发html php,html自学怎么入门,昵图网免费图片大全 图库 背景墙之前写过一篇关于 memcpy函数面试的文章几个简单的笔试题里面的代码使用的是char指针来实现#xff0c;今天我们来看看Linux下面的memcpy函数#xff0c;它的实现上还是有一些巧妙的。void * memcpy(void * dest, const void *src, size_t n)
{if (!(((unsigned long) dest ^… 之前写过一篇关于 memcpy函数面试的文章几个简单的笔试题里面的代码使用的是char指针来实现今天我们来看看Linux下面的memcpy函数它的实现上还是有一些巧妙的。void * memcpy(void * dest, const void *src, size_t n)
{if (!(((unsigned long) dest ^ (unsigned long) src) 7)) {__memcpy_aligned_up ((unsigned long) dest, (unsigned long) src,n);return dest;}__memcpy_unaligned_up ((unsigned long) dest, (unsigned long) src, n);return dest;
}首先函数会对参数判断地址是不是对齐的如果是对齐的话会调用对齐的内存拷贝函数如果是不对齐的话会调用不对其的函数。正常情况下地址都会是按4字节对齐的看看__memcpy_aligned_up 函数/** Hmm.. Strange. The __asm__ here is there to make gcc use an integer register* for the load-store. I dont know why, but it would seem that using a floating* point register for the move seems to slow things down (very small difference,* though).** Note the ordering to try to avoid load (and address generation) latencies.*/
static inline void __memcpy_aligned_up (unsigned long d, unsigned long s,long n)
{ALIGN_DEST_TO8_UP(d,s,n);n - 8;while (n 0) {unsigned long tmp;__asm__(ldq %0,%1:r (tmp):m (*(unsigned long *) s));n - 8;s 8;*(unsigned long *) d tmp;d 8;}n 8;DO_REST_ALIGNED_UP(d,s,n);
}我们直接看代码操作就很清楚了是按照8个字节来做的偏移我写了个测试程序测试程序和内核代码有一些小出入主要是我用的是devc来写代码unsigned long并不是8字节。测试代码如下#include stdio.h
#include string.hvoid * cris_memcpy(void *out, const void *in, unsigned int length) {if (!(((unsigned long) out ^ (unsigned long) in) 7)) {printf(aligned\n);} if (out NULL || in NULL) {return NULL;}while (length) {*(char*)out *(char*)in;length length - 1;}return out;
}typedef unsigned long long usize8_t;static inline void __memcpy_aligned_up (usize8_t d, usize8_t s,long n) {if (!(((usize8_t) d ^ (usize8_t) s) 7)) {printf(aligned\n);} //n - 8;printf(%d %d\n,n,sizeof(usize8_t));while (n 0) {usize8_t tmp;tmp *(usize8_t *) s;n - 8;s 8;*(usize8_t *) d tmp;d 8;}n 8;
}int main() {char a[20] happy new year;char b[20];char c[20];cris_memcpy(b, a, strlen(a));__memcpy_aligned_up(c, a, strlen(a));printf(a%s\n,a);printf(b%s\n,b);printf(c%s\n,c);return 0;
}代码输出最后如果觉得不错大家顺手点个赞转发就是对我最大的鼓励和支持长按识别二维码关注公众号