我需要在我的newlib存根中調用一些系統調用,而當前的實現使用C宏,這些宏隨着時間的推移變得難以閱讀和糟糕。 (我討厭宏...) 但是,我的C++模板實現不只有一個參數工作:作爲C++模板的ARM系統調用
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;
}
現在我可以調用例如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不再尊重「註冊」變量。 例子:我在SVC指令設置一個斷點,並執行
syscall<FWRITE, int>(ptr, 1, len, f)
但不知何故,r0設置爲1,R1爲PTR ...... 我也試過沒有優化編譯,寄存器只是爲了改變位,但它仍然是錯誤的順序。我知道我可以做「mov r0,%[param1]」等,但這會阻止優化,因此會導致代碼變慢。
這是GCC(4.8.2)中的錯誤還是我忽略了某些東西?
這看起來都很笨拙: -/...我會盡量避免使用C++代碼中的'asm'! –
另請注意,註冊關鍵字已被棄用了一段時間... –
相信我,我會如果我可以;-) – Fabian