這篇主要介紹arm64程序調用規則,詳細分析了程序調用過程當中,參數是如何傳遞的。Android、iOS、Linux等基本遵循這些規則,可是各個操做系統平臺也有小部分本身特定的規則。下一篇,我將介紹iOS平臺的特定規則。html
術語 | 意義 |
---|---|
A32 | 在ARMv7架構中,使用32位固定長度指令的ARM指令集。 |
A64 | AArch64可用時的指令集。 |
AAPCS64 | AArch64程序調用標準。(PCS:Procedure Call Standard) |
AArch32 | ARMv8中的32位通用寄存器,兼容ARMv7-A。 |
AArch64 | ARMv8中的64位通用寄存器 |
ABI(Application Binary Interface) | 彙編接口規範,跟執行環境相關,好比Linux ABI,說的是Linux環境下的彙編接口規範; |
ARM-based | 基於ARM |
Floating point | 根據上下文有這三種意思:(1)遵循IEEE 754 2008的浮點運算; (2)ARMv8浮點指令集; (3)一個被ARMv8浮點指令集和ARMv8 SIMD指令集共享的寄存器組。 |
Q-o-I | Quality of Implementation |
SIMD | Single Instruction Multiple Data 一條指令操做多個數據 |
T32 | T32使用可變16bit和32bit |
Routine, subroutine | Routine:調用者;subroutine:被調用者 |
Procedure | 沒有返回值的函數 |
Function | 有返回值的函數 |
PIC, PID | Position-independent code, position-independent data. |
Program state | 指程序內存和寄存器的值 |
Caller- saved register | 調用者在調用函數以前,保存寄存器(通常入棧),函數返回後恢復寄存器(通常出棧) |
Callee-saved register | 被調用者(函數內部),在起始地方保存寄存器,在結束時,恢復寄存器 |
NGRN(The Next General-purpose Register Number ) | 能夠理解爲,記錄r0-r7(見下文寄存器)使用個數,參數傳遞前設爲0,每放一個參數進入寄存器(整型寄存器),值加1。當等於8時候,說明r0-r7寄存器使用完了,再有參數,只能放入內存了。 |
NSRN (The Next SIMD and Floating-point Register Number) | 同上,記錄v0-v7使用個數 |
NSAA (The next stacked argument address) | 記錄參數放入內存,參數傳遞前設爲SP,因此內存中參數範圍應該是 sp~NSAA。詳細見下文參數傳遞 |
Type Class | Machine Type | Byte size |
Natural Alignment (bytes) |
---|---|---|---|
Integral | Unsigned byte | 1 | 1 |
Signed byte | 1 | 1 | |
Unsigned half- word |
2 | 2 | |
Signed half- word |
2 | 2 | |
Unsigned word | 4 | 4 | |
Signed word | 4 | 4 | |
Unsigned double-word |
8 | 8 | |
Signed double- word |
8 | 8 | |
Unsigned quad- word |
16 | 16 | |
Signed quad- word |
16 | 16 | |
Floating Point | Half precision | 2 | 2 |
Single precision | 4 | 4 | |
Double precision |
8 | 8 | |
Quad precision | 16 | 16 | |
Short vector | 64-bit vector | 8 | 8 |
128-bit vector | 16 | 16 | |
Pointer | Data pointer | 8 | 8 |
Code pointer | 8 | 8 |
arm64有兩種寄存器:bash
寄存器 | 別名 | 意義 |
---|---|---|
SP | Stack Pointer:棧指針 | |
r30 | LR | Link Register:在調用函數時候,保存下一條要執行指令的地址。 |
r29 | FP | Frame Pointer:保存函數棧的基地址。 |
r19...r28 | Callee-saved registers(含義見上面術語解釋) | |
r18 | 平臺寄存器,有特定平臺解釋其用法。若是平臺未把其作特殊用途,可當作臨時寄存器使用。(iOS平臺保留的寄存器,應用不可以使用) | |
r17 | IP1 | The second intra-procedure-call temporary register (can be used by call veneers and PLT code); at other times may be used as a temporary register. |
r16 | IP0 | The first intra-procedure-call scratch register (can be used by call veneers and PLT code); at other times may be used as a temporary register. |
r9...r15 | 臨時寄存器 | |
r8 | 在一些狀況下,返回值是經過r8返回的 | |
r0...r7 | r0-r7在函數調用過程當中傳遞參數和返回值 | |
NZCV | 狀態寄存器:N(Negative)負數 Z(Zero) 零 C(Carry) 進位 V(Overflow) 溢出 |
arm64有31個通用整型寄存器,r0-r30。當使用64bits時候,命名x0-x30;使用32bits時,命名w0-w30。當寄存器在此程序調用標準中具備固定角色時,使用大寫。架構
ARM64有32個寄存器v0-v31,用於處理SIMD和浮點運算。長度不一樣稱謂也不一樣,b,h,s,d,q,分別表明byte(8位),half(16位),single(32位),double(64位),quad(128位)。v0-v7在函數調用過程當中傳遞參數和返回值;v8-v15 是Callee-saved registers(見術語解釋),且是保存前64bits(更大的位數,調用者負責保存),v0-v7, v16-v31不須要保存或者調用者保存。app
一個進程的內存可分爲5類:函數
可寫靜態數據能夠細分爲初始化,零初始化和未初始化數據。 除了棧以外,其它4類內存不須要佔用連續的內存。 進程必須具備一些代碼和棧,其它3類不是必須有。 堆是由進程管理的內存區域, 一般用於建立動態數據對象。post
地址空間包括一個或多個不相交的區域。 區域不能跨越零地址,可是能夠從零開始。 標記尋址(tagged addressing)的使用是特定平臺解釋的。 當禁用標記尋址時,指針的全部64位都被傳遞到地址轉換系統。 啓用標記尋址時,爲了進行地址轉換,將忽略指針的前八位。注意:此tagged addressing,非iOS裏的Tagged Pointer。spa
棧是連續的內存空間,可用於存儲局部變量和參數傳遞(用於傳遞參數的寄存器不夠用時候)。棧地址是從高到低,棧的地址保存在SP中。 棧使用限制:操作系統
A64指令集包含函數調用指令BL和BLR。 執行BL:PC(program counter)順序的下一個值,也就是返回地址(函數調用完成返回要執行指令的地址),存放到LR中,將跳轉地址傳給PC。BLR跟BL相似,只不過PC的值是從寄存器中讀取。.net
參數可經過r0-r七、v0-v7,棧來傳遞;若是參數個數很少,且參數可放進寄存器,那僅用寄存器傳遞參數。指針
可變參數可分爲命名參數(已聲明的)和匿名參數(可選的參數)。 當可變參數的函數,調用時候,沒有可選參數時候(只有已聲明的參數),調用過程和固定參數的函數同樣的。
參數傳遞從概念上能夠分爲2階段:
參數傳遞過程分爲3個階段:
階段A – 初始化 (在開始處理參數以前,該階段僅執行一次)
階段B - 預填充和擴展參數 (把參數列表中的每個參數,去匹配下面規則,第一個被匹配到的規則,應用到該參數上。)
階段C- 把參數放到寄存器或棧裏 (參數列表中的每一個參數,將依次應用如下規則,直到參數放到寄存器或棧裏,此參數處理完成,而後再從參數列表中取參數。注: 將參數分配給寄存器時,寄存器中未使用的位的值不肯定。 將參數分配給棧時,未填充字節的值不肯定。)
從上面規則,能夠獲得經驗:
函數返回方式取決於返回結果的類型。
void func(T arg)
複製代碼
arg值經過寄存器(組)傳遞,返回的結果也是經過相同的寄存器(組)返回。 2. 調用者申請內存(內存大小足夠放入返回結果且是內存對齊的),將內存地址放入x8中傳遞給子函數,子函數運行時候,能夠更新x8指向內存的內容,從而將結果返回。
假如文章有不對地方,歡迎你們留言指出;或者給我發郵件(wu_k_k@foxmail.com)。
--EOF-- 轉載請保留連接,謝謝