이미 다 아는 바와 같이, memcpy는 메모리 영역을 복사하는 표준 C 함수이다. C 수준에서 가장 간단하게 그 아이디어를 표현하자면, 이렇게 쓸 수 있다.

void *
memcpy(void *dst, void *src, size_t n)
{
        char *d = dst, *s = src;
        while (n--)
                *d++ = *s++;
        return dst;
}
인텔계통의 32비트 CPU에서는 어셈블리어로 memcpy()를 구현하는 중에 가장 간단한 것은 다음과 같이 표현할 수 있다.
; x86에서 가장 간단한 memcpy
; void *memcpy(void *dst, void *src, size_t n)
memcpy  PROC C
        push    edi
        mov     edi,[esp+8]     ; dst
        mov     eax,edi         ; return value
        push    esi
        mov     esi,[esp+16]    ; src
        mov     ecx,[esp+20]    ; n
    rep movsb
        pop     esi
        pop     edi
        ret
memcpy  ENDP
이 코드는 위의 C코드를 직역한 것과 같다. 이러한 단순한 코드를 좀더 빠르게 만들려면, 4바이트 단위로 복사하면 되겠다.
; 약간 더 빠른 memcpy
; void *memcpy(void *dst, void *src, size_t n)
memcpy  PROC C
        push    edi
        mov     edi,[esp+8]     ; dst
        mov     eax,edi         ; return value
        push    esi
        mov     esi,[esp+16]    ; src
        mov     ecx,[esp+20]    ; n
        mov     edx,ecx
        shr     ecx,2
        and     edx,3
    rep movsd
        mov     ecx,edx
    rep movsb
        pop     esi
        pop     edi
        ret
memcpy  ENDP
물론, 요즘의 컴파일러들은 memcpy()를 rep movsd/rep movsb의 조합으로 알아서 최적화하므로, 위에서 보인 구현들은 최종 실행파일의 크기 줄이기 정도로 유용성이 제한된다.

memcpy 구현 연재 목록
[1] 가장 단순한 구현
[2] 주소 정렬
[3] MMX 이용
[4] SSE로 확장
[5] 그외의 고려사항들
[6] 초보가 빠지기 쉬운 함정
Posted by movsd
,