2009-09-25 2 views
10

" 'ASM'에서 불가능 제약". 컴파일러는 응답 GCC testasm.c의 -otestasm
: " 'ASM'에서 불가능 제약"나는 testasm.c
으로 다음 코드를 저장하고 그것을 컴파일.리눅스 어셈블러 오류가 나는 리눅스에서 어셈블러로 시작하고

#include <stdio.h> 
int main(void) 
{ 
    int foo=10,bar=15; 

    __asm__ __volatile__ ("addl %%ebx,%%eax" 
     : "=eax"(foo) 
     : "eax"(foo), "ebx"(bar) 
     : "eax" 
    ); 

    printf("foo = %d", foo); 

    return 0; 
} 

이 문제를 어떻게 해결할 수 있습니까? (나는 here에서 예를 복사했습니다.)

데비안 레니, 커널 2.6.26-2-AMD64
GCC 버전 4.3.2 (데비안 4.3.2-1.1)

해결 :
허용되는 답변보기 - 수정 된 절이 더 이상 지원되지 않는 것 같습니다.

답변

9
__asm__ __volatile__ ("addl %%ebx,%%eax" : "=a"(foo) : "a"(foo), "b"(bar)); 

나는 어떤 시점에서 레지스터 제약 조건에 대한 구문이 바뀌었지만 그것이별로 잘 문서화되어 있지 않다고 믿는다. 원시 어셈블리를 작성하고 번거 로움을 피하는 것이 더 쉽습니다. 하나는 여러 줄을 사용하고자 할 경우

+0

감사합니다. 더 이상 '수정 된'절이 마음에 들지 않으므로 내가 바꿀 때마다 & 밀어 넣어야 할 것입니다. – slashmais

+2

수정 된 절은 여전히 ​​작동합니다. 문제는 "출력"이 암시 적으로 "수정 됨"을 지정하므로 두 필드 모두에서 나타나는 eax를 사용하는 것이 문제의 원인이라고 생각합니다. –

0

,이 또한 '\'..

__asm__ __volatile__ (
     "addl %%ebx,%%eax; \ 
     addl %%eax, %%eax;" 
     : "=a"(foo) 
     : "a"(foo), "b"(bar) 
    ); 

작동하는 여러 캐릭터 라인 (지침)을 채택하도록 컴파일러에 추가해야합니다.

+0

이것은별로 좋은 조언이 아닙니다. 입력 및 출력 목록에 사용할 레지스터를 지정하지만 실제 어셈블리 블록 내부에는 여전히 하드 코드 된 레지스터를 사용합니다. 대신에 '% 0'과'% 1'을 사용해야합니다. –

+0

@DanielKamilKozar : 허용 된 대답은 모든 것을 한 줄로 처리했습니다. 그래서, 동일한/유사한 코드를 사용하여 다중 행에서이를 수행하는 방법을 보여 줬습니다. 나는 하나의 멀티 라인을 비교할 때 더 쉽게 이해할 수있을 것이라고 생각하면서 원래 받아 들인 대답에 사용 된 하드 코드 된 레지스터를 수정하려하지 않았다. –

5

제약 조건은 단일 글자이며 (추가 장식이있는 경우도 있음) 몇 가지 대안을 지정할 수 있습니다 (즉, 중간 피연산자 또는 레지스터가 "ir"임). 따라서 "eax"라는 제약은 "e"(부호있는 32 비트 정수), "a"(레지스터 eax) 또는 "x"(모든 SSE 레지스터)를 의미합니다. 즉 영업 이익은 의미 ... 그리고 "E"명확하게 이해가되지 않습니다에 출력 어떤 것을 조금 다르다. 또한 일부 피연산자 (이 경우 입력 및 출력)가 다른 것과 동일해야하는 경우 숫자 제약 조건으로 참조하십시오. eax가 clobbered라고 말할 필요는 없습니다. 결과물입니다. 인라인 코드의 인수를 % 0, % 1, ...로 참조 할 수 있으며 명시 적 레지스터 이름을 사용할 필요가 없습니다.

#include <stdio.h> 

int main(void) 
{ 
    int foo=10, bar=15; 

    __asm__ __volatile__ (
     "addl %2, %0" 
     : "=a" (foo) 
     : "0" (foo), "b" (bar) 
    ); 

    printf("foo = %d", foo); 

    return 0; 
} 

더 나은 솔루션 % 2 아무것도 할 수 있도록하는 것, 그리고 % 0 레지스터 (86가 허용하는,하지만 당신은해야 할 것 : 그래서 OP에 의해 의도 한대로 코드에 대한 올바른 버전이 될 것이다 기계 설명서 확인) :

#include <stdio.h> 

int main(void) 
{ 
    int foo=10, bar=15; 

    __asm__ __volatile__ (
     "addl %2, %0" 
     : "=r" (foo) 
     : "0" (foo), "g" (bar) 
    ); 

    printf("foo = %d", foo); 

    return 0; 
} 
관련 문제