Chinaunix首页 | 论坛 | 博客
  • 博客访问: 139795
  • 博文数量: 49
  • 博客积分: 2510
  • 博客等级: 少校
  • 技术积分: 595
  • 用 户 组: 普通用户
  • 注册时间: 2008-11-25 23:08
文章分类
文章存档

2011年(1)

2009年(48)

我的朋友

分类: LINUX

2009-03-13 07:38:53

 

第三章 ARM指令集

3.1 ARM指令集概述

ARM指令集是32位的,程序的启动都是从ARM指令集开始。所有的ARM指令集都可以是有条件执行的。本节从以下三个方面介绍:

3.1.1 指令集编码

ARM指令集是以32位二进制编码的方式给出的,大部分的指令编码中定义了第一操作数、第二操作数、目的操作数、条件标志影响位以及每条指令所对应的不同功能实现的二进制位。

每条32ARM指令都具有不同的二进制编码方式,和不同的指令功能相对应。

3.1.2 条件执行

ARM指令根据CPSR中的条件位自动判断是否执行指令,在条件满足时,指令执行,否则指令被忽略。

ARM的指令编码表中,统一占用编码的最高四位[3128]来表示“条件码”(即”cond”)。

3.1.3 指令分类及指令格式

ARM指令集可以分为六大类,分别为数据处理指令、Load/Store指令、跳转指令、程序状态寄存器处理指令、协处理器指令和异常产生指令。

ARM指令使用的基本格式如下:

opcode{cond}{S} Rd〉,〈Rn{,〈operand2}

opcode 操作码;指令助记符,如LDRSTR等。

cond 可选的条件码;执行条件,如EQNE等。

S 可选后缀;若指定“S”,则根据指令执行结果更新CPSR中的条件码。

Rd 目标寄存器。

Rn 存放第1操作数的寄存器。

operand2 2个操作数

3.2 ARM寻址方式

3.2.1 立即寻址

立即寻址也叫立即数寻址,这是一种特殊的寻址方式,操作数本身就在指令中给出,只要取出指令也就取到了操作数,这个操作数被称为立即数,对应的寻址方式也就叫做立即寻址。例如以下指令:

ADD R0R0,#1 /*R0←R01*/

ADD R0R0,#0x3f /*R0←R00x3f*/

在以上两条指令中,第二个源操作数即为立即数,要求以“#”为前缀,对于以十六进制表示的立即数,还要求在“#”后加上“0x”

3.2.2 寄存器寻址

寄存器寻址就是利用寄存器中的数值作为操作数,这种寻址方式是各类微处理器经常采用的一种方式,也是一种执行效率较高的寻址方式。以下指令:



ADD R0R1R2 /*R0←R1R2*/

该指令的执行效果是将寄存器R1R2的内容相加,其结果存放在寄存器R0中。

第二操作数为寄存器型的移位操作

ARM指令的数据处理指令中参与操作的第二操作数为寄存器型时,在执行寄存器寻址操作时,可以选择是否对第二操作数进行移位,即Rm{},其中Rm称为第二操作数寄存器,用来指定移位类型(LSLLSRASLASRRORRRX)和移位位数。移位位数可以是5位立即数(#<#shift>)或寄存器(Rs)。在指令执行时将移位后的内容作为第二操作数参与运算。例如指令:



ADD R3R2R1LSR #2 R3<—R2 + R1÷4

第二操作数移位方式

LSL:逻辑左移,空出的最低有效位用0填充。

LSR:逻辑右移,空出的最高有效位用0填充。

ASL:算术左移,由于左移空出的有效位用0填充,因此 它与LSL同义。

ASR:算术右移,算术移位的对象是带符号数,移位过程中必须保持操作数的符号不变。如果源操作数是正数,空出的最高有效位用0填充,如果是负数用1填充。

ROR:循环右移,移出的字的最低有效位依次填入空出的最高有效位。

RRX:带扩展的循环右移。将寄存器的内容循环右移1位,空位用原来C标志位填充。



第二操作数的移位位数

移位位数可以用立即数方式或者寄存器方式给出,如下所示:



ADD R3R2R1LSR #2 R3 <—R2 + R1÷4

ADD R3R2R1LSR R4 R3 <—R2 + R1÷2R4



3.2.3 寄存器间接寻址

寄存器间接寻址就是以寄存器中的值作为操作数的地址,而操作数本身存放在存储器中。例如以下指令:



LDR R0[R1] /*R0←[R1]*/

STR R0[R1] /*[R1]←R0*/



第一条指令将以R1的值为地址的存储器中的数据传送到R0中。第二条指令将R0的值传送到以R1的值为地址的存储器中。

3.2.4 基址加偏址寻址

基址变址寻址就是将寄存器(该寄存器一般称作基址寄存器)的内容与指令中给出的地址偏移量相加,从而得到一个操作数的有效地址。变址寻址方式常用于访问某基地址附近的地址单元。采用变址寻址方式的指令又可以分为以下几种形式:

前变址模式:

LDR R0[R1,#4] R0←[R14]

自动变址模式:

LDR R0[R1,#4] R0←[R14]R1←R14

后变址模式:

LDR R0[R1] ,#4 R0←[R1]R1←R14

基址寄存器的地址偏移可以是一个立即数,也可以是另一个寄存器,并且在加到基址寄存器前还可以经过移位操作,如下所示:

LDR r0[r1r2]r0<—mem32[r1+r2]

3.2.5 堆栈寻址

堆栈是一种数据结构,按先进后出(First In Last OutFILO)的方式工作,使用一个称作堆栈指针的专用寄存器指示当前的操作位置,堆栈指针总是指向栈顶。

当堆栈指针指向最后压入堆栈的数据时,称为满堆栈(Full Stack),而当堆栈指针指向下一个将要放入数据的空位置时,称为空堆栈(Empty Stack)。

即访问存储器时,存储器的地址向高地址方向生长,称为递增堆栈(ascending stack)。 存储器的地址向低地址方向生长,称为递减堆栈(descending stack)。

四种类型的堆栈工作方式 :

满递增堆栈:堆栈指针指向最后压入的数据,且由低地址向高地址生成。

满递减堆栈:堆栈指针指向最后压入的数据,且由高地址向低地址生成。

空递增堆栈:堆栈指针指向下一个将要放入数据的空位置,且由低地址向高地址生成。

空递减堆栈:堆栈指针指向下一个将要放入数据的空位置,且由高地址向低地址生成。

3.2.6 块拷贝寻址

块拷贝寻址是多寄存器传送指令LDM/STM的寻址方式。LDM/STM指令可以把存储器中的一个数据块加载到多个寄存器中,也可以把多个寄存器中的内容保存到存储器中。寻址操作中的寄存器可以是R0-R1516个寄存器的子集或是所有寄存器。

LDM/STM指令依据其后缀名的不同其寻址的方式也有很大不同,见下表。

多寄存器loadstore指令的堆栈和块拷贝对照

3.2.7 相对寻址

与基址变址寻址方式相类似,相对寻址以程序计数器PC的当前值为基地址,指令中的地址标号作为偏移量,将两者相加之后得到操作数的有效地址。以下程序段完成子程序的调用和返回,跳转指令BL采用了相对寻址方式:

BL NEXT ;跳转到子程序

NEXT处执行

……

NEXT

……

MOV PCLR ;从子程序返回

3.3 ARM指令详细介绍

3.3.1 数据处理指令

ARM的数据处理指令主要完成寄存器中数据的算术和逻辑运算操作。本节按以下内容组织:

数据处理指令分类

数据处理指令根据指令实现处理功能可分为以下六类:

数据传送指令;

算术运算指令;

逻辑运算指令;

比较指令;

测试指令;

乘法指令。

数据处理指令表



3.3.2 Load/Store指令

ARM的数据存取指令Load/Store是唯一用于寄存器和存储器之间进行数据传送的指令。ARM指令集中有三种基本的数据存取指令:

单寄存器的存取指令(LDRSTR

单寄存器存取指令是ARM在寄存器和存储器间传送单个字节和字的最灵活方式。根据传送数据的类型不同,单个寄存器存取指令又可以分为以下两类:

单字和无符号字节的数据传送指令

这一类数据传送指令的汇编格式如下:

前变址格式

LDR|STR {} {B} Rd[Rn] {!}

后变址格式

LDR|STR {} {B} {T} Rd[Rn]

相对PC的形式

LDR|STR {} {B} RdLABEL

多寄存器存取指令(LDMSTM

多寄存器传送指令可以用一条指令将16个可见寄存器(R0~R15)的任意子集合(或全部)存储到存储器或从存储器中读取数据到该寄存器集合中。与单寄存器存取指令相比,多寄存器数据存取可用的寻址模式更加有限。多寄存器存取指令的汇编格式如下:



LDM/STM{} Rn{!}

单寄存器交换指令(SWP

3.3.3 程序状态寄存器与通用寄存器之间的传送指令

ARM指令中有两条指令,用于在状态寄存器和通用寄存器之间传送数据。修改状态寄存器一般是通过“读取-修改-写回”三个步骤的操作来实现的。这两条指令分别是:

状态寄存器到通用寄存器的传送指令(MRS

通用寄存器到状态寄存器的传送指令(MSR

MRS

其汇编格式如下:

MRS{} RdCPSR|SPSR

MSR

其汇编格式如下:

MSR{} CPSR_f | SPSR_f#<32-bit immediate>

MSR{} CPSR_ | SPSR_Rm

3.3.4 转移指令

ARM的转移指令可以从当前指令向前或向后的32MB的地址空间跳转,根据完成的功能它可以分为以下4种:

B 转移指令

BL 带链接的转移指令

BX 带状态切换的转移指令

BLX 带链接和状态切换的转移指令

转移和转移链接指令(BBL

转移指令B在程序中完成简单的跳转指令,可以跳转到指令中指定的目的地址。BL指令完全象转移指令一样地执行转移,同时把转移后面紧接的一条指令的地址保存到链接寄存器LRr14)。汇编格式如下:

B{L}{}

转移交换和转移链接交换(BXBLX

这些指令用于支持Thumb16位)指令集的ARM芯片,程序可以通过这些指令完成处理器从ARM状态到Thumb状态的切换。类似的Thumb指令可以使处理器切换回32ARM指令。

汇编格式如下:

1B{L}X{} Rm

2BLX

3.3.5 异常中断指令

异常中断指令可以分为一下两种:

软件中断指令(SWI

断点指令(BKPT—仅用于v5T体系)

软件中断指令SWI用于产生SWI异常中断,用来实现在用户模式下对操作系统中特权模式的程序的调用;断点中断指令BKPT主要用于产生软件断点,供调试程序用。

SWI

SWISoftWare Interrupt)代表“软件中断”,用于用户调用操作系统的系统例程,常称为“监控调用”。它将处理器置于监控(SVC)模式,从地址0x08开始执行指令。其汇编格式如下:

SWI {} <24位立即数>

断点指令(BKPT—仅用于v5T体系)

断点指令用于软件调试;它使处理器停止执行正常指令而进入相应的调试程序。



汇编格式如下:

BKPT { immed_16}

3.3.6 协处理器指令

RM支持16个协处理器,用于各种协处理器操作,最常使用的协处理器是用于控制片上功能的系统协处理器,例如控制ARM720上的高速缓存和存储器管理单元等,也开发了浮点ARM协处理器,还可以开发专用的协处理器。ARM协处理器指令根据其用途主要分为以下三类:

数据操作指令;

数据传送指令;

寄存器和内存单元之间的传送数据。

协处理器数据操作完全是协处理器内部的操作,它完成协处理器寄存器的状态改变。



汇编格式如下:

CDP{} CRdCRnCRm{}

协处理器数据传送指令从存储器读取数据装入协处理器寄存器,或将协处理器寄存器的数据存入存储器。



汇编格式如下:

前变址格式:

LDC|STC{}{L} CRd[Rn ]{!}

后变址格式:

LDC|STC{}{L} CRd[Rn]

ARM和协处理器寄存器之间传送数据有时是有用的。这些协处理寄存器传送指令使得协处理器中产生的整数能直接传送到ARM寄存器或者影响ARM条件码标志位。



汇编格式如下:

从协处理器传送到ARM寄存器:

MRC{} RdCRnCRm{}

ARM寄存器传送到协处理器:

MCR{} RdCRnCRm{}

阅读(1890) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~