Arm入門第七講,Thumb 與ARM子程式。
Arm入門第七講,Thumb 與ARM子程式。
一丶Thumb
1.1 什麼是Thumb
Thumb 指令集是16bit指令集,是為了相容資料匯流排寬度為16位的應用系統,Arm體系結構除了支援執行效率很高的32位Arm指令集以外,同時也支援16位的Thumb指令集。可以說Thumb是Arm指令集的一個子集,允許指令編碼為16位的長度。 與等價的32位程式碼相比較,Thumb指令集在保留32程式碼的優勢的同時,又大大節省了空間。
1.2 Thumb指令集的由來
Thumb指令集是從ARMV4T之後的ARM處理器有的指令集。是一種16bit指令模式,叫做Thumb. 他可以看做是ARM指令壓縮形式的子集,它是為減少程式碼量而提出,具有16bit的程式碼密度。
Thumb指令T恤並不完整,只支援通用功能,必要時仍然需要ARM指令。 比如進入異常。
1.3 Thumb的特點
1.Thumb程式碼所需要的儲存空間為Arm程式碼的 60%-70% 畢竟指令短,那麼自然就會佔用空間。
2.Thumb程式碼使用的指令數比ARM程式碼多30%--40%
3.若使用32位的儲存器,那麼ARM程式碼比Thumb程式碼塊40%
4.若使用16位儲存器,Thumb則比ARM程式碼快40%-50%
5.與ARM程式碼比較,使用Thumb程式碼,儲存器的功耗會降低30%
顯然是各有優缺點的。
1.4 Thumb與Arm的卻別
區別如下:
1. 分支指令: 跳轉的範圍小,除了B指令外,其他都是無條件跳轉。
2. 資料處理指令: Thumb指令只有兩個運算元,而ARM指令則是3個運算元。
3. 單暫存器載入/儲存指令: Thumb指令只能訪問R0-R7暫存器。
4. 多暫存器載入/儲存指令: Thumb指令只能訪問R0-R7的子集
5. Thumb特有指令: push 和POP是它特有的指令,作用於R13(sp)暫存器。
編寫Thumb 指令的時候,要先使用偽指令CODE16宣告,而且在ARM指令中要使用BX
編寫ARM指令的時候可以用 CODE32宣告,然後如果遵循一定的呼叫規則,則Thumb子程式和ARM子程式可以互相呼叫。
二丶ARM的ATPCS呼叫標準
ATPCS標準 可以理解為ARM是怎麼使用堆疊的。
那麼在此之前需要熟悉 呼叫約定的知識。 X86的棧操作知識等等。
2.1 呼叫約定
呼叫約定分為如下:
-
cdecl呼叫約定
該呼叫約定遵循以下規則:
引數入棧順序是從右向左
棧平衡負責 是由呼叫者來平。
如函式A 呼叫函式B 在這裡A就是呼叫者 B就是被呼叫者。
-
stdcall 呼叫約定
入棧規則: 引數從右向左入棧
棧平衡負責: 被呼叫者負責
如B函式接受2個引數。 A呼叫B 在B執行完畢之後會操作棧來保證棧平衡。
-
fastcall呼叫約定
引數入棧順序: 函式的第一第二個引數通過ecx和edx入棧。 x64的結構下還有r8 r9(暫存器), 剩餘的引數則從右向左入棧。
棧平衡:被呼叫者進行棧平衡。 (如果是x64那麼則是呼叫者負責)
返回值的存放:
返回值放在EAX和RAX(x64)中
下面是呼叫堆疊圖:
2.2 ARM呼叫約定
ARM函式之間互相呼叫遵循的規則就是ATPCS(ARM-THUMB Procedure Call Standard) ATPCS主要是定義了函式呼叫時引數的傳遞規則以及函式的返回規則。 它很類似於X64架構下的fastcall呼叫。
它們有一個共同的特點就是暫存器多,有大量暫存器可用。
-
傳參方式
R0 -R3是傳遞函式的第1到第四個引數的,超出的部分從右向左通過棧傳遞。
在X64下再是 RCX RDX R8 R9暫存器進行引數傳遞。所以這裡很雷同。
-
棧平衡
棧平衡則是由呼叫者進行棧平衡的。
-
結果儲存
1.結果為32位整數的時候,可以通過暫存器R0來返回。
2.結果是64位整數的時候,可以通過R0 R1返回。
3.結果是浮點數,那麼通過浮點暫存器F0 D0 或者S0返回。
4.結果是符合浮點數,那麼可以通過暫存器F0 -FN 或者D0 -DN來進行返回。
-
區域性變數
R4-R11是用來儲存區域性變數的,如果用到了那麼函式在進入的時候就要先儲存,這點類似於x86環境下的pushad pushfd等指令,儲存暫存器環境。 而在返回的時候,這些暫存器的值也要進行恢復。
Thumb指令只能使用R4-R7,R11也可以做FP暫存器。也就是x86的EBP
-
返回地址
返回地址使用R14暫存器進行儲存(也叫做LR暫存器)
x86的返回地址在棧中儲存。
-
棧頂暫存器
R13是作為棧頂暫存器的,也就是SP暫存器。 x86下則是使用ESP
-
棧基址暫存器
R11作為棧基址暫存器的 也就是FP指令。 x86下則是EBP
-
下一條指令暫存器
R15暫存器,也叫做PC暫存器。 是指向下一條要執行指令的,類似於X86下的EIP暫存器。
-
備份暫存器
R12暫存器主要作用於子程式內部的,也叫做IP暫存器。 內部過程呼叫暫存器,可以備份儲存 SP(R13) LR(R14)暫存器等。
堆疊使用的FD滿遞減棧,也就是跟X86是一樣的。