2013-05-28 135 views
0

我希望將svc#編成c代碼。現在我可以使用程序集來佔用svc的值。cortex m3 svc with gcc inline assembly

SVC_Handler: 
    tst lr, #0x4 
    ite eq 
    mrseq r0, msp 
    mrsne r0, psp 
    b SVC_Handler_C 

    void SVC_Handler_C(unsigned int *svc_args) 
    { 
     unsigned int svc_number; 
     svc_number=((char *)svc_args[6])[-2]; 

但我希望將它翻譯成c代碼中的內聯彙編。但我發現sp會通過局部變量的函數輸入或其他東西來修改。有沒有可能解決這個問題?謝謝

回答

2

我假設你只是想內聯彙編代碼。如果是這種情況,那麼請嘗試以下操作:

__attribute__((naked)) void SVC_Handler(void) { 
    __asm__ __volatile__ (
    " tst  lr, #0x4   \n\t" 
    " ite  eq     \n\t" 
    " mrseq r0, msp    \n\t" 
    " mrsne r0, psp    \n\t" 
    " b SVC_Handler_C   \n\t"); 
} 

然後再編寫SVC_Handler_C當作普通的C函數。

+0

如果你這樣寫,那麼也使它'__attribute __((noreturn))';-) –

+0

你能否詳細說明爲什麼還需要屬性'noreturn'?謝謝。 – BlueSky

+0

不是_needed_,但是一個好主意,因爲它阻止編譯器在函數末尾('b lr')創建「正常」返回。只要在編譯上面的/不使用它時檢查拆卸差異。 –

-1

在藍天的版本稍有變化:

__attribute__((naked)) void SVC_Handler(void) { 
    register unsigned int *svc_args __asm__("r0"); 

    __asm__ __volatile__ (
     "tst  lr, #0x4 
     ite  eq 
     mrseq %0, msp 
     mrsne %0, psp" : "=r"(svc_args)); 

    return SVC_Handler_C(svc_args); 
} 

我很驚訝,雖然你沒有考慮簡單的處理直接使C函數和檢索通過上述小聯彙編塊的論點。

+0

由於裸體,這不能正常工作,因爲函數處理函數的末尾沒有返回。結果,代碼掉到了下一個相鄰的代碼中,並且在我的情況下陷入了一個無限循環,調用了SVC_Handler_C,它是相鄰的。 –

+0

@WieserSoftwareLtd那裏可能存在編譯器依賴關係。在我嘗試的情況下,編譯器沒有爲'return SVC_Handler()'做一個'bx'(但是通過直接'b ...'尾部遞歸的,因此_不能通過__)。你生成的程序集是什麼?另見BlueSky上面的最後一條評論 - 與_very_相關。 –