newlib 스텁에서 일부 syscalls를 호출해야하며 현재 구현에서는 읽을 수없고 끔찍한 C 매크로를 사용합니다.ARM syscall with C++ template
template <int nr, typename RETTYPE, typename PARAM1>
inline RETTYPE syscall(PARAM1 p1)
{
register PARAM1 r0 asm("r0") = p1;
asm volatile("svc %[nr]\n"
: "=r" (r0)
: [nr] "i" (nr), "r" (r0)
: "memory", "r1", "r2", "r3", "r12", "lr");
return (RETTYPE) r0;
}
지금 내가 호출 할 수 있습니다 예를 들면 : 그러나, C++ 템플릿 내 구현이 하나 개의 매개 변수에 대한 작동 하는가 (그리고 난 ... 매크로를 싫어) malloc 사용
void *ptr = syscall<SYS_MALLOC, void*>(0x1000);
0x1000 바이트를 할당합니다. 네 개의 매개 변수에 대한
내 구현 :
template <int nr, typename RETTYPE, typename PARAM1, typename PARAM2, typename PARAM3, typename PARAM4>
inline RETTYPE syscall(PARAM1 p1, PARAM2 p2, PARAM3 p3, PARAM4 p4)
{
register PARAM1 r0 asm("r0") = p1;
register PARAM2 r1 asm("r1") = p2;
register PARAM3 r2 asm("r2") = p3;
register PARAM4 r3 asm("r3") = p4;
asm volatile("svc %[nr]\n"
: "=r" (r0)
: [nr] "i" (nr), "r" (r0), "r" (r1), "r" (r2), "r" (r3)
: "memory", "r12", "lr");
return (RETTYPE) r0;
}
이 작동하지 않습니다는 "SWI"명령에서 레지스터의 내용은 임의입니다. 어떻게 든 GCC는 더 이상 "레지스터"변수를 존중하지 않습니다. 예 : I는 SVC 명령어에 중단 점을 설정하고
syscall<FWRITE, int>(ptr, 1, len, f)
실행 어쨌든 R0는 I는 최적화하지 않고 컴파일 시도 ... 를 ptr에하기 (1) 및 (R1)로 설정되어, 레지스터 막 순서 변경된 조금이지만 여전히 잘못된 순서입니다. 나는 "mov r0, % [param1]"등등을 할 수 있다는 것을 알고 있지만, 최적화를 막을 것이므로 느린 코드가됩니다.
GCC (4.8.2)의 버그입니까? 아니면 뭔가를 내려다 보았습니까?
그 모든 것이 매우 어색해 보입니다. -/... 나는 C++ 코드에서'asm'을 피하려고합니다! –
또한 'register' 키워드는 이미 잠시 동안 더 이상 사용되지 않습니다 ... –
나를 믿으십시오, 할 수만 있다면, ;-) – Fabian