PPC 汇编入门指南

2019-08-31 19:22

看懂PowerPC汇编,需要如下3方面的知识:

1.PowerPC指令集架构即Power ISA,可以从Power.org获得,包括寄存器定义,数据模型,寻址方式和指令定义以及指令助记符;

2.PowerPC ABI即应用程序二进制接口,即寄存器的使用规范和栈调用结构;

3.PowerPC Pseudo-ops,即.text, .align n等汇编语言中常用的伪操作符。

PowerPC ISA分为3个级别即“Book”,分别对应于用户指令集体系结构,虚拟环境体系结构和操作环境体系结构。其中Book III分化出了服务器版本Book III-S(经典PowerPC架构)和嵌入式版本Book III-E(专门为嵌入式优化的版本)。

1.寄存器定义:

PowerPC处理器寄存器分为2大类-专用寄存器和非专用寄存器。其中,非专用寄存器包括32个通用目的寄存器(GPR),32个浮点寄存器(FPR),条件寄存器(CR),浮点状态和控制寄存器(FPSCR);专用寄存器主要包括连接寄存器(LR),计数寄存器(CTR),机器状态寄存器(MSR)以及时间基准寄存器(TBL/TBU)等等。PPC4xx系列处理器还有DCR寄存器,需要用专门的指令访问。这里有两点需要注意:

1. PowerPC处理器可以运行于两个级别,即用户模式和特权模式。用户模式下,仅有GPR,FPR,CR,FPSCR,LR,CTR,XER以及TBL/TBU可以访问。从Power ISA 2.05开始,DCR寄存器也可以在通过用户模式DCR访问指令进行访问。

2.PowerPC处理器没有专用的栈指针寄存器和PC指针寄存器,也就是说硬件不负责维护调用栈。

2.数据模型:

PowerPC支持如下数据格式:byte, halfword, word, doubleword,quadword, 同时默认支持big-endian字节序,即MSB(最高有效字节,例如0x12345678中0x12即MSB)保存在低地址。little-endian字节序可以通过修改设置支持。

注意:PowerPC习惯, msb(最高有效位)为bit0,lsb为bit31.

3.寻址方式

PowerPC没有专门的IO操作指令,所有地址访问一视同仁,并且只支持地址和寄存器之间的访问。因此寻址方式非常简单,可以概括为2类6种:

3.1 Load/store/算术/逻辑/cache指令:

a)寄存器间接寻址模式,通常写作RA或者RB;

b)寄存器间接立即数索引寻址模式,即(基址寄存器+立即数偏移)寻址模式,通常写作d(RA);

c)寄存器间接索引寻址模式(基址寄存器 + 偏移寄存器)寻址模式,通常写作RA,RB。

注意:对于三种模式,若寄存器为GPR0,则其内容被忽略,并以0代替其内容。

3.2 跳转指令:

a)立即数寻址模式;

b)链接寄存器(LR)模式,即目的地址被保存在LR中;

c)计数寄存器(CTR)模式,即目的地址保存在CTR中。

注意:实际上还有一些特殊的跳转指令rfi/rfci/rfmci,其目的地址保存在SRR0/CSRR0/MCSRR0中。

4.指令定义和指令助记符:

PowerPC指令的长度都是4字节,但是种类繁多,而且有些指令极其复杂。因此,通常情况下,PowerPC汇编编程中采用指令和助记符混用的方式。 助记符主要用来简化内存访问、算术运算、逻辑运算等常用指令,例如用bne target代替bc 4,2,target表示不为零则跳转。下面仅以一些常见的汇编代码片段来做一些简单的归纳,具体信息请参考相应的处理器core用户手册或者Power ISA。注意,cache和MMU指令会跟其实现一起介绍,此处不再赘述。

4.1 读取一个word(0x12345678)到目的寄存器

lis RA,0x12345678@h /* 高16位(0x1234)偏移16位后变成0x12340000放进RA */ ori RB, RA, 0x12345678@l /* RA与低16位(0x5678)相或后构成完整数据放进RA */

注意:PowerPC指令中, i后缀表示立即数,s后缀表示左移16位。例如addi、addis、ori、oris等。这段代码也可以用来读取某个变量的值,只需要把立即数替换成变量名。

2.从某个地址(0x56789abc)读取数据

lis RA,0x56789abc@ha /* 调整后的高16位(0x5679)偏移16位后变成(0x56790000)放进RA */

lwz RB, 0x56789abc@l (RA) /* RA加上低16位(0xffff9abc) 构成完整数据地址,然后将其内容放进RB */

注意:

? @l,@h和@ha:用于算术运算的操作数(包括addi的操作数)时,@l获取的是符号扩展的低16位数据(0xffff9abc) ,因此高16位必须进行根据bit15进行调整,而不能简单的使用@h来获取。

? load/store指令的通常格式为(l/st)(w/h/b)(z/br)(u/x) RA,… . 其中l代表读取数据到RA中;st代表将RA的内容写入内存;w/h/b分别代表针对word、halfword/byte进行操作;z仅用于读取数据,代表字或者半字读到寄存器中后将其高位清零(注意:对word的读取无意义,但必须加);br代表读取后或者存入前对数据进行字节序反转;u代表从某个内存地址读取数据后,同时更新保存内存地址的寄存器;x代表使用寄存器间接索引寻址模式(基址寄存器 + 偏移寄存器)寻址模式(默认使用寄存器间接立即数索引寻址模式)

? 这段代码也可以用来访问数组或者结构中的某个成员,或者指针指向的地址块中的数据,只需把立即数换成相应的数组名、结构名或者指针即可。

3.入栈/出栈操作

入栈:

stwu 1, –16(1) /* 原始栈指针GPR1保存在新栈顶(原始栈指针减去16)*/

mflr 0 /* LR暂存在GPR1 */

stw 0, 20(1) /* 保存LR到调用者的栈中 */ 出栈:

lwz 0, 20(1) /* LR出栈 */

mtlr 0 /* 恢复LR */

addi r1, r1, 16 /* 销毁栈 */

注意:栈定义会在ABI部分详细解释,此处不再赘述。

4.循环

li 0, 10 /* 循环次数暂存入GPR0 */

mtctr 0 /* 更新计数寄存器 CTR*/ label:

… /* 需要重复执行的指令 */

bdnz label /* 递减计数器,不等于0则跳转到标号处重复执行 */

注意:

? label类似于C语言中的标号,因此在同一段代码中,不能重复。因此,习惯中使用数字标号来代替。数字标号作为跳转指令的目的地址时,通常在其后一个b表示向最近的低地址数字标号跳转,加f表示向最近的高地址数字标号跳转。例如beq 1f或者blt 2b。注意,标号,不管是数字形式还是字母形式,都可以用作一个代表标号所对应行的地址的变量使用。例如,可以用lis RA, 1f@ha; lwz RB, 1f@l(RA)可以用来获取标号1f处的指令内容。

?

跳转指令分为条件跳转和无条件跳转两种:


PPC 汇编入门指南.doc 将本文的Word文档下载到电脑 下载失败或者文档不完整,请联系客服人员解决!

下一篇:GB 14881-2013试题答案

相关阅读
本类排行
× 注册会员免费下载(下载后可以自由复制和排版)

马上注册会员

注:下载文档有可能“只有目录或者内容不全”等情况,请下载之前注意辨别,如果您已付费且无法下载或内容有问题,请联系我们协助你处理。
微信: QQ: