基本ATPCS規定了在子程序調用時的一些基本規則,包括下面四方面的內容。
各寄存器的使用規則及其相應的名稱。
數據棧的使用規則。
參數傳遞的規則。
子程序結果的返回規則。
1. 寄存器的使用規則及其相應的名稱
寄存器的使用必須滿足下面的規則。
子程序間通過寄存器R0~R3來傳遞參數,被調用的子程序在返回前無需恢復寄存器R0~R3的內容。
在子程序中,使用寄存器R4~R11保存局部變量,這時寄存器可以記作V1~V8。如果在子程序中用到了寄存器V1~V8中的某些寄存器,子程序進入時必須保存這些寄存器的值,在返回前必須恢復這些寄存器的值;對於子程序中沒有用到的寄存器則不必進行這些操作。在Thumb程序中,通常只能使用寄存器R4~R7來保存局部變量。
寄存器R12用作子程序間的Scratch寄存器(用於保存SP, 在函數返回時使用該寄存器出棧),記作IP。
寄存器R13用作數據棧指針,記作SP。在子程序中寄存器R13不能用作其他用途。寄存器SP在進入子程序時的值和退出子程序的值必須相等。
寄存器R14稱爲連接寄存器,記作LR。它用作保存子程序的返回地址。如果在子程序中保存了返回地址,寄存器R14則可以用作其他用途。
寄存器R15是程序計數器,記作PC。它不能用作其他用途。
ATPCS中的各寄存器在ARM編譯器和彙編器中都是預定義的。
表4-1總結了在ATPCS中各寄存器的使用規則及其名稱。
表4-1 寄存器的使用規則
寄存 器 |
別 名 |
特殊名稱 |
使 用 規 則 |
R15 |
|
PC |
程序計數器 |
R14 |
|
LR |
連接寄存器 |
R13 |
|
SP |
數據棧指針 |
R12 |
|
IP |
子程序內部調用的Scratch寄存器 |
R11 |
V8 |
|
ARM狀態局部變量寄存器8 |
R10 |
V7 |
Sl |
ARM狀態局部變量寄存器7 在支持數據檢查的ATPCS 中爲數據棧限制指針 |
(續表)
寄 存器 |
別名 |
特殊名稱 |
使 用 規 則 |
R9 |
V6 |
SB |
ARM狀態局部變量寄存器6 在支持RWPI的ATPCS 中爲靜態基址寄存器 |
R8 |
V5 |
|
ARM狀態局部變量寄存器5 |
R7 |
V4 |
WR |
ARM狀態局部變量寄存器4 Thumb狀態工作寄存器 |
R6 |
V3 |
|
局部變量寄存器3 |
R5 |
V2 |
|
局部變量寄存器2 |
R4 |
V1 |
|
局部變量寄存器1 |
R3 |
A4 |
|
參數/結果/Scratch寄存器4 |
R2 |
A3 |
|
參數/結果/Scratch寄存器3 |
R1 |
A2 |
|
參數/結果/Scratch寄存器2 |
R0 |
A1 |
|
參數/結果/Scratch寄存器1 |
2. 數據棧的使用規則
棧指針是保存了棧頂地址的寄存器值。棧指針通常可以指向不同的位置。一般的,棧可以有以下四種數據棧。
FD:Full Descending
ED:Empty Descending
FA:Full Ascending
EA:Empty Ascending
當棧指針指向與棧頂元素時,稱爲Full棧。當棧指針指向與棧頂元素相鄰的一個元素時,稱爲Empty棧。數據棧的增長方向也可以不同,當數據棧向內存減少的地址方向增長時,稱爲Descending棧;反之稱爲Ascending棧。ARM的ATPCS規定默認的數據棧爲Full Descending(FD)類型,並且對數據棧的操作是8字節對齊的。
3. 參數傳遞的規則
根據參數個數是否固定可以將子程序參數傳遞規則分爲以下兩種。
(1) 參數個數可變的子程序參數傳遞規則
對於參數個數可變的子程序,但參數不超過四個時,可以使用寄存器R0~R3來傳遞參數;當參數超過四個時,還可以使用數據棧來傳遞參數。在傳遞參數時,將所有參數看作是存放在連續的內存單元中的字數據。然後,依次將各字數據傳送到寄存器R0、R1、R2、R3中,如果參數多於四個,則將剩餘的字數據傳送到數據棧中,入棧的順序與參數順序相反,即最後一個字數據先入棧。
(2) 參數個數固定的子程序參數傳遞規則
對於參數個數固定的子程序,參數傳遞與參數個數可變的子程序參數傳遞的規則不同,如果系統包含浮點運算的硬件部件,浮點參數將按各個浮點參數按順序處理和爲每個浮點參數分配FP寄存器的規則傳遞。分配的方法是,滿足該浮點參數需要的且編號最小的一組連續的FP寄存器中,第一個整數參數,通過寄存器R0~R3來傳遞,其他參數通過數據棧傳遞。
4. 子程序結果返回規則
子程序中結果返回的規則如下。
如果結果爲一個32位的整數,可以通過寄存器返回。
如果結果爲一個64位整數,可以通過寄存器R0和R1返回,依此類推。
如果結果爲一個浮點數,可以通過浮點運算的寄存器F0、D0或S0返回。
如果結果爲複合型的浮點數(如複數),可以通過寄存器F0~FN或者D0~DN返回。
對於爲數更多的結果,需要通過內存來傳遞。
轉載 gyh198 的博文:http://blog.csdn.net/gyh198/article/details/7247505