PPC 调用约定 r0-r31寄存器介绍
最近在做kernel從ARM到一款PPC處理器的移植,需要學下下PPC的通用寄存器,找到的文檔整理如下:
?
| r0 | local | commonly used to hold the old link register when building the stack frame |
| r1 | dedicated | stack pointer |
| r2 | dedicated | table of contents pointer |
| r3 | local | commonly used as the return value of a function, and also the first argument in |
| r4–r10 | local | commonly used to send in arguments 2 through 8 into a function |
| r11–r12 | local | ? |
| r13–r31 | global | ? |
| lr | dedicated | link register; cannot be used as a general register. Use?mflr?(move from link register) or?mtlr?(move to link register) to get at, e.g.,?mtlr r0 |
| cr | dedicated | condition register |
?
?
r0 - r31都是32位長度的寄存器,其中使用上各有區別:
r0?????????????連接寄存器?
r1?????????????堆棧指針--通俗點叫sp,程序在內存中運行時當前的地址指針
r2?????????????目錄表的指針?
r3 - r10?????函數參數(1-8),r3是函數第一個參數,r4是函數第二個參數,依次類推...,r3也用在函數返回值時。
PowerPC簡介
PowerPC 體系結構規范(PowerPC Architecture Specification)發布于 1993 年,它是一個 64 位規范 ( 也包含 32 位子集 )。幾乎所有常規可用的 PowerPC(除了新型號 IBM RS/6000 和所有 IBM pSeries 高端服務器)都是 32 位的。
PowerPC 處理器有 32 個(32 位或 64 位)GPR(通用寄存器)以及諸如 PC(程序計數器,也稱為 IAR/指令地址寄存器或 NIP/下一指令指針)、LR(鏈接寄存器)、CR(條件寄存器)等各種其它寄存器。有些 PowerPC CPU 還有 32 個 64 位 FPR(浮點寄存器)。MPC555使用的PowerPC CPU是帶有FPR的。一些常用寄存器介紹如下:
通用寄存器的用途:
r0 在函數開始(function prologs)時使用。
r1 堆棧指針,相當于ia32架構中的esp寄存器,idapro把這個寄存器反匯編標識為sp。
r2 內容表(toc)指針,idapro把這個寄存器反匯編標識為rtoc。系統調用時,它包含系統調用號(這個好像跟系統有關吧)。
r3 作為第一個參數和返回值。
r4-r10 函數或系統調用開始的參數。
r11 用在指針的調用和當作一些語言的環境指針。
r12 它用在異常處理和glink(動態連接器)代碼。
r13 保留作為系統線程ID。
r14-r31 作為本地變量,非易失性。
?
專用寄存器的用途:
lr 鏈接寄存器,它用來存放函數調用結束處的返回地址。
ctr 計數寄存器,它用來當作循環計數器,會隨特定轉移操作而遞減。
xer 定點異常寄存器,存放整數運算操作的進位以及溢出信息。
msr 機器狀態寄存器,用來配置微處理器的設定。
cr 條件寄存器,它分成8個4位字段,cr0-cr7,它反映了某個算法操作的結果并且提供條件分支的機制。
?
寄存器r1、r14-r31是非易失性的,這意味著它們的值在函數調用過程保持不變。寄存器r2也算非易失性,但是只有在調用函數在調用后必須恢復它的值時才被處理。
寄存器r0、r3-r12和特殊寄存器lr、ctr、xer、fpscr是易失性的,它們的值在函數調用過程中會發生變化。此外寄存器r0、r2、r11和r12可能會被交叉模塊調用改變,所以函數在調用的時候不能采用它們的值。
條件代碼寄存器字段cr0、cr1、cr5、cr6和cr7是易失性的。cr2、cr3和cr4是非易失性的,函數如果要改變它們必須保存并恢復這些字段。
在AIX上,svca指令(sc是PowerPC的助記符)用來表示系統調用,r2寄存器指定系統調用號,r3-r10寄存器是給該系統調用的參數。在執行系統調用指令之前有兩個額外的先決條件:LR寄存器必須保存返回系統調用地址的值并且在系統調用前執行crorc cr6, cr6, cr6指令(?)。
應用程序二進制接口(ABI)
從技術而言,開發人員可以將任一 GPR 用于任何操作。例如,由于不存在:“堆棧指針寄存器”,為此程序員就可以使用任何寄存器。實際上,定義一組約定很有用,這樣二進制對象就可以與不同的編譯器和預先編寫好的匯編代碼進行互操作。
調用約定是由使用的 ABI(應用程序二進制接口)決定的。ppc32 Linux 和 NetBSD 實現使用 SVR4(System V R4)ABI,而 ppc64 Linux 仿效了 AIX,使用 PowerOpen ABI。ABI 還指定當調用子例程時哪些寄存器被認為是易失型的(調用者保存(caller-save))以及哪些被認為是非易失型的(被調用者保存(callee-save)),以及許多其它內容。
SVR4 ABI 指定了一些行為的具體示例:
-由于 PowerPC 擁有如此多的 GPR(32 個,而相比之下 IA32 只有 8 個),所以傳遞參數的寄存器從 gpr3 開始。
-寄存器 gpr3 到 gpr12 是易失型的(調用者保存)寄存器,如果需要的話,在調用子例程之前必須先保存它們并在返回之后恢復它們。
???????-寄存器 gpr1 用來作為棧幀指針。
指令格式
PowerPC
指令包括操作碼和操作數兩部分,PowerPC支持三操作數的指令格式。如算術指令:
add rD,rA,rB
表示把(rA)+(rB)的和存放到rD寄存器中。
注意:
指令中的點號“.”表示:指令將更新條件寄存器CR0。如add. rD,rA,rB。
指令中的字母“c”表示:指令顯示說明結果影響XER寄存器中的進位位[CA],如addc rD,rA,rB。
指令中的字母“e”表示:在指令中把XER[CA]中的數據作為一個操作數,并在XER[CA]位記錄進位位,如adde rD,rA,rB
指令中的字母“o”表示:溢出標志。對于整數,在XER[OA]位記錄溢出和在CR0[SO]記錄溢出位,如addo rD,rA,rB
?
條件寄存器
條件寄存器CR包括8個4bit的字段,即CR0~CR7。每個字段可以表示整數運算或比較的結果。每個條件字段可以記錄比較結果,即大于、小于、等于和總體溢出等。條件寄存器格式如圖1所示。
?
?
異常處理器
整數異常寄存器XER是一個特殊功能寄存器,它包括一些對增加計算精度有用的信息和出錯信息。XER的格式如下:
?
SO為總體溢出標志:一旦有溢出位OV置位,SO就會置位。
OV為溢出標志:當發生溢出時置位,否則清零;在作乘法或除法運算時,如果結果超過寄存器的表達范圍,則溢出置位。
CA為進位標志:當最高位產生進位時,置位,否則清零;擴展精度指令(后述)可以用CA作為操作符參與運算。
存儲/加載指令
1 整數存儲指令
整數存儲指令如表2所示。
表2 整數存儲指令
| 名稱 | 助記符 | 語法格式 |
| 字節存儲(偏移地址尋址) | stb | rS, d(rA) |
| 字節存儲(寄存器尋址) | stbx | rS, rA, rB |
| 記錄有效地址的字節存儲(偏移地址尋址) | stbu | rS, d(rA) |
| 記錄有效地址的字節存儲(寄存器尋址) | stbux | rS, rA, rB |
| 半字存儲(偏移地址尋址) | sth | rS, d(rA) |
| 半字存儲(寄存器尋址) | sthx | rS, rA, rB |
| 記錄有效地址的半字存儲(偏移地址尋址) | sthu | rS, d(rA) |
| 記錄有效地址的半字存儲(寄存器尋址) | sthux | rS, rA, rB |
| 字存儲(偏移地址尋址) | stw | rS, d(rA) |
| 字存儲(寄存器尋址) | stwx | rS, rA, rB |
| 記錄有效地址的字存儲(偏移地址尋址) | stwu | rS, d(rA) |
| 記錄有效地址的字存儲(寄存器尋址) | stwux | rS, rA, rB |
(1)????字節存儲指令stb(偏移地址尋址)
stb rS,d(rA)??
有效地址為rA的內容加d,rS的低8位內容存儲到有效地址為EA的存儲器中。
(2)????字節存儲指令stbx(寄存器尋址)
stbx rS,rA,rB
有效地址為rA的內容加上rB的內容,rS的低8位內容存儲到有效地址為EA的存儲器中。
(3)????記錄有效地址的字節存儲指令stbu(偏移地址尋址)
stub rS,d(rA)
有效地址EA=(rA)+d,rS的低8位內容存儲到有效地址為EA的存儲器中。rA=EA,如果rA=0,則指令無效。
(4)????記錄有效地址的字節存儲指令stbux(寄存器尋址)
stbux rS,rA,rB
有效地址EA=(rA)+(rB),rS的低8位內容存儲到有效地址為EA的存儲器中,rA=EA,如果rA=0,則指令無效。
(5)????半字存儲指令sth(偏移地址尋址)
sth rS,d(rA)
有效地址EA=(rA)+d,rS的低16位內容存儲到有效地址為EA的存儲器中。
(6)????記錄有效地址的半字存儲指令sthu(偏移地址尋址)
sthu rS,d(rA)
有效地址EA=(rA)+d,rS的低16位內容存儲到有效地址為EA的存儲器中。rA=EA,如果rA=0,則指令無效。
(7)????字存儲指令stw(偏移地址尋址)
stw rS,d(rA)
有效地址EA=(rA)+d,rS的32位內容存儲到有效地址為EA的存儲器中。
(8)????記錄有效地址的字存儲指令stwu(偏移地址尋址)
stwu rS,d(rA)
有效地址EA=(rA)+d,rS的32位內容存儲到有效地址為EA的存儲器中,rA=EA,如果rA=0,則指令無效。
(9)????記錄有效地址的字存儲指令stwux(寄存器尋址)
stwux rS,rA,rB
有效地址EA=(rA)+(rB),rS的32位內容存儲到有效地址為EA的存儲器中。rA=EA,如果rA=0,則指令無效。
(10)字存儲指令stwx(寄存器尋址)
stwx rS,rA,rB
有效地址EA=(rA)+(rB),rS的32位內容存儲到有效地址為EA的存儲器中。
2、整數加載指令
整數加載指令如表3所示。
| 名稱 | 助記符 | 語法格式 |
| 高位清零加載字節指令(偏移地址尋址) | lbz | rD, d(rA) |
| 高位清零的加載字節指令(寄存器尋址) | lbzx | rD, rA, rB |
| 高位清零的加載字節并記錄有效地址指令(偏移地址尋址) | lbzu | rD, d(rA) |
| 高位清零的加載字節并記錄有效地址指令(寄存器尋址) | lbzux | rD, rA, rB |
| 高位清零的加載半字指令(偏移地址尋址) | lhz | rD, d(rA) |
| 高位清零的加載半字指令(寄存器尋址) | lhzx | rD, rA, rB |
| 高位清零的加載半字并記錄有效地址指令(偏移地址尋址) | lhzu | rD, d(rA) |
| 高位清零的加載半字并記錄有效地址指令(寄存器尋址) | lhzux | rD, rA, rB |
| 加載半字指令(偏移地址尋址) | lha | rD, d(rA) |
| 加載半字指令(寄存器尋址) | lhax | rD, rA, rB |
| 加載半字并記錄有效地址指令(偏移地址尋址) | lhau | rD, d(rA) |
| 加載半字并記錄有效地址指令(寄存器尋址) | lhaux | rD, rA, rB |
| 加載字指令(偏移地址尋址) | lwz | rD, d(rA) |
| 加載字指令(寄存器尋址) | lwzx | rD, rA, rB |
| 加載字并記錄有效地址指令(偏移地址尋址) | lwzu | rD, d(rA) |
| 加載字并記錄有效地址指令(寄存器尋址) | lwzux | rD, rA, rB ? |
?
(1)????lbz rD, d(rA) ;EA=(rA|0)+d。從存儲器讀取EA地址的內容,并加載低8位到rD,rD的其他位清0。不影響其他寄存器。
(2)????lbzu rD, d(rA) ;EA=(rA)+d。從存儲器讀取EA地址一個字節的內容,并加載低8位到rD,rD的其他各位清零,有效地址EA存放在rA中。
?
(3)????lbzux rD,rA,rB ;EA=(rA)+(rB)。從存儲器讀取EA地址一個字節的內容,并加載低8位到rD,rD的其他各位清零,EA存放在rA中。如果rA=0或者rA=rD,則指令無效。
(4)????lbzx rD,rA,rB???;EA=(rA|0)+(rB)。從存儲器讀取EA地址一個字節的內容,并加載低8位到rD,rD的其他各位清0。
(5)????lha rD, d(rA) ;EA=(rA|0)+d。從存儲器EA處讀取兩個字節的數,并加載到rD的低16位。rD的其他位填充最高位的值。
?
(6)????lhax rD,rA,rB ;EA=(rA)+(rB)。從存儲器EA處讀取兩個字節的數,并加載到rD的低16位。rD的其他位填充最高位的值。
(7)????lhau rD, d(rA) ;EA=(rA)+d。從存儲器EA處讀取兩個字節的數,并加載到rD的低16位。rD的其他位填充最高位的值。EA存放在rA中,如果rA=0或者rA=rD,則指令格式無效。
(8)????lhaux rD,rA,rB ;EA=(rA)+(rB)。從存儲器EA處讀取兩個字節的數,并加載到rD的低16位。rD的其他位填充最高位的值。EA存放在rA中,如果rA=0或者rA=rD,則指令格式無效。
?
?
(9)????lhz rD, d(rA) ;EA=(rA|0)+d。從存儲器EA處讀取兩個字節的數,并加載到rD的低16位。rD的其他位清零。
?
(10)lhzu rD, d(rA) ;EA=(rA|0)+d。從存儲器EA處讀取兩個字節的數,并加載到rD的低16位。rD其他位清零。EA存入rA,如果rA=0或者rA=rD,則指令格式無效。
?
(11)lhzux rD,rA,rB ;EA=(rA)+(rB)。從存儲器EA處讀取兩個字節的數,加載到rD的低16位,rD其他位清零。EA存入rA,如果rA=0或者rA=rD,則指令格式無效。
?
(12)lhzx rD,rA,rB ;EA=(rA|0)+(rB),從EA處讀取兩個字節的數,并加載到rD的低16位,將rD的其他位清零。
?
(13)lwz rD,d(rA) ;EA=(rA|0)+d,從EA處讀取4個字節的數,并加載到rD。
?
(14)lwzu rD,d(rA) ;EA=(rA)+d,從EA處讀取4個字節的數,并加載到rD。rA=EA,如果rA=0或rA=rD,則指令格式無效。
?
(15)lwzux rD,rA,rB ;EA=(rA)+(rB),從EA處讀取4個字節的數,并加載到rD。rA=EA,如果rA=0或rA=rD,則指令格式無效。
?
(16)lwzx rD,rA,rB ;EA=(rA|0)+(rB),從EA處讀取4個字節的數,并加載到rD。
整數多字存儲/加載指令
表3 整數多字存儲/加載指令
| 名稱 | 助記符 | 語法格式 |
| 多字加載 | lmw | rD,d(rA) |
| 多字存儲 | stmw | rS,d(rA) |
(1)????lmw rD,d(rA) ;EA=rA+d。以EA起始的n個連續的字加載到通用寄存器GPRs rD到r31處,n=32-rD。EA必須為4的倍數,如果rA=0,則指令格式無效。指令執行時間長。
(2)????stmw rS,d(rA) ;EA=rA+d。把通用寄存器從GPRs rS到GPRs r31,存儲到以EA起始的n個連續的字存儲器,EA必須是4的倍數。指令執行時間長。
轉移指令
表4 分支控制指令
| 名稱 | 助記符 | 語法格式 |
| 無條件轉移 | b( ba bl bla) | target_addr |
| 條件轉移 | bc( bca bcl bcla) | BO,BI,target_addr |
| 條件轉移(轉移目標地址由LR指出) | bclr(bclrl) | BO,BI |
| 條件轉移(轉移目標地址由CTR指出) | bcctr(bcctrl) | BO,BI |
(1)????無條件轉移指令bx(b ba bl bla)
指令的編碼格式:
?
指令的語法格式:
b target_addr(AA=0 LK=0)
ba target_addr(AA=1 LK=0)
bl target_addr(AA=0 LK=1)
bla target_addr(AA=1 LK=1)
如果AA=0,則轉移目標地址為LI||0b00的值經符號位擴展后加上指令地址。
如果AA=1,則轉移目標地址為LI||0b00的值經符號擴展后的值。
如果LK=1,則轉移指令下一條指令的有效地址存放到連接寄存器。
(1)????條件轉移指令bcx
指令編碼格式:
?
指令語法格式:
bc BO, BI, target_addr(AA=0 LK=0)
bca BO, BI, target_addr(AA=1 LK=0)
bcl BO, BI, target_addr(AA=0 LK=1)
bcla BO, BI, target_addr(AA=1 LK=1)
BI字段表示條件寄存器CR中的位用于轉移條件。BO字段操作碼定義見表5。
表5 BO字段操作碼定義
| BO | 說明 |
| 0000y | 計數器CTR減量,如果條件不成立則轉移 |
| 0001y | 計數器CTR減量,如果條件不成立則轉移 |
| 001zy | 如果條件不成立,則轉移 |
| 0100y | 計數器CTR減量,如果條件成立則轉移 |
| 0101y | 計數器CTR減量,如果條件成立則轉移 |
| 011zy | 如果條件成立則轉移 |
| 1z00y | 計數器CTR減量,如果CTR!=0,則發生轉移 |
| 1z01y | 計數器CTR減量,如果CTR=0,則發生轉移 |
| 1z1zz | 發生轉移 |
注:位z表示該位可以被忽略,位y表示是不是條件轉移
(2)????條件轉移指令bclx(轉移目標地址由LR指出)
指令的編碼格式:
?
指令的語法格式:
bclr BO, BI(LK=0)
bclrl BO, BI(LK=1)
BI字段表示條件寄存器CR中的位用于轉移條件。
BO字段操作碼定義如表5所示。
轉移目標地址為LR[0-29]||0b00。
如果LK=1,則轉移指令下一條有效地址存放到連接寄存器。
(3)????條件轉移指令bcctrx(轉移目標地址由CTR指出)
指令的編碼格式:
?
指令的語法格式:
bcctr BO, BI(LK=0)
bcctrl BO, BI(LK=1)
轉移目標地址是CTR||0b00。
如果LK=1,則轉移指令下一條指令的有效地址存放到連接寄存器。
如果減量計數器(BO[2]=0),指令格式無效,則轉移到目標地址。
特殊寄存器傳送指令
特殊寄存器傳送指令如表6所示。
表6 特殊寄存器傳送指令
| 名稱 | 助記符 | 語法格式 |
| 讀取機器狀態寄存器 | mfmsr | rD |
| 寫入機器狀態寄存器 | mtmsr | rS |
| 讀取特殊功能寄存器 | mfspr | rD, SPR |
| 寫入特殊功能寄存器 | mtspr | SPR, rS |
| 讀取段寄存器 | mfsr | rD, SR |
| 寫入段寄存器 | mtsr | SR, rS |
| 間接讀取段寄存器 | mfsrin | rD, rB |
| 間接寫入段寄存器 | mtsrin | rS, rB |
| 讀取時基寄存器 | mftb | rD, TBR |
(1)????讀取機器狀態寄存器指令mfmsr
???指令的編碼格式:
?
???指令的語法格式:
mfmsr rD
讀取MSR的內容放入rD中,這是超級用戶層指令,不影響其他寄存器。
(2)寫入機器狀態寄存器指令mtmsr
指令的編碼格式:
?
指令的語法格式:
mtmsr rS
把rS的內容存入MSR中,這是超級用戶指令。
(1)????讀取特殊功能寄存器指令mfspr
指令的編碼格式:
?
指令的語法格式:
mfspr rD,SPR
指令操作:
n<—spr[5-9]||spr[0-4]
rD<—spr(n)
特殊功能寄存器(SPR)的編碼如表7所示,將SPR的內容存入rD中。
表7 Power PC UISA SPR編碼
| ? | spr | ? | 寄存器名 |
| 編碼n | spr[5-9] | spr[0-4] | ? |
| 1 | 00000 | 00001 | XER |
| 8 | 00000 | 01000 | LR |
| 9 | 00000 | 01001 | CR |
(2)????寫入特殊功能寄存器指令mtspr
指令的編碼格式:
?
指令的語法格式:
mtspr spr,rS
把rS的內容存入到指定的特殊功能寄存器中。
(3)????讀取段寄存器指令mfsr
指令的編碼格式:
?
????指令的語法格式:
????mfsr rD,SR
指令操作:
rD<—SEGREG(SR)
將段寄存器SR的內容讀入rD中,這是一個超級用戶層指令。
(1)????寫入段寄存器指令mtsr
指令的編碼格式:
?
指令的語法格式:
mtsr SR,rS
將rS中的內容讀入SR,這是一個超級用戶層指令。
(2)????間接讀取段寄存器指令mfsrin
指令的編碼格式:
?
指令的語法格式:
mfsrin rD,rB
指令操作:
rD<—SEGREG(rB[0-3])
由rB寄存器的0~3位選取的段寄存器的內容,復制到rDzhong。這是一個超級用戶層指令。
(3)????間接寫入段寄存器指令mtsrin
指令的編碼格式:
?
指令的語法格式:
mtsrin rS,rB
指令操作:
SEGREG(rB[0-3])<—(rS)
將rS中的內容復制到由rB的0~3位所指定的寄存器中。這是一個超級用戶層指令。
(4)????讀取時基寄存器指令mftb
指令的編碼格式:
?
指令的語法格式:
mftb rD,TBR
指令操作:
n<—tbr[5-9]||tbr[0-4]
if n=268 then
rD<—TBL
else if n=269 then
rD<—TBU
該指令的TBR編碼如表8所示。
表8 指令mftb的TBR編碼
| ? | TBR | ? | 寄存器名 | 訪問 |
| 編碼 | tbr[5-9] | tbr[0-4] | ? | ? |
| 268 | 01000 | 01100 | TBL | 用戶 |
| 269 | 01000 | 01101 | TBR | 用戶 |
?
系統調用指令
(1)????系統調用指令sc
指令的編碼格式:
?
指令的使用:
sc指令調用操作系統去執行服務程序。當控制返回到一個執行系統調用的程序時,寄存器的內容依賴于程序提供的系統所使用的寄存器的約定。
跟在sc指令后面的有效指令地址被放在SRR0中。MSR中的位0、5~9和16~31被放在SRR1中對應的位置,SRR1中位1~4和10~15被設 置為未定義值。當sc異常產生,異常處理程序更改MSR寄存器。異常處理程序到MSR[IP]形成基址加0xC00偏移量形成的地址去取下一條指令。
受影響的寄存器有:
依賴于系統服務、SRR0、SRR1及MSR。
(2)????中斷返回指令rfi
指令的編碼格式:
?
指令操作:
MSR[16-23,25-27,30-31] <—SRR1[16-23,25-27,30-31]
NIA<—iea SRR0[0-29]||0b00
SRR1中的位0、5~9和16~31被放在MSR中對應的位置。如果新的MSR值沒有使能任何未完的操作,則在MSR的控制下,從地址SRR0[0-29]||0b00取下一條指令。
指令的使用中受影響的寄存器為MSR。
總結
以上是生活随笔為你收集整理的PPC 调用约定 r0-r31寄存器介绍的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: windows使用glade2开发gtk
- 下一篇: openocd for windows