WinCE 和 Linux 上的 ARM 呼叫約定


介紹

由於ARM處理器的低功耗、高效能和低成本,其架構在嵌入式系統和移動裝置中越來越受歡迎。它廣泛用於Windows CE和Linux等作業系統的開發。在本文中,我們將討論Windows CE和Linux上的ARM呼叫約定。

什麼是呼叫約定?

呼叫約定是一組規則,規定了程式中函式呼叫的方式。這些規則用於定義如何傳遞引數、如何處理返回值以及在函式呼叫期間如何管理堆疊。ARM架構有幾種不同的呼叫約定,它們因使用的作業系統而異。

Windows CE上的呼叫約定

Windows CE是為小型裝置(如手機和PDA)設計的即時作業系統。Windows CE中使用的ARM呼叫約定稱為Windows CE作業系統的ARM過程呼叫標準(APCS-CE)。

APCS-CE定義了函式呼叫的幾個規則。首先,函式的前四個引數透過暫存器r0到r3傳遞。如果引數超過四個,則在堆疊上傳遞。其次,函式的返回值透過暫存器r0傳遞。如果返回值大於32位,則透過暫存器r0和r1傳遞。

第三,堆疊以特定方式管理。當呼叫函式時,呼叫者負責將返回地址壓入堆疊。被呼叫者負責在其可以使用它們之前將其餘暫存器壓入堆疊。最後,堆疊與8位元組對齊。

示例

這是一個使用APCS-CE呼叫約定新增兩個數字的函式示例:

int add(int a, int b) { 
   int c; 
   __asm { 
      mov r0, a 
      mov r1, b 
      bl sum 
      mov c, r0 
   } 
   return c; 
}
int sum(int a, int b) { 
   return a + b; 
}

在這個例子中,add()函式接收兩個引數(a和b),並返回它們的和。引數透過暫存器r0和r1傳遞,函式呼叫使用bl指令進行。sum()函式單獨定義,並接收兩個引數(a和b),將它們相加並返回。

Linux上的呼叫約定

Linux是一個流行的開源作業系統,執行在各種裝置上,包括伺服器、桌面和嵌入式系統。Linux中使用的ARM呼叫約定稱為ARM過程呼叫標準(APCS)。

APCS定義了函式呼叫的幾個規則。首先,函式的前四個引數透過暫存器r0到r3傳遞。如果引數超過四個,則在堆疊上傳遞。其次,函式的返回值透過暫存器r0傳遞。如果返回值大於32位,則透過暫存器r0和r1傳遞。

第三,堆疊以特定方式管理。當呼叫函式時,呼叫者負責將返回地址壓入堆疊。被呼叫者負責在其可以使用它們之前將其餘暫存器壓入堆疊。最後,堆疊與8位元組對齊。

示例

這是一個使用APCS呼叫約定新增兩個數字的函式示例:

int add(int a, int b) { 
   int c; 
   asm volatile ( 
      "mov r0, %1
\t" "mov r1, %2
\t" "bl sum
\t" "mov %0, r0
\t" : "= ) }

在這個例子中,add()函式接收兩個引數(a和b),並返回它們的和。引數透過暫存器r0和r1傳遞,函式呼叫使用bl指令進行。sum()函式單獨定義,並接收兩個引數(a和b),將它們相加並返回。

APCS-CE和APCS之間的區別

APCS-CE和APCS之間的主要區別在於堆疊的管理方式。APCS-CE要求堆疊與8位元組對齊,而APCS沒有此要求。此外,APCS-CE要求呼叫者在呼叫函式之前將其餘暫存器壓入堆疊,而APCS沒有此要求。

另一個區別是返回值的處理方式。APCS-CE要求返回值透過暫存器r0傳遞,而APCS允許返回值透過任何暫存器傳遞。

此外,重要的是要注意,呼叫約定可能因使用的編譯器而異。例如,不同版本的GCC可能對同一作業系統使用不同的呼叫約定。必須查閱所用特定編譯器的文件,以確保遵循正確的呼叫約定。

另一個重要的考慮因素是ARM架構支援32位和64位模式,並且呼叫約定可能因使用的模式而異。例如,在64位模式下,引數透過暫存器x0到x7傳遞,而不是r0到r7。

最後,值得注意的是,ARM架構除了APCS和APCS-CE之外,還有許多其他呼叫約定。例如,有一個由Microsoft Visual C++編譯器生成的ARM程式碼的呼叫約定,還有一個由LLVM編譯器生成的ARM程式碼的呼叫約定。

結論

在本文中,我們討論了Windows CE和Linux上的ARM呼叫約定。我們看到這兩個作業系統都使用ARM過程呼叫標準,但在堆疊管理和返回值處理方式上存在一些差異。瞭解這些呼叫約定對於在ARM架構上編寫高效且可移植的程式碼非常重要。

更新於:2023年3月14日

瀏覽量:326

開啟您的職業生涯

完成課程獲得認證

開始
廣告