2011-12-07 74 views
0

如何將基於堆棧的結構傳遞給ARM程序集中的子例程?在ARM中調用基於堆棧的結構的約定?

例如:

typedef struct SomeStruct { 
    uint32_t one; 
    uint32_t two; 
    uint32_t three; 
    uint32_t four; 
} SomeStruct; 

void SomeFunction(uint32_t someValue, SomeStruct someStruct, uint32_t otherValue); 

在這種情況下,如何將結構傳遞?我的猜測是:

  • r0 - someValue
  • r1 - someStruct.one
  • r2 - someStruct.two
  • r3 - someStruct.three
  • *sp - someStruct.four
  • *sp,#4 - otherValue

這是正確的還是會發生其他事情?或者只是通過結構的sp基地址?

+0

現在我想起來了,我的猜測聽起來很愚蠢。 –

+0

除非你的結構非常小,否則直接傳遞結構並不常見。如果你只是傳遞一個指向結構體的指針,那麼調用該函數的開銷就會減少。 – TJD

+0

@TJD:雖然這是有問題的,因爲參數在邏輯上是一個副本。因此,如果調用者執行'SomeFunction(1,my_global_struct,1);'並且被調用者執行'if(&someStruct ==&my_global_struct)',那麼當然必須是false。所以調用約定可以傳遞一個指針,這可能會有所幫助,但可能被調用者仍然需要拷貝一個拷貝,在這種情況下,它不會少開銷。 –

回答

4

有一個「過程調用標準」的ARM ABI這裏:http://infocenter.arm.com/help/topic/com.arm.doc.ihi0042d/IHI0042D_aapcs.pdf

有64位ARM不止一個ABI爲ARM,多了,但只是在看這一項,相關部門是「5.5參數傳遞」。乍一看,我認爲C.5說你是對的,這個結構將在r1-r3和堆棧之間分開。

B.1,它可以用指向內存中副本的指針替換組合類型的參數,因爲調用者和被調用者都必須有SomeStruct作爲完整類型才能通過值傳遞,所以它不會應用於C中。

+0

我沒有特別看過ARM ABI,但是通過調用者傳遞地址來處理結構的傳遞和返回是非常普遍的。如果被調用的函數是用C編寫的,則該地址不會暴露給用戶代碼;相反,編譯器通常會生成代碼來複制結構。如果一個例程只調用一次,那麼調用者進行復制會更好,但是大多數例程會被調用足夠的次數,以致被調用的代碼執行復制的效率更高。 – supercat