2013-01-24 3 views
2

디버그 구성을 사용하여 문제가없는 Xcode (4.5.2) 프로젝트가 있습니다. 그러나 이제 릴리스 구성을 작성하기 위해 문제가 발생했습니다. 즉, 인라인 어셈블리 함수 중 하나가 오류 Invalid symbol redefinition을 얻는 중입니다. 그 오류 메시지를 검색하는 것은 저에게 컴파일러 오류가있는 사람을 찾았지 만 그것이 의미하는 바에 관한 정보는 없습니다. 내가 __sub 보호 된 이름이 될 거라고 생각하기 때문에 __sbt__sub를 대체하려고했습니다LLVM의 인라인 ASM에서 "유효하지 않은 심볼 재정의"

inline int MulDivAdd(int nNumber, 
       int nNumerator, 
       int nDenominator, 
       int nToAdd) 
{ 
    int nRet; 

    __asm__ __volatile__ (
     "mov %4,  %%ecx \n" 
     "mov %1,  %%eax \n" 
     "mull %2    \n" 
     "cmp $0,  %%ecx \n" 
     "jl  __sub   \n" 
     "addl %%ecx, %%eax \n" 
     "adc $0,  %%edx \n" 
     "jmp __div   \n" 
    "__sub:      \n" // "Invalid symbol redefinition" 
     "neg %%ecx   \n" 
     "subl %%ecx, %%eax \n" 
     "sbb $0,  %%edx \n" 
    "__div:      \n" // "Invalid symbol redefinition" 
     "divl %3    \n" 
     "mov %%eax, %0  \n" 

     : "=m" (nRet) 
     : "m"  (nNumber), 
      "m"  (nNumerator), 
      "m"  (nDenominator), 
      "m"  (nToAdd) 
     : "eax", "ecx", "edx" 

    ); 

    return nRet; 
} 

하지만이 사건이 아니었다 다음은 기능은 주석 오류 라인,이다. 왜 이것이 릴리스에서만 발생하는지 이해하지 못합니다 - 최적화로 인한 것일 수 있습니까? 같은 1:2:jxx 1f 또는 jxx 1b 같은

+0

C로 작성하면 ('int64_t'를 사용하면) 더 나은 codegen을 얻을 수 있습니다. 분기는 완전히 불필요합니다 (부호 확장 및 추가가되어야합니다). 또한 서명 된 데이터와 함께 부호없는 곱하기 명령어 ('mull')를 사용하면 문제가 발생합니다. 문제의 프로그램에 대해서는 중요하지 않지만 아마 버그 일 것입니다. –

+0

@StephenCanon 그래서이 wisecracking 질문에 관련이 있습니까? –

답변

11

사용 지역 레이블. 점프의 방향 (앞으로는 f, 뒤로는 b)이 필요합니다. 따라서 코드는 다음과 같아야합니다.

__asm__ __volatile__ (
    "mov %4,  %%ecx \n" 
    "mov %1,  %%eax \n" 
    "mull %2    \n" 
    "cmp $0,  %%ecx \n" 
    "jl  1f    \n" 
    "addl %%ecx, %%eax \n" 
    "adc $0,  %%edx \n" 
    "jmp 2f    \n" 
"1:       \n" 
    "neg %%ecx   \n" 
    "subl %%ecx, %%eax \n" 
    "sbb $0,  %%edx \n" 
"2:       \n" 
    "divl %3    \n" 
    "mov %%eax, %0  \n" 
) 

순수하게 숫자로 구성된 기호는 "함수의 지역 번호"입니다. "인라인"은 코드가 물리적으로 중복된다는 의미이므로 여러 심볼 정의를 얻는 이유는 기호가 실제로 "전역"방식으로 여러 번 정의된다는 것입니다.

물론 디버그 빌드가있는 경우 "인라인 없음"을 의미하므로 인라인 된 함수는 인라인되지 않으며 기호는 한 번만 선언되고 "작동"합니다.

[필자는이 효율성과 컴파일러 자체에 대해 다소 의의가 있습니다. 필자는 일부 입력에 대해 레지스터를 사용하는 것이 더 효율적이라고 생각했습니다.

+0

빠른 답변을 보내 주셔서 감사합니다. 효율성에 관해서는, 이것은 내가 옮겨 왔던 것입니다. 그래서 원래의 인텔 구문 ASM을 GAS로 번역했습니다. 나중에 그것을 최적화하려고 할 수도 있습니다. – benwad

+0

나는 그것을 C로 먼저 재 작성하고 그것이 어떻게되는지 보려고한다. [나는 무엇을하는지 확신 할 수는 없지만 많은 수학 함수의 일부처럼 보입니다. 그러나 그것은 완전히 틀릴 수 있습니다.] –

+0

점프 타겟에서'f'와'b' 접미어가 무엇을 의미하는지 설명 할 수 있습니다 =) –