PowerPC汇编指令集标签:汇编指令PowerPCPPC2008-05-0421:25PowerPC体系结构规范(PowerPCArchitectureSpecification)发布于1993年,它是一个64位规范(也包含32位子集)。几乎所有常规可用的PowerPC(除了新型号IBMRS/6000和所有IBMpSeries高端服务器)都是32位的。PowerPC处理器有32个(32位或64位)GPR(通用寄存器)以及诸如PC(程序计数器,也称为IAR/指令地址寄存器或NIP/下一指令指针)、LR(链接寄存器)、CR(条件寄存器)等各种其它寄存器。有些PowerPCCPU还有32个64位FPR(浮点寄存器)。MPC555使用的PowerPCCPU是带有FPR的。一些常用寄存器介绍如下:通用寄存器的用途:r0在函数开始(functionprologs)时使用。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寄存器必须保存返回系统调用地址的值并且在系统调用前执行crorccr6,cr6,cr6指令(?)。应用程序二进制接口(ABI)从技术而言,开发人员可以将任一GPR用于任何操作。例如,由于不存在:“堆栈指针寄存器”,为此程序员就可以使用任何寄存器。实际上,定义一组约定很有用,这样二进制对象就可以与不同的编译器和预先编写好的汇编代码进行互操作。调用约定是由使用的ABI(应用程序二进制接口)决定的。ppc32Linux和NetBSD实现使用SVR4(SystemVR4)ABI,而ppc64Linux仿效了AIX,使用PowerOpenABI。ABI还指定当调用子例程时哪些寄存器被认为是易失型的(调用者保存(caller-save))以及哪些被认为是非易失型的(被调用者保存(callee-save)),以及许多其它内容。SVR4ABI指定了一些行为的具体示例:-由于PowerPC拥有如此多的GPR(32个,而相比之下IA32只有8个),所以传递参数的寄存器从gpr3开始。-寄存器gpr3到gpr12是易失型的(调用者保存)寄存器,如果需要的话,在调用子例程之前必须先保存它们并在返回之后恢复它们。-寄存器gpr1用来作为栈帧指针。指令格式PowerPC指令包括操作码和操作数两部分,PowerPC支持三操作数的指令格式。如算术指令:addrD,rA,rB表示把(rA)+(rB)的和存放到rD寄存器中。注意:指令中的点号“.”表示:指令将更新条件寄存器CR0。如add.rD,rA,rB。指令中的字母“c”表示:指令显示说明结果影响XER寄存器中的进位位[CA],如addcrD,rA,rB。指令中的字母“e”表示:在指令中把XER[CA]中的数据作为一个操作数,并在XER[CA]位记录进位位,如adderD,rA,rB指令中的字母“o”表示:溢出标志。对于整数,在XER[OA]位记录溢出和在CR0[SO]记录溢出位,如addorD,rA,rB条件寄存器条件寄存器CR包括8个4bit的字段,即CR0~CR7。每个字段可以表示整数运算或比较的结果。每个条件字段可以记录比较结果,即大于、小于、等于和总体溢出等。条件寄存器格式如图1所示。异常处理器整数异常寄存器XER是一个特殊功能寄存器,它包括一些对增加计算精度有用的信息和出错信息。XER的格式如下:SO为总体溢出标志:一旦有溢出位OV置位,SO就会置位。OV为溢出标志:当发生溢出时置位,否则清零;在作乘法或除法运算时,如果结果超过寄存器的表达范围,则溢出置位。CA为进位标志:当最高位产生进位时,置位,否则清零;扩展精度指令(后述)可以用CA作为操作符参与运算。存储/加载指令1整数存储指令整数存储指令如表2所示。表2整数存储指令名称助记符语法格式字节存储(偏移地址寻址)stbrS,d(rA)字节存储(寄存器寻址)stbxrS,rA,rB记录有效地址的字节存储(偏移地址寻址)stburS,d(rA)记录有效地址的字节存储(寄存器寻址)stbuxrS,rA,rB半字存储(偏移地址寻址)sthrS,d(rA)半字存储(寄存器寻址)sthxrS,rA,rB记录有效地址的半字存储(偏移地址寻址)sthurS,d(rA)记录有效地址的半字存储(寄存器寻址)sthuxrS,rA,rB字存储(偏移地址寻址)stwrS,d(rA)字存储(寄存器寻址)stwxrS,rA,rB记录有效地址的字存储(偏移地址寻址)stwurS,d(rA)记录有效地址的字存储(寄存器寻址)stwuxrS,rA,rB(1)字节存储指令stb(偏移地址寻址)stbrS,d(rA)有效地址为rA的内容加d,rS的低8位内容存储到有效地址为EA的存储器中。(2)字节存储指令stbx(寄存器寻址)stbxrS,rA,rB有效地址为rA的内容加上rB的内容,rS的低8位内容存储到有效地址为EA的存储器中。(3)记录有效地址的字节存储指令stbu(偏移地址寻址)stubrS,d(rA)有效地址EA=(rA)+d,rS的低8位内容存储到有效地址为EA的存储器中。rA=EA,如果rA=0,则指令无效。(4)记录有效地址的字节存储指令stbux(寄存器寻址)stbuxrS,rA,rB有效地址EA=(rA)+(rB),rS的低8位内容存储到有效地址为EA的存储器中,rA=EA,如果rA=0,则指令无效。(5)半字存储指令sth(偏移地址寻址)sthrS,d(rA)有效地址EA=(rA)+d,rS的低16位内容存储到有效地址为EA的存储器中。(6)记录有效地址的半字存储指令sthu(偏移地址寻址)sthurS,d(rA)有效地址EA=(rA)+d,rS的低16位内容存储到有效地址为EA的存储器中。rA=EA,如果rA=0,则指令无效。(7)字存储指令stw(偏移地址寻址)stwrS,d(rA)有效地址EA=(rA)+d,rS的32位内容存储到有效地址为EA的存储器中。(8)记录有效地址的字存储指令stwu(偏移地址寻址)stwurS,d(rA)有效地址EA=(rA)+d,rS的32位内容存储到有效地址为EA的存储器中,rA=EA,如果rA=0,则指令无效。(9)记录有效地址的字存储指令stwux(寄存器寻址)stwuxrS,rA,rB有效地址EA=(rA)+(rB),rS的32位内容存储到有效地址为EA的存储器中。rA=EA,如果rA=0,则指令无效。(10)字存储指令stwx(寄存器寻址)stwxrS,rA,rB有效地址EA=(rA)+(rB),rS的32位内容存储到有效地址为EA的存储器中。2、整数加载指令整数加载指令如表3所示。名称助记符语法格式高位清零加载字节指令(偏移地址寻址)lbzrD,d(rA)高位清零的加载字节指令(寄存器寻址)lbzxrD,rA,rB高位清零的加载字节并记录有效地址指令(偏移地址寻址)lbzurD,d(rA)高位清零的加载字节并记录有效地址指令(寄存器寻址)lbzuxrD,rA,rB高位清零的加载半字指令(偏移地址寻址)lhzrD,d(rA)高位清零的加载半字指令(寄存器寻址)lhzxrD,rA,rB高位清零的加载半字并记录有效地址指令(偏移地址寻址)lhzurD,d(rA)高位清零的加载半字并lhzuxrD,rA,rB记录有效地址指令(寄存器寻址)加载半字指令(偏移地址寻址)lharD,d(rA)加载半字指令(寄存器寻址)lhaxrD,rA,rB加载半字并记录有效地址指令(偏移地址寻址)lhaurD,d(rA)加载半字并记录有效地址指令(寄存器寻址)lhauxrD,rA,rB加载字指令(偏移地址寻址)lwzrD,d(rA)加载字指令(寄存器寻址)lwzxrD,rA,rB加载字并记录有效地址指令(偏移地址寻址)lwzurD,d(rA)加载字并记录有效地址指令(寄存器寻址)lwzuxrD,rA,rB(1)lbzrD,d(rA);EA=(rA|0)+d。从存储器读取EA地址的内容,并加载低8位到rD,rD的其他位清0。不影响其他寄存器。(2)lbzurD,d(rA);EA=(rA)+d。从存储器读取EA地址一个字节的内容,并加载低8位到rD,rD的其他各位清零,有效地址EA存放在rA中。(3)lbzuxrD,rA,rB;EA=(rA)+(rB)。从存储器读取EA地址一个字节的内容,并加载低8位到rD,rD的其他各位清零,EA存放在rA中。如果rA=0或者rA=rD,则指令无效。(4)lbzxrD,rA,rB;EA=(rA|0)+(rB)。从存储器读取EA地址一个字节的内容,并加载低8位到rD,rD的其他各位清0。(5)lharD,d(rA);EA=(rA|0)+d。从存储器EA处读取两个字节的数,并加载到rD的低16位。rD的其他位填充最高位的值。(6)lhaxrD,rA,rB;EA=(rA)+(rB)。从存储器EA处读取两个字节的数,并加载到rD的低16位。rD的其他位填充最高位的值。(7)lhaurD,d(rA);EA=(rA)+d。从存储器EA处读取两个字节的数,并加载到rD的低16位。rD的其他位填充最高位的值。EA存放在rA中,如果rA=0或者rA=rD,则指令格式无效。(8)lhauxrD,rA,rB;EA=(rA)+(rB)。从存储器EA处读取两个字节的数,并加载到rD的低16位。rD的其他位填充最高位的值。EA存放在rA中,如果rA=0或者rA=rD,则指令格式无效。(9)lhzrD,d(rA);EA=(rA|0)+d。从存储器EA处读取两个字节的数,并加载到rD的低16位。rD的其他位清零。(10)lhzurD,d(rA);EA=(rA|0)+d。从存储器EA处读取两个字节的数,并加载到rD的低16位。rD其他位清零。EA存入rA,如果rA=0或者rA=rD,则指令格式无效。(11)lhzuxrD,rA,rB;EA=(rA)+(rB)。从存储器EA处读取两个字节的数,加载到rD的低16位,rD其他位清零。EA存入rA,如果rA=0或者rA=rD,则指令格式无效。(12)lhzxrD,rA,rB;EA=(rA|0)+(rB),从EA处读取两个字节的数,并加载到rD的低16位,将rD的其他位清零。(13)lwzrD,d(rA);EA=(rA|0)+d,从EA处读取4个字节的数,并加