2012-05-31 2 views
1

인라인 어셈블러에서 특정 값을 일부 레지스터로 복사하려고하지만 불만이 있습니다.ARM 인라인 어셈블러에서 특정 레지스터를 사용하는 방법

asm("" :: "r0" (value)); 
asm("" :: "a1" (value)); 

두 선이 트리거 :

Error: matching constraint references invalid operand number 

그래서 어떻게 직접 적용하려면 레지스터를 지정합니까이 짧은 오류를 트리거 할 코드의 버전? 나는 값의 이름을 소개하고 내 자신에 의해 복사 할 수 있지만이 코드는 더 짧고 읽기 쉽기 때문에 이것을 피하고 싶습니다.

왜 묻는가 현재 일부 syscalls에서 작업 중입니다. 다음과 같이 syscall 매크로를 사용하고 싶습니다.

#define SYSCALL0(NUMBER) asm("swi #" STRINGIFY(NUMBER)); 
#define SYSCALL1(NUMBER, A) asm("swi #" STRINGIFY(NUMBER) :: "r0"(A)); 
#define SYSCALL2(NUMBER, A, B) asm("swi #" STRINGIFY(NUMBER) :: "r0"(A), "r1"(B)); 
... 

이 내용은 온라인에 잘 들어 맞습니다. 은 물론 내가 좋아하는 뭔가를 할 수 :

#define SYSCALL1(NUMBER, A) register type R0 asm("r0") = A; 
          SYSCALL0(NUMBER) 

을하지만 나는 어떤 유형의 오류를 얻을 아니면 다른 기능에 매크로를 사용 type 제대로 마다을주고 typeA을 변환해야합니다.

register long r0 asm ("r0"); 

그런 다음 r0 "별칭"등록 : GCC와

답변

1

는 바로 가기가있다.

statement expression과 결합하면 r0을 "반환 값"으로 사용할 수도 있습니다.

#define SYSCALL1(NUMBER,A) ({\ 
    register long r0 asm("r0") = (long) (A); \ 
    asm("swi #" STRINGIFY(NUMBER) : "=r"(r0) : "r"(r0) : "memory"); \ 
    r0; }) 

extended assemblylocal reg vars을 참조하십시오 (원상 복구가 합법적인지 아닌지 나는 전혀 모른다는 uClibc와의 콜 구현하는 것이 생각.있다).

+0

예, 알고 있었지만 긴 구문이 마음에 들지 않습니다. 나는 나의 동기를 보여주기 위해 나의 질문을 업데이트 할 것이다. – Nobody

+0

처리하는 모든 레지스터가 동일한 "C 유형"(long)이 아닙니까? – Mat

+0

레지스터는이 유형이지만 들어오는 변수는 매번 캐스팅을해야하므로 임의의 유형 (예 : int, char *, void (fn *) (void), ...)을 가질 수 있습니다. 그것은 불가능하다는 것이 아니라 정말로 추악합니다. – Nobody

관련 문제