memcopy()函数c语言实现和汇编实现比较

        今天突然心血来潮想起我前一家公司面试时遇到的一个面试题,就是实现个memcopy()函数。当初太紧张(刚毕业第二次面试),所以写的不是很好(可以说漏洞百出);现在刚学了点汇编,刚好就用两种语言实现下;

        首先来看汇编实现的memcpy函数,是利用宏函数来实现的,用汇编指令rep和movsb配合循环把数据以字节为单位从ds:esi传送到es:edi中,把循环次数放在ecx中。当然这样拷贝的才是真正的内存拷贝,其他的函数都稍微有点牵强。

 #define myMemcpy(dest, src, n) ({\
         void* _ret = dest;\
         __asm__("cld;rep;movsb"\
             ::"D"((long)(_ret)), "S"((long)(src)), "c"((long)(n)));\
         _ret;})
        在调试汇编实现的memcpy函数时,遇到个错误,这里记录下来:

        错误:myMemcpy.c: In function ‘main’:
    myMemcpy.c:15: error: can't find a register in class ‘CREG’ while reloading ‘asm’
    myMemcpy.c:15: error: ‘asm’ operand has impossible constraints


        发生这个错误是因为,我开始添加了 修改寄存器列表那一栏(添加了变更寄存器si, di, ex);查了下资料说是同一个变量两次出现时使用了同一个寄存器,就会报这样的错误。解决办法是把变更寄存器中那些寄存器名称用占位符替代(di==0;si==1;cx==2);但是还是不行,后来我干脆就把  修改寄存器列表 删了,因为我记得有些gcc编译器对于在输入输出中出现过的寄存器,不列入变更寄存器列表中;(我前几篇blog中也提到在输入输出中出现过的寄存器,不用添加到变更寄存器列表中去)但是有些版本的gcc却需要添加到变更寄存器那一栏;


        下面来看下c语言方式来实现memcpy函数,其实我感觉c语言来实现还是比较简单的,就是把输入的数据强制转换成字符来操作,因为在c语言中没有比字符更小的单位了。而对于是否返回ret,如果要多次使用memcpy的话(   myMemcpy1(xxx,  myMemcpy1(xx, xx, xx),  xx)    ),那肯定是要返回的。如果不需要就没必要和原来的memcpy()一样,不要太死板(不过还是建议要返回ret,可以考虑以后扩展)。

 void* myMemcpy1(void* dest, void* src, unsigned int n)
 {
     char* d = (char*)dest;
     char* s = (char*)src;
     char* ret = d;

     while(n--){
         *d++ = *s++;
     }   
     return ret;
 }

        好了,该实现的都实现了,现在来测试下,当然我调试通过了,感兴趣的可以试着调试下。

 
 int main(void)
 {
     char test1[] = "yuzhihui";
     char test2[1024] = {}; 
     char test3[1024] = {}; 
         
     myMemcpy(test2, test1, sizeof(test1));
     myMemcpy1(test3, test1, sizeof(test1));
 
     printf("test1:%s\n", test1);
     printf("test2:%s\n", test2);
     printf("test3:%s\n", test3);
 
     int t1 = 100;
     int t2 = 0;
     int t3 = 0;
 
     myMemcpy(&t2, &t1, sizeof(t1));
     myMemcpy1(&t3, &t1, sizeof(t1));
 
     printf("t1:%d\n", t1);
     printf("t2:%d\n", t2);
     printf("t3:%d\n", t3);
 
     return 0;
 }
        下面就贴下运行的结果:

                
        转载请注明作者和原文出处,原文地址:http://blog.csdn.net/yuzhihui_no1/article/details/43601757

        如果有什么不正确之处,欢迎大家指正,一起努力,共同学习!!


你可能感兴趣的:(面试,C语言,linux内核,内存拷贝,C中内嵌汇编)