2012-02-28 4 views
1

C 코드를 리버스 엔지니어링하려고합니다.하지만 어셈블리의이 부분은 실제로 이해할 수 없습니다. 나는 그것이 SSE 확장의 일부라는 것을 알고있다. 그러나, 일부는 x86 명령어에서 익숙했던 것과는 정말로 다릅니다.C 코드의 SSE2 명령어

static int sad16_sse2(void *v, uint8_t *blk2, uint8_t *blk1, int stride, int h) 
{ 
    int ret; 
    __asm__ volatile(
     "pxor %%xmm6, %%xmm6   \n\t" 
     ASMALIGN(4) 
     "1:        \n\t" 
     "movdqu (%1), %%xmm0   \n\t" 
     "movdqu (%1, %3), %%xmm1  \n\t" 
     "psadbw (%2), %%xmm0   \n\t" 
     "psadbw (%2, %3), %%xmm1  \n\t" 
     "paddw %%xmm0, %%xmm6   \n\t" 
     "paddw %%xmm1, %%xmm6   \n\t" 
     "lea (%1,%3,2), %1    \n\t" 
     "lea (%2,%3,2), %2    \n\t" 
     "sub $2, %0      \n\t" 
     " jg 1b       \n\t" 
     : "+r" (h), "+r" (blk1), "+r" (blk2) 
     : "r" ((x86_reg)stride) 
    ); 
    __asm__ volatile(
     "movhlps %%xmm6, %%xmm0   \n\t" 
     "paddw %%xmm0, %%xmm6   \n\t" 
     "movd %%xmm6, %0    \n\t" 
     : "=r"(ret) 
    ); 
    return ret; 
} 

% 1, % 2 및 % 3은 무엇입니까? (% 1, % 2, % 3)은 무엇을 의미합니까? 또한 "+ r", "-r", "= r"은 무엇을 의미합니까?

+0

이 코드에서는 _two disjointed_ inline 어셈블리 블록을 사용할 수 없습니다. 그것은 작동하지만 그것은 무한한 지혜로운 컴파일러가 입력하기 전에 두 번째'__asm__' 블록의 "선언되지 않은 입력"(regs'% xmm0' /'% xmm6')을 사용하여 무언가를 할 수도 있기 때문에 보장 할 수 없습니다. 수정 방법에 대한 자세한 내용은 http://stackoverflow.com/questions/8891139/why-is-this-inline-assembly-not-working를 참조하십시오. –

답변

2

너는 이것을 GCC Inline Asssembly HOWTO에보고 싶을 것이다.

백분율 기호 숫자는 명령어 피연산자입니다.

0

인라인 어셈블러는 매크로 전 처리기와 유사하게 작동합니다. 그들은 파라미터리스트에 표시 한 선도 정확히 퍼센트 피연산자이 경우, 순서대로 입력 매개 변수로 대체된다

%0 h    output, register, r/w 
%1 blk1    output, register, r/w 
%2 blk2    output, register, r/w 
%3 (x86_reg)stride input, register, read only 

파라미터는 일반 식 C이다. 이들은 "constraints"에 의해 추가로 지정 될 수 있습니다.이 경우 "r"은 메모리 피연산자 인 "m"과 반대되는 레지스터에 값이 있어야 함을 의미합니다. 제약 조건 수정 자 "= r"은 쓰기 전용 피연산자로 만들고 "+ r"은 읽기/쓰기 피연산자이고 "r"및 일반 읽기 피연산자입니다.

첫 번째 콜론 다음에는 출력 피연산자가 두 번째 입력 피연산자 뒤에 나타나고 선택적인 세 번째 피연산자 레지스터 뒤에 나타납니다.

따라서 명령어 시퀀스는 각 바이트의 blk1blk2의 절대 차이의 합을 계산합니다. 이것은 16 바이트 블록에서 발생하므로 stride이 16이면 블록이 연속적으로 나타나고 그렇지 않으면 구멍이 있습니다. 일부 명령어는 두 번 나타납니다. 최소 루프 풀기가 수행 되었기 때문에 h 매개 변수는 처리 할 32 바이트 블록 수입니다. psadbw 명령은 대상 레지스터의 하위 16 비트에서만 요약되므로 두 번째 asm 블록은 쓸모없는 것처럼 보입니다. (일부 코드를 생략 했습니까?)