2014-11-14 6 views
0

AVR 용 RPC 라이브러리를 작성 중이며 일부 인라인 어셈블러 코드에 함수 주소를 전달하고 어셈블러 코드 내에서 함수를 호출해야합니다. 그러나 어셈블러는 함수를 직접 호출하려고 할 때 불평합니다.gcc 인라인 어셈블러 (avr-gcc)에 전달 된 const 함수 주소 주소

이 최소한의 예 Test.cpp에 (나는 인수를 전달하고있어 실제 경우와 함수는 템플릿 클래스의 정적 멤버의 실체화) 문제를 보여

void bar() { 
    return; 
} 

void foo() { 
    asm volatile (
     "call %0" "\n" 
     : 
     : "p" (bar) 
    ); 
} 

avr-gcc -S test.cpp -o test.S -mmcu=atmega328p로 컴파일하는 것은 잘 작동 내가 함께 조립하려고 할 때하지만 불평 avr-gcc -c test.S -o test.o -mmcu=atmega328p AVR-같이

test.c: Assembler messages: 
test.c:38: Error: garbage at end of line 

나는 그것이 "TEST.C"가 참조되는 파일 라인 (38)에 포함되어 test.S이다를 기록 왜 아무 생각이 없다 :

012 3,516,
call gs(_Z3barv) 

내가 here을 찾을 수있는 인라인 어셈블러에 있었던 파라미터의 모든 심지어 원격으로 합리적인 제약을 시도했지만 나는 시도 그 중 어느 것도 작동하지 않습니다.

gs() 부분이 제거 되었으면 모든 것이 작동하지만 모든 제약 조건이이를 추가하는 것 같습니다. 나는 그것이 무엇을하는지 전혀 모른다.

ldi r30, lo8(gs(_Z3barv)) 
ldi r31, hi8(gs(_Z3barv)) 
icall 

그리고 어떤 불평하지 않는 AVR-같이

void bar() { 
    return; 
} 

void foo() { 
    asm volatile (
     "ldi r30, lo8(%0)" "\n" 
     "ldi r31, hi8(%0)" "\n" 
     "icall" "\n" 
     : 
     : "p" (bar) 
    ); 
} 

어셈블러는이 같은 모습을 만들어 :

이상한 것은이 같은 간접 호출을 수행하는 것은 잘 조립이다 찌꺼기.

답변

1

call은 일정한 알려진 어셈블리시 값을 요구합니다. "p" 제약 조건에는 해당 의미가 포함되어 있지 않습니다. 이 처리 할 수없는 변수 (예 : char* x)의 포인터도 허용됩니다. (때로는 gcc가 "p"가 여기에서 작동하는 방식으로 최적화 할 수있을 정도로 영리하다는 것을 기억하는 것 같습니다. 기본적으로 문서화되지 않은 동작이며 비 결정적이기 때문에 더 중요하지는 않습니다.)

실제로 컴파일 타임 상수라고하면 "i" (bar)을 사용할 수 있습니다. 그렇지 않다면, 이미 알아 낸대로 icall을 사용하는 것 외에 다른 선택의 여지가 없습니다.

Btw, https://gcc.gnu.org/onlinedocs/gcc/Machine-Constraints.html#Machine-Constraints의 AVR 섹션에는 AVR 관련 제약이 더 기록되어 있습니다.