簡體   English   中英

C 函數調用的 ARM 匯編函數中的寄存器使用

[英]Register usage in ARM assembly function which is called by a C function

ARM 的 C 函數調用約定說:

  • 調用者將在 r0-r3 中傳遞前 4 個參數。
  • 調用者將在堆棧上傳遞任何額外的參數。
  • 調用者將從 r0 獲取返回值。

我正在手工編寫一個由 C 調用的匯編函數。原型相當於:

void s(void);

假設 C 函數c()調用s()

由於s()沒有參數也沒有返回值。 我相信r0-r3不會被編譯器觸及來生成c()調用s()的調用序列。

假設s()將使用r0-r12來完成其功能。 c()也有可能使用這些寄存器。

我不確定是否必須明確保存和恢復s()涉及的所有寄存器,比如r0-r12 這樣的內存操作會花費一些時間。

或者至少我不必為r0-r3這樣做?

來自Arm 架構的過程調用標准,第 6.1.1 節(第 19 頁):

子程序必須保留寄存器 r4-r8、r10、r11 和 SP(以及將 r9 指定為 v6 的 PCS 變體中的 r9)的內容

所以是的,因為 r0-r3 是臨時寄存器,您不需要在s()使用它們之前保存它們,但是您必須保存和恢復任何其他寄存器。

假設編譯器符合 ARM ABI,然后像這樣聲明s()

extern void s(void);

應該就足夠了,並且編譯器不應該在調用s()之后發出依賴於c()函數中先前的 r0-r3 值的代碼(即c()應該在調用s()之前根據需要保存 r0-r3 和之后恢復它們),因為這會破壞 ABI 合規性。

通常,在混合 C 和 asm 時,您永遠無法對 C 代碼使用的寄存器做出任何假設,除了那些保證被調用約定堆疊的寄存器。 在使用它們之前堆疊所有其他寄存器,然后稍后彈出它們。 所有這些都取決於編譯器在調用匯編程序函數時在內部做出和沒有做出的假設。

這里有一些不錯的信息: Mixing C, C++, and Assembly Language

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM