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;
}

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個字節),再一個一個字節地複製。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章