static __always_inline void *__memcpy(void *to, const void *from, size_t n) { int d0, d1, d2; asm volatile("rep ; movsl\n\t" "movl %4,%%ecx\n\t" "andl $3,%%ecx\n\t" "jz 1f\n\t" "rep ; movsb\n\t" "1:" : "=&c" (d0), "=&D" (d1), "=&S" (d2) #分别表示第零个操作数(%0)--到第二个(%2)操作数 : "0" (n / 4), "g" (n), "1" ((long)to), "2" ((long)from) #分别表示第三个操作数(%3)到第六个操作数(%6);其中%3个===第%0个;%5==%1;%6==%2 : "memory"); return to; }

n/4表示 传入的n是字节数,而这里拷贝是按四个字节一次来拷贝的。

rep ; movsl 的工作流程如下:

while(ecx) {
movl (%esi), (%edi);
esi += 4;
edi += 4;
ecx--;
}

rep ; movsb 与此类似,只是每次拷贝的不是双字(4字节),而是字节。

"=&D" (d1) 不是想将 edi 的最终值输出到 d1 中,而是想告诉 gcc edi的值早就改了,不要认为它的值还是初始化时的 dest,避免"吝啬的" gcc 把修改了的 edi 还当做 dest 来用。 而 d0、d1、d2 在开启优化后会被 gcc 无视掉(输出到它们的值没有被用过)。   memcpy 先复制一个一个的双字,到最后如果还有没复制完的(少于4个字节),再一个一个字节地复制。