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

posted @ 2019-01-24 13:53  一生热爱  阅读(8927)  评论(0编辑  收藏  举报