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;
}ide
rep ; movsl 的工做流程以下:优化
while(ecx) {
movl (%esi), (%edi);
esi += 4;
edi += 4;
ecx--;
} 工作流
rep ; movsb 与此相似,只是每次拷贝的不是双字(4字节),而是字节。it
"=&D" (d1) 不是想将 edi 的最终值输出到 d1 中,而是想告诉 gcc edi的值早就改了,不要认为它的值仍是初始化时的 dest,避免"吝啬的" gcc 把修改了的 edi 还当作 dest 来用。 而 d0、d一、d2 在开启优化后会被 gcc 无视掉(输出到它们的值没有被用过)。
memcpy 先复制一个一个的双字,到最后若是还有没复制完的(少于4个字节),再一个一个字节地复制。asm