linux gcc內聯彙編分析memcpy

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

n/4表示 傳入的n是字節數,而這裏拷貝是按四個字節一次來拷貝的。

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

相關文章
相關標籤/搜索