2014-03-24 19 views
2

我需要在我的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)中的錯誤還是我忽略了某些東西?

+0

這看起來都很笨拙: -/...我會盡量避免使用C++代碼中的'asm'! –

+0

另請注意,註冊關鍵字已被棄用了一段時間... –

+0

相信我,我會如果我可以;-) – Fabian

回答

4

這是bug 33661,這是相當古老。我幾年前遇到過它。

+0

不是每天我點擊一個隨機的SO鏈接,結束閱讀支持的編譯器錯誤爲內聯彙編...帽子給你先生。 – asveikau

+0

偉大的:-( 解決方法:在模板中內聯全局非模板函數的工作原理很醜陋,但可行。 – Fabian