PowerPC汇编指令集
Posted brucemengbm
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了PowerPC汇编指令集相关的知识,希望对你有一定的参考价值。
PowerPC 体系结构规范(PowerPC Architecture Specification)公布于 1993 年,它是一个 64位规范 ( 也包括 32 位子集 )。差点儿全部常规可用的 PowerPC(除了新型号 IBM RS/6000 和全部IBM pSeries 高端server)都是 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
PowerPC 体系结构规范(PowerPC Architecture Specification)公布于 1993 年,它是一个 64位规范 ( 也包括 32 位子集 )。差点儿全部常规可用的 PowerPC(除了新型号 IBM RS/6000 和全部IBM pSeries 高端server)都是 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
以上是关于PowerPC汇编指令集的主要内容,如果未能解决你的问题,请参考以下文章