문제

어셈블리 코드를 C/C ++ 프로그램에 포함시킬 때 푸시 명령어로 저장하여 클로버링 레지스터를 피할 수 있습니다 (또는 클로버 컴파일러 목록을 지정).

어셈블리를 인라인으로 포함하고 있으며 Clobbered Register를 밀고 튀어 나오는 오버 헤드를 피하려면 GCC가 귀하를 위해 레지스터를 선택할 수있는 방법이 있습니까 (예 : 유용한 정보가 없음).

도움이 되었습니까?

해결책

예. 특정 변수 (입력 또는 출력)가 레지스터에 저장되도록 지정할 수 있지만 레지스터를 지정할 필요는 없습니다. 보다 이 문서 자세한 설명을 위해. 기본적으로 인라인 어셈블리는 다음과 같습니다.

asm("your assembly instructions"
      : output1("=a"),  // I want output1 in the eax register
        output2("=r"),  // output2 can be in any general-purpose register
        output3("=q"),  // output3 can be in eax, ebx, ecx, or edx
        output4("=A")   // output4 can be in eax or edx
      : /* inputs */
      : /* clobbered registers */
   );

다른 팁

컴파일러 내입 어셈블리와 C/C ++ 코드를 혼합하는 매우 유용한 방법입니다. 그들은 기능처럼 보이지만 실제로 개별 기본 지침에 직접 컴파일하는 선언 (컴파일러 내부의 특별한 경우). 이것은 당신에게 어셈블리에서 작동한다는 많은 제어를 제공하지만 레지스터 색칠과 스케줄을 컴파일러까지 둡니다.

그런 다음 일반적인 C 변수를 내재적으로 전달하고 컴파일러가 레지스터에로드하고 주변의 다른 OPS를 예약하게 할 수 있다는 것입니다. 예를 들어,

struct TwoVectors
{
   __m128 a; __m128b;
}

// adds two vectors A += B using the native SSE opcode
inline void SimdADD( TwoVectors *v ) 
{
   v->a = _mm_add_ps( v->a , v->b ); // compiles directly to ADDSS opcode
}

좋아, 그래서 위의 의견을 남길 수는 없지만 올바른 구문 (위에 표시된 것과는 다름)은 다음과 같습니다.

asm ( "your assembly instructions"
    : "=a"(output1),
      "=r"(output2),
      "=q"(output3),
      "=A"(output4)
    : /* inputs */
    : /* clobbered registers */
);

입력 및 출력 레지스터를 컴파일러에 할당 할 수는 있지만, 스크래치/온도 레지스터 (예 : 중간 값에 사용되지만 입력 또는 출력에 사용되지 않음)를 컴파일러에 남겨 두는 명백한 방법은 없습니다. 역사적으로, 나는 방금 clobber 목록 (예 : "%xmm1", "%rcx")에 명시 적으로 나열되었지만 이제 컴파일러가 선택할 수 있도록 출력으로 나열하는 것이 더 나을 것이라고 생각합니다. 이 문제를 결정적으로 다루는 소스는 모릅니다.

라이센스 : CC-BY-SA ~와 함께 속성
제휴하지 않습니다 StackOverflow
scroll top