PowerPC匯編入門


PowerPC

  • PowerPc體系結構規范,發布於1993年,是一個64位規范也包含32位子集

  • ppc處理器有32個(32位或者64位)GPR 以及諸如PC(程序計數器,也稱IAR/指令地址寄存器或者NIP/下一指令指針)、LR(鏈接寄存器)、FPSCR(浮點狀態和控制寄存器)、CTR(計數寄存器)、FPR(浮點寄存器)、CR(條件寄存器)、等各種其他寄存器。有些ppc cpu還有32個64位FPR(浮點寄存器)

  • PowerPC處理器可以運行於兩個級別,即用戶模式和特權模式。用戶模式下,僅有GPR,FPR,CR,FPSCR,LR,CTR,XER以及TBL/TBU可以訪問。從Power ISA 2.05開始,DCR寄存器也可以在通過用戶模式DCR訪問指令進行訪問。

  • 注意 :指令中的“.”表示更新條件寄存器如add. rD,rB,rA

            * 指令中的“c”表示:指令顯示說明結果影響XER寄存器中的進位位【CA】如addc rD,rA,rB
           * 指令中的“e”表示:在指令中吧XER【CA】中的數據作為一個操作數,並在XER【CA】位記錄進位位,如addr ,rA,rB
            * 指令中的字母“0”表示:溢出標識。對於整數,在XER【OA】位記錄溢出和在CR0【so】記錄溢出位,如addo rD,rA,rB
    
  • PowerPC指令中, i后綴表示立即數,s后綴表示左移16位。例如addi、addis、ori、oris等。這段代碼也可以用來讀取某個變量的值,只需要把立即數替換成變量名。

  • 配置寄存器

配置寄存器 作用
HID0-HID2 硬件實現寄存器
MSR 機器狀態寄存器(用來配置微處理器的設定)
MBAR 存儲器基址寄存器
SVR 系統處理器
PVR 版本寄存器
  • 存儲管理寄存器

存儲管理寄存器 作用
LBATOU/LBATOL/LBAT3U/LBAT3L 指令BAT寄存器
DBATOU/DBATOL/DBAT3U/DBAT3L 數據BAT寄存器
DMISS/DCMP/HASH1/HASH2/ICMP/RPA 軟件表搜索寄存器
SDR1 SDR1
SR0-SR15 段寄存器
SPRGs:SPRG0-SPRG7 中斷處理寄存器
DSISR DSISR
SRP0 SRP1 保存恢復寄存器
DEC 多功能寄存器
CSRR0-CSRR1 緊急中斷寄存器
DAR 數據地址寄存器
TBL-TBU 時基設施(用於寫)
IABR/IABR2/DABR/DABR2 指令/數據地址斷點寄存器
IBCR/DBCR 指令/數據地址斷點控制
通用寄存器 作用
r0 在函數開始時使用
r1 堆棧指針,相當於ia32架構中的esp寄存器,
r2 內容表指針,idapro吧這個寄存器反匯編標識為rtoc,系統調用時包含系統調用號
r3 作為第一個參數和返回值
r4-r10 函數或系統調用開始的參數
r11 用在指針的調用或當做一些語言的環境指針
r12 他用在異常處理個glink(動態鏈接器代碼)
r13 保留作為系統線程id
r14-r31 作為本地變量非易失性
  • 寄存器r1、r14-r31是非易失性的,意味着他們的值在函數調用過程中保持不變。

  • 寄存器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指令

異常處理器

  • 整數異常寄存器xer是一個特殊功能寄存器,他包括一些對增加計算精度有用的信息和出錯信息
  • xer的格式如下
    • so為總體溢出標志:一旦有溢出位,so就會置位
    • ov為溢出標志:當發生溢出時置位,否則清零。
    • ca位進位標志:當最高位產生進位時,置位,否則清零;擴展精度指令可以用ca作為操作符參與運算

存儲加載指令

名稱 助記符 語法格式 指令解釋
字節存儲 (偏移地址尋址) stb rS,d(rA) 有效地址為rA的內容加d,rS的低八位存儲到有效地址為EA的存儲器中
字節存儲(寄存器尋址) stbx rS,rA,rB 有效地址為rA的內容加rB的內容,rS的低八位內容存儲到有效地址為EA的存儲器中
記錄有效地址的字節存儲(偏移地址尋址) stbu rS,d(rA) 有效地址EA=(rA)+d,rS的低八位內容存儲到有效地址為EA的存儲器中。rA=EA,如果rA=0,則指令無效
記錄有效地址的字節存儲(寄存器尋址) stbux rS,rA,rB 有效地址EA=(rA)+(rB),rS的低八位內容存儲到有效地址為EA的存儲器中,RA=EA,如果rA=0指令無效
半字存儲(偏移地址尋址) sth rS,d(rA) 有效地址EA=(rA)+d,rS的低16位存儲到有效地址為EA的存儲器中
半字存儲(寄存器尋址) sthx rS,rA,rB 有效地址EA=(rA)+(rB),rS的低16位存儲到有效地址為EA的存儲器中
記錄有效地址的半子存儲(偏移地址尋址) sthu rS,d(rA) 有效地址EA=(rA)+d,rS的低16位內容存儲到有效地址為EA的存儲器中。rA=EA,如果rA=0,則指令無效。
記錄有效地址的半子存儲(寄存器尋址) sthux rS,rA,rB 有效地址EA=(rA)+(rB),rS的低16位內容存儲到有效地址為EA的存儲器中。rA=EA,如果rA=0,則指令無效
字存儲(偏移地址尋址) stw rS,d(rA) 有效地址EA=(rA)+d,rS的32位內容存儲到有效地址為EA的存儲器中。
字存儲(寄存器尋址) stwx rS,rA,rB 有效地址EA=(rA)+(rB),rS的32位內容存儲到有效地址為EA的存儲器中,rA=EA,如果rA=0,則指令無效。
記錄有效地址的字存儲(偏移地址尋址) stwu rS, d(rA) 有效地址EA=(rA)+d,rS的32位內容存儲到有效地址為EA的存儲器中。rA=EA,如果rA=0,則指令無效。
記錄有效地址的字存儲(寄存器尋址) stwux rS,rA,rB 有效地址EA=(rA)+(rB),rS的32位內容存儲到有效地址為EA的存儲器中。rA=EA,如果rA=0,則指令無效。
  • 整數加載指令

名稱 助記符 語法格式 指令解釋
高位清零加載字節指令(偏移地址尋址) lbz rD,d(rA) EA=(rA_0)+d.從存儲器讀取EA地址的內容,並加載低八位到rD,rD的其他位清零。不影響其他寄存器
高位清零加載字節指令(寄存器尋址) lbzx rD,rA,rB EA=(rA_0)+(rB)。從存儲器讀取EA地址一個字節的內容,並加載低8位到rD,rD的其他各位清0。
高位清零的加載字節並記錄有效地址指令(偏移地址尋址) lbzu rD,d(rA) EA=(rA)+d。從存儲器讀取EA地址一個字節的內容,並加載低8位到rD,rD的其他各位清零,有效地址EA存放在rA中
高位清零的加載字節並記錄有效地址指令(寄存器尋址) lbzux rD,rA,rB EA=(rA)+(rB)。從存儲器讀取EA地址一個字節的內容,並加載低8位到rD,rD的其他各位清零,EA存放在rA中。如果rA=0或者rA=rD,則指令無效。
高位清零的加載半字指令(偏移地址尋址) lhz rD,d(rA) EA=(rA_0)+d。從存儲器EA處讀取兩個字節的數,並加載到rD的低16位。rD的其他位清零。
高位清零的加載半字指令(寄存器尋址) lhzx rD,rA,rB EA=(rA_0)+(rB),從EA處讀取兩個字節的數,並加載到rD的低16位,將rD的其他位清零。
高位清零的加載半字並記錄有效地址指令(偏移地址尋址) lhzu rD,d(rA) EA=(rA_0)+d。從存儲器EA處讀取兩個字節的數,並加載到rD的低16位。rD其他位清零。EA存入rA,如果rA=0或者rA=rD,則指令格式無效。
高位清零的加載半字並記錄有效地址指令(寄存器尋址) lhzux rD,rA,rB 從存儲器EA處讀取兩個字節的數,加載到rD的低16位,rD其他位清零。EA存入rA,如果rA=0或者rA=rD,則指令格式無效
加載半字指令(偏移地址尋址) lha rD,d(rA) EA=(rA_0)+d。從存儲器EA處讀取兩個字節的數,並加載到rD的低16位。rD的其他位填充最高位的值。
加載半字指令(寄存器尋址) lhax rD,rA,rB EA=(rA)+(rB)。從存儲器EA處讀取兩個字節的數,並加載到rD的低16位。rD的其他位填充最高位的值。
加載半字並記錄有效地址指令(偏移地址尋址) lhau rD,d(rA) 從存儲器EA處讀取兩個字節的數,並加載到rD的低16位。rD的其他位填充最高位的值。EA存放在rA中,如果rA=0或者rA=rD,則指令格式無效。
加載半字並記錄有效地址指令(寄存器尋址) lhaux rD,rA,rB EA=(rA)+(rB)。從存儲器EA處讀取兩個字節的數,並加載到rD的低16位。rD的其他位填充最高位的值。EA存放在rA中,如果rA=0或者rA=rD,則指令格式無效。
加載字指令(偏移地址尋址) lwz rD,d(rA) EA=(rA_0)+d,從EA處讀取4個字節的數,並加載到rD。
加載字指令(寄存器尋址) lwzx rD,rA,rB EA=(rA_0)+(rB),從EA處讀取4個字節的數,並加載到rD
加載字並記錄有效地址指令(偏移地址尋址) lwzu rD,d(rA) EA=(rA)+d,從EA處讀取4個字節的數,並加載到rD。rA=EA,如果rA=0或rA=rD,則指令格式無效。
加載字並記錄有效地址指令(寄存器尋址) lwzux rD,rA,rB EA=(rA)+(rB),從EA處讀取4個字節的數,並加載到rD。rA=EA,如果rA=0或rA=rD,則指令格式無效
  • 整數多字存儲/加載指令

名稱 助記符 語法格式 指令解釋
多字加載 l m w rD,d(rA) EA=rA+d。以EA起始的n個連續的字加載到通用寄存器GPRs rD到r31處,n=32-rD。EA必須為4的倍數,如果rA=0,則指令格式無效。指令執行時間長
多字存儲 s t m w rS,d(rA) EA=rA+d。把通用寄存器從GPRs rS到GPRs r31,存儲到以EA起始的n個連續的字存儲器,EA必須是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
  • 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 ||oboo的值經符號擴展后的值
    • LK=1,則轉移指令下一條指令的有效地址存放到鏈接寄存器
  • 指令語法格式

    • 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)

    • 無條件跳轉主要有b(跳轉到相對地址)\ba(跳轉到絕對地址)\blr(跳轉到連接寄存器)\bctr(跳轉到計數寄存器)4種;(注意,rfi、rfci、rfmci等異常返回指令也可以看做是特殊的無條件跳轉。)

    • 條件跳轉指令分為兩種:需要配合比較指令/算術指令/邏輯運算指令使用的beq(相等或者為0則跳轉)/bne(不等或者非0則跳轉)/blt(小於則跳轉)/bgt(大於則跳轉)/ble(小於等於則跳轉)/bge(大於等於則跳轉)/bnl(不小於則跳轉)/bng(不小於則跳轉)等和需要配合計數寄存器CTR使用的bdz(CTR遞減到0則跳轉)/bdnz(CTR沒有遞減到0則跳轉)等。

    • 此外條件跳轉指令還可以增加后綴a表示跳轉到絕對地址;所有跳轉指令增加后綴l表示同時更新連接寄存器(LR),用於子程序調用。配合條件跳轉指令使用的比較指令主要是cmp(l)w(i),其中l表示邏輯比較既無符號數比較,w表示比較2個word,i表示寄存器內容跟立即數進行比較;配合條件跳轉指令使用的算術指令必須加上后綴“.”用以表示更新條件寄存器CR,主要有add(寄存器內容相加)/addi(寄存器內容跟立即數相加)/addis(立即數左移16位后跟寄存器內容相加)和subi(寄存器內容減去立即數)/subis(寄存器內容減去左移16位后的立即數)/subf(從RB(第三個參數)中減去RA(第二個參數)的內容放入RT(第一個參數));
      配合條件跳轉指令使用的邏輯指令也必須加上后綴“.”用以表示更新條件寄存器CR,主要包括and(i)(s)/or(i)(s)。CTR等專用寄存器必須通過專用命令mfspr rD,SPR和mtspr SPR,rS或者mfctr/mtctr/mflr/mtlr/mfspr/mtspr/mftbl/mftbu/mttbl/mttbu鞥助記符進行操作。此外,DCR寄存器必須通過mfdcr/mtdcr/mfdcrx/mtdcrx/mfdcrux/mtdcrux等進行操作。

  • BI字段表示寄存器CR中的位用於轉移條件BO字段操作見下

BO 說明
0000y 計數器CTR減量,如果條件不成立則轉移
0001y 計數器CTR減量,如果條件不成立則轉移
001zy 如果條件不成立,則轉移
0100y 計數器CTR減量,如果條件成立則轉移
0101y 計數器CTR減量,如果條件成立則轉移
011zy 如果條件成立則轉移
1z00y 計數器CTR減量,如果CTR!=0,則發生轉移
1z01y 計數器CTR減量,如果CTR=0,則發生轉移
1z1zz 發生轉移
  • 注:位z可以被忽略,位y表示是不是條件轉移
  • bclr BO ,BI(LK=0)
  • bclrl BO ,BI(LK=1)
  • BI字段表示條件寄存器CR中的位用於轉移條件
  • 轉移目標地址為LR[0-29]||0B00
  • 如果LK=1,則下一條有效地址存放到連接寄存器
  • 條件轉移指令bcctrx(轉移目標地址由ctr指出)
  • 指令的語法格式
    • bcctr BO,BI(LK=0)
    • bcctrl BO,BI(LK=1)
    • 轉移目標地址是:CTR||0b00
    • 如果LK=1,則轉移指令下一條指令的有效地址存放到連接寄存器。
    • 果減量計數器(BO[2]=0),指令格式無效,則轉移到目標地址。
  • 特殊寄存器傳送指令

說明 助記符 格式 解釋
讀取機器狀態寄存器 mfmsr rD 讀取MSR的內容放入rD中,這是超級用戶層指令,不影響其他寄存器。
寫入機器狀態寄存器 mtmsr rS 把rS的內容存入MSR中,這是超級用戶指令。
讀取特殊功能寄存器 mfspr rD,SPR n<—spr[5-9]_spr[0-4] rD<—spr(n) 特殊功能寄存器(SPR),將SPR的內容存入rD中。
寫入特殊功能寄存器 mtspr SPR,rS 把rS的內容存入到指定的特殊功能寄存器中。
讀取段寄存器 mfsr rD,SR 將段寄存器SR的內容讀入rD中,這是一個超級用戶層指令。
寫入段寄存器 mtsr SR,rS 將rS中的內容讀入SR,這是一個超級用戶層指令。
間接讀取段寄存器 mfsrin rD,rB 由rB寄存器的0~3位選取的段寄存器的內容,復制到rD中。這是一個超級用戶層指令。
間接寫入段寄存器 mtsrin rS,rB 將rS中的內容復制到由rB的0~3位所指定的寄存器中。這是一個超級用戶層指令
讀取時基寄存器 mftb rD,TBR n<—tbr[5-9]_tbr[0-4] if n=268 then rD<—TBL else if n=269 then rD<—TBU
  • Power PC UISA SPR編碼

  • 指令mftb的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。
      • 實際上還有一些特殊的跳轉指令rfi/rfci/rfmci,其目的地址保存在SRR0/CSRR0/MCSRR0中。
  • 常用指令

  • 大部分cpu的指令集可分為:數據讀寫、數值計算、流程控制、設備管理四個部分。由於PowerPC使用RISC,指令長32bit,Endian一般是可調的,默認為大端,另外PowerPc沒有棧,所以程序要自己實現相關操作。
  • 運算和邏輯指令

  • 他們與通用寄存器有關,源數據來自GPR或者16立即數,目的是GPR寄存器。操作為32位,GPR中存放32位更新數據,“cntlzw”用於計算字中第一個零,用於在一個字中找到1時將一個指令中的0的數量找出。他在決定例外寄存器中最高優先服務時有用。

  • 數據讀寫指令

    • 數據在存儲器中核通用寄存器中的傳送很有用,數據小於傳送長度(單字,半字或字節),指令會使數據變為32位,將不同的位填0或符號擴展。
  • 需要注意上面舉例lbz和lbh並不完全等同於mov al,【ebx】和mov ax,【ebx+10】這兩個,前面兩個是將字節和半字加載到r3時還清空了高位,后兩條只是加載數據到eax並不會清高位
  • sthbrw和stwbrx,對PowerPC存取小端格式數據很有用,它們允許存取這樣的數據,若數據以小端順序進入總線,就把它存為大端順序

  • 賦值指令

  • lis r3,0x1234

  • addi r3,r3,0x5678

  • 將0x12345678加載到寄存器r3中,因為在RISC下PowerPc的每條指令都是32bit,除去指令和寄存器參數編碼,只剩下16bit的長度描述立即數,如立即數加載指令li:

  • 這樣立即數simm只有16位,所以需要兩次加載,使用lis 立即數載入並左移和addi立即數加法兩條指令完成

  • 這里的調用由PowerPC使用lr寄存器完成,在bl指令跳轉前,下一條指令li r1,1的地址會被保存在lr,而執行的func中的blr時,系統會跳到lr表示的地址返回。

  • 介紹特殊寄存器的操作指令,他們可以完成特殊寄存器之間和通用寄存器之間的數據交換

  • 雖然沒有提供棧的相關指令push pop等但是應用r1模擬棧指針,實現多層調用對LR的記錄和恢復

  • PowerPC指令長為32位,指令內僅有16位用於加載常量值,由於地址最多可達到64位,所以我們可以采用每次一段的方式載入地址,匯編程序中@符號指示匯編程序給出一個符號值特殊處理形式:@highest:表示一個常量的48-63位;@higher:表示一個常量的32-48位;@h:16-31位;@l:0-15位

  • 位移操作

指令 指令解釋
rlwinm(.)rA,rS,SH,MB,ME 寄存器RS的內容循環左移立即數SH位,然后跟立即數MB和ME形成的MASK相與后放進RA
rlwnm(.)rA,rS,RB,MB,ME 類似於上一條指令,只是把左移的位數放到了寄存器RB中
rlwimi(.)rA,rS,SH,MB,ME 寄存器RS的內容循環左移立即數SH位,然后跟立即數MB和ME形成的MASK相與,再把RA的內容跟立即數MB和ME形成的MASK的補碼相與,即清掉RA中MASK對應的位,最后把處理后的RS和RA的內容相或,放入RA中
  • 注:MASK形成的規則是,如果MB小於等於ME,則MB到ME之間的位全部置1,包括這兩位,形成MASK;否則,MB到ME之間的位清0,其他位包括這兩位置1,形成MASK。

  • 指令格式

  • PowerPC指令集分為以下幾類:

  • I-form指令格式:該類是無條件轉移指令

  • AA=0,表示LI中存放的是相對地址LI*4,基址是當前指令的地址

  • AA=1,表示LI中存放的是絕對地址LI*4

  • LK=1,表示轉移到目的地址的同時,將當前指令的下一條指令存入LR寄存器

  • LK=0,僅僅表示跳轉到目的地址,而不用修改LR寄存器

    • 例如
      • b LI//AA=0,LK=0:跳轉到目的地址:LI*4+當前指令的地址
      • ba LI//AA=1,LK=0:跳轉到:LI*4
      • bl LI//AA=0,LK=1:跳轉到目的地址:LI*4+PC,同時把PC+4放入LR寄存器(pc是當前指令地址)
      • bla LI//AA=1,LK=1 : 跳轉到目的地址:LI*4,同時把PC+4放入LR寄存器
  • bl 10000051c 對應的機器指令為:

  • 4b ff ff ff b5,其中的LK=0xed。

  • 將LI*4符號擴展到32為對應的真值為-0x4c,而當前指令的地址為0x1000056c,所以跳轉的目標地址就是0x1000056c+(-0x4c)=0x1000051c即為print函數的入口地址。

  • 因此如果想獲得下一條指令的有效地址可以使用下面的匯編代碼:

    • bl invstr //將當前指令的下一條指令PC+4放入LR寄存器
    • invstr:mflrr6 //將LR寄存器的內容放入r6寄存器中
  • B-Form指令格式

    • 該類為有條件轉移指令
  • BO字段:從六位到十位共5bit

    • BO[0]為1:表示根據CTR寄存器是否為0進行轉移;
    • 為0:根據CR寄存器的相應字段和BI字段中的條件進行轉移。
    • BO[1]為1:指定的條件為真時轉移,為0:指定的條件為假時轉移
    • BO[2]為1:執行bc指令時,CTR寄存器保持不變,為0:執行bc指令時,CTR寄存器自減
    • BO[3]為1:CTR寄存器為0時進行條件轉移,為0:CTR寄存器非0時進行條件轉移
    • BO[4]為1:bc指令將被判斷為執行轉移功能,處理器將預取轉移指令目標地址后面的幾條指令,並將預先取得的指令放入緩沖對列。為0:bc指令不被判斷為執行轉移功能,不預取轉移指令目標地址后面的幾條指令
  • BI字段(11-15bit)

    • BI[0-2]的值n(n在0到7之間):指出CR寄存器中的CRn字段的狀態作為指令跳轉條件,BI[3-4]的值表述指令跳轉條件,具體如下:
    • 00 使用LT(小於)狀態作為指令的轉移條件
    • 01 使用GT(大於)狀態作為指令的轉移條件
    • 10 使用EQ(等於)狀態作為指令的轉移條件
  • 11 使用SO(溢出)狀態作為指令的轉移條件

  • BD字段(16-29bit):指出轉移的目標地址

    • bc 16,0,BD
    • BO[0]為1:表示根據CTR寄存器是否為0進行轉移,和CR寄存器無關了;
    • BO[2]為0:執行bc指令時,CTR寄存器自減;
    • BO[3]為0:CTR寄存器為非0時進行條件轉移;
    • BO[4] 為0:bc指令不被判斷為執行轉移功能,不預取轉移指令目標地址后面的幾條指令
    • 指令的意思是將CTR寄存器自減,如果CTR不為0則跳轉到BD指示的地址處。可以使用指令助記符bdnz BD表示,CTR寄存器自減,如果CTR不為0則跳轉到BD指示的地址處
  • bc 4,2,BD

  • BO[0]為0根據CR寄存器的相應字段和BI字段在中的條件進行轉移

  • BO[1]為0:指定的條件為假時轉移

  • BO[2]為1:執行bc指令時,CTR寄存器保持不變

  • BI[0-2]的值為0:指出CR寄存器中的CR0中的狀態作為指令跳轉條件

  • BI[3-4]的值為10:使用EQ(等於)狀態作為指令的轉移條件

  • 該指令的意思是說只有比較結果不等於0,就轉移。可以使用指令助記符:bne BD 來代表bc 4,2,BD。(目標地址是絕對地址還是相對地址還要看AA)
  • 常用的指令助記符lt(小於), le(小於等於),eq(等於),so(溢出),+(轉移被靜態預測為真,選擇轉移),-(轉移被靜態預測為假,不選擇轉移)等等。在Powerpc指令集中常用的條件轉移指令只有bc,bcl,以前的轉移指令beq,ndnz,ble等等都是助記符。

  • SC-Form指令

    • 該指令主要用來實現系統調用,只有“sc”這一條匯編
  • D-Form指令

    • 該指令一定包含一個立即數
  • RS/RT:存放該條指令運算結果的寄存器的索引

    • RA:存放源數據的寄存器索引
    • D:存放該指令需要的另一個立即數數據源
    • 該指令格式包含兩類:
      • 對存儲器或者寄存器進行讀寫的指令
      • 立即數的算術運算和邏輯運算指令
  • 典型指令如下:

  • Load Word and Zero指令

    • lwz RT, D(RA)
  • extsign(D):表示D符合擴展到32bit(因為D是16 bit,參與運算的是32bit)。MEM(EA,4):表示從EA地址處取得32位數據。該指令的目的就是將RA+D指定的地址中讀取一個32位的數據,然后將此數據傳遞給RT寄存器。此外還有對16 bit 和8 bit進行操作的lhz,lbz指令

  • STore Word指令

    • stw RS, D(RA)
    • 和lwz指令想反,將寄存器RS中的32位數存到RA+D指向的內存單元處
    • 注:立即數D參與的尋找計算,都需要將D符號擴展至32位。
  • Load Word and Zero with Update指令

  • lwzu RT,D(RA)

  • 將D+RA指向的內存單元的值放入RT索引的寄存器,然后將RA寄存器的值更新為RA+D

  • Store Word with Update指令

  • stwu RS,D(RA)

  • 這兩條指令可以實現數據棧的壓棧和出棧操作,另外還有對8位和16位數據進行操作的指令lbzu,stbu和sthu,lhzu指令,格式通上。

  • Compare Immediate指令

    • cmpi BF,L,RA,SI
  • 將寄存器RA與立即數SI進行比較,然后將比較指令產生的狀態放入CR寄存器的不同字段中,CR寄存器有8個CRn字段(n從0至7),可以由三bit位的BF段指定。

    • L:表示是進行32位還是64的比較。對於e600而言,只有L=0的比較。
    • CR寄存器用來存放指令執行之后的狀態,該寄存器分為8個字段。分別為CR0,CR1,…,CR7。每個字段都由4bit組成。
    • 各個字段CRn(n從0至7)都可以表示響應指令執行的結果:
    • CR0(0):用來表示LT(小於),當整型指令運算結果為負時置1;
    • CR0(1):用來表示GT(大於),當整型指令運算結果為正時置1;
    • CR0(2):用來表示EQ(等於),當整型指令運算結果為0時置1;
    • CR0(3):用來表示SO(溢出),當整型指令運算結果溢出時置1;
      • 同理浮點數的運算使用CR1來保存運算狀態,保存過程同上,e600的比較指令可以使用CR寄存器的全部的CRn(n從0至7)來保存運算的結果。一般在比較指令cmp之后都會有一個條件跳轉指令,比如bc指令。其中cmp指令可以指定由CR寄存器的CRn段來保存結構,比如上面的cmpi指令就用BF來指定CRn字段,一般而言bc指令就會更新cmp中相同的CRn段來決定條狀。
  • Compare Logical Immediate指令

    • cmpli BF,L,RA,UI和cmpli的指令的用法相同,所不同的是cmpli 是無符號數直接的比較,而cmpi是有無符號之間的比較。
  • Trap Word Immediate指令

  • twi TO,RA,SI

    • 指令稱之為陷阱(trap)指令,該指令對一些Trap條件進行測試,如果條件成立,則處理器進入系統的trap程序,然后對trap事件進行處理。
    • TO字段(有5位),第0至4位此次表示:
      • LTS:(有符號式比較:小於)
      • GTS:(有符號數比較:大於)
      • EQ:(有符號數比較:等於)
      • LT:(無符號數比較:小於)
      • GT:(無符號數比較大於)
      • 如果用戶將TO設置為16(這里原博寫的是1,我覺得寫錯了),並且RA中的有符號數小於立即數SI(符合擴展之后),則處理器進程Trap處理程序。
      • 如果把立即數SI換成寄存器索引RB,則tw TO,RA,RB就是X-Form形式。
      • tw 31, r0, r0就是一個無條件trap指令,可用助記符“trap”表示。
      • D-Form指令包含了很多用於算術和邏輯運算的指令,這些指令都是需要一個立即數的,由於這些立即數都是在指令中的,這樣在e600內核中,這些立即數的長度只能限制在16位。為了能順利的處理32位的立即數,e600內核中的D-Form指令可以在立即數的計算時把立即數左移16位,這樣我們就可以用兩條指令就可以把一個立即數放到一個通用計算器中。
  • X-Form指令

  • 相比,只是將D-Form指令中的D字段差分為RB,XO和Rc字段。

    • X-Form中的RB和RS字段存放源操作數寄存器的索引

    • RT字段存放目的操作數的索引;

    • RA字段既可以存放源操作數寄存器的索引,而言可以存放目的操作數的索引;

    • Rc字段置1表示當前指令的運算結果將改變CR寄存器中的相應CRn段,具有“.”的后綴的指令,其Rc位置1。

    • 存儲器訪問類指令:lbzx, lhzx, lhax, lwzx,stbx, sthx, stwx,lbzux,lhzux,lwzux,stbux,sthux,stwux指令等,這些指令和D-Form中的lbz,lhz,lha,lwz,stb,sth,stw,lbzu,lhzu,lwzu,stub,sthu,stwu一一對應,所不同的是D-Form使用的立即數,換成了X-Form使用的寄存器索引。

    • 字節序列交換指令:lhbrx,lwbrx,sthbrx,stwbrx指令,這些指令的作用是調整字節序列。

    • 比較類指令和trap指令:cmp,cmpl,tw指令

    • 算術邏輯運算指令:and,or,xor,nand,nor,eqv指令

    • ount Leading Zeros Word 指令:cntlzw RA,RS

    • 該指令找出RS寄存器中從左邊開始第一個不為0的位,然后將該位所在的位序(從0開始)存入RA中;

  • XL-Form指令

    • 不同,該類指令使用LR寄存器或者CTR寄存器,而不適用16位的立即數作為跳轉目標。
  • bclr BO,BI,BH //LK=0,21-30字段值為16

    • bclrl BO,BI,BH //LK=1,21-30字段值為16
    • bcctr BO, BI,BH //LK=0,21-30字段值為528
    • bcctrlBO, BI, BH //LK=1,21-30字段值為528
  • X-Form類指令的BO,BI字段值和B-Form類中的BO,BI字段含義相同,LK置1表示跳轉指令執行后,LR寄存器指向下一條指令的地址(當前指令地址+4),BH字段用於靜態分支預測。

  • 當條件滿足時,bclr和bclrl指令使用LR寄存器進行長條狀,而bcctr,bcctrl指令使用CTR寄存器進行長跳轉。

  • 於B-Form指令類似,X-Form指令也使用了很多助記符,比如:blr 相當於 bclr 20, 0

  • blr是XL-Form指令,bc是I-Form指令。

  • XL-Form指令還可以支持CR寄存器不同段CRn的與,或,異或,同或操作,指令格式如下:

  • crand BT,BA,BB //第21-30字段為257,BT<-BA&BB

    • cror BT,BA,BB //第21-30字段為449,BT<-BA|BB
    • crxor BT,BA,BB //第21-30字段為193,BT<-BA同或BB
    • crnand BT,BA,BB //第21-30字段為255,BT<-!(BA&BB)
    • mcrf BF,BFA //第21-30字段為0,將CR的BFA字段拷貝到BF字段
  • ** XFX-Form,XFL-Form,XS-Fomr,XO-Form類指令**

  • addo.,subfo.,addco.,subfo. 指令,此類指令將會影響CA,SO,OV位和CR0字段;

    • addeo.,subfeo.,addzeo.,subfzeo. 指令,此類指令除會影響CA,SO,OV位和CR0字段外,還可以將CA位參與運算;
    • mullw,divw指令,此類指令用作乘除運算;
    • A-Form指令用作浮點運算,典型指令有fadd,fsub,fmul,fdiv。
  • M-Form指令

    • M-Form指令主要作用是對選定的字段做循環左移,並做一些相應掩碼操作,該類指令時PowerPC指令的精華,包含了一組非常強大的指令。
    • Rotate Left Word Immediate thenAND with Mask指令
    • rlwinm RA,RS,SH,MB,ME (Rc=0)
    • rlwinm. RA,RS,SH,MB,ME (Rc=1)
    • 寄存器RS的內容循環左移立即數SH位,然后跟立即數MB和ME形成的MASK相與后放進RA
    • MASK形成的規則是,如果MB小於等於ME,則MB到ME之間的位全部置1,包括這兩位,形成MASK;否則,MB到ME之間的位清0,其他位包括這兩位置1,形成MASK。
  • Rotate Left Word then AND withMask指令

    • rlwnm RA,RS,RB,MB,ME (Rc=0)
    • rlwnm. RA,RS,RB,MB,ME (Rc=1)
    • 類似於上一條指令,只是把左移的位數放到了寄存器RB中
  • Rotate Left Word Immediate thenMask Insert指令

    • rlwimi RA,RS,SH,MB,ME (Rc=0)
    • rlwimi. RA,RS,SH,MB,ME (Rc=1)
  • 寄存器RS的內容循環左移立即數SH位,然后跟立即數MB和ME形成的MASK相與,再把RA的內容跟立即數MB和ME形成的MASK的補碼相與,即清掉RA中MASK對應的位,最后把處理后的RS和RA的內容相或,放入RA中

    • MASK形成的規則是,如果MB小於等於ME,則MB到ME之間的位全部置1,包括這兩位,形成MASK;否則,MB到ME之間的位清0,其他位包括這兩位置1,形成MASK。
    • 抽取0x87654321(RS)的bit 24-31,用以對立即數0x12345678(RA)的bit 8-15進行先清除后置位的操作,從而得到0x12215678.rlwimi rA, rS, 16, 8, 15
    • 0x87654321(RS)循環左移16位得到0x43218765,然后與MASK0x00ff0000 (MASK[8,15])相與得到0x00210000;再把0x12345678(RA)與MASK0x00ff 0000 (MASK[8,15])的補碼0xff00ffff相與,得到0x1200 5678; 最后0x0021 0000跟0x1200 5678相與,得到0x12215678。
  • 總結

    • PowerPC處理器采用RISC定長指令集,所以它的指令集不多,但是這些基本的指令集可以衍生出很多復雜的指令集,而令我們這些初學PowerPC指令集的人望而生畏,但是即便如此,我們仍然應該耐着性子把這些指令認真的讀一遍,這樣我們才能了解PowerPC指令集
  • 參考資料

https://blog.csdn.net/skywind/article/details/6347684
http://www.360doc.com/content/13/0731/12/13289331_303773120.shtml
http://www.360doc.com/content/12/1025/10/7775902_243630953.shtml
https://bbs.csdn.net/wap/topics/390375940
https://blog.csdn.net/zhangliang_571/article/details/40745447
http://blog.chinaunix.net/uid-26675482-id-4142669.html
https://blog.csdn.net/qq_30567891/article/details/82782282


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM