文章详情

  • 游戏榜单
  • 软件榜单
关闭导航
热搜榜
热门下载
热门标签
php爱好者> php文档>嵌入式系统学习12-ARM指令集

嵌入式系统学习12-ARM指令集

时间:2009-03-13  来源:beauty2001

 

第三章 ARM指令集

3.1 ARM指令集概述

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

3.1.1 指令集编码

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

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

3.1.2 条件执行

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

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

3.1.3 指令分类及指令格式

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

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

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

opcode 操作码;指令助记符,如LDR、STR等。

cond 可选的条件码;执行条件,如EQ、NE等。

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

Rd 目标寄存器。

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

operand2 第2个操作数

3.2 ARM寻址方式

3.2.1 立即寻址

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

ADD R0,R0,#1 /*R0←R0+1*/

ADD R0,R0,#0x3f /*R0←R0+0x3f*/

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

3.2.2 寄存器寻址

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



ADD R0,R1,R2 /*R0←R1+R2*/

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

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

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



ADD R3,R2,R1,LSR #2 ;R3<—R2 + R1÷4

第二操作数移位方式

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

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

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

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

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

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



第二操作数的移位位数

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



ADD R3,R2,R1,LSR #2 ;R3 <—R2 + R1÷4

ADD R3,R2,R1,LSR 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←[R1+4]

自动变址模式:

LDR R0,[R1,#4]! ;R0←[R1+4]、R1←R1+4

后变址模式:

LDR R0,[R1] ,#4 ;R0←[R1]、R1←R1+4

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

LDR r0,[r1,r2];r0<—mem32[r1+r2]

3.2.5 堆栈寻址

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

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

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

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

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

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

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

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

3.2.6 块拷贝寻址

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

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

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

3.2.7 相对寻址

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

BL NEXT ;跳转到子程序

; NEXT处执行

……

NEXT

……

MOV PC,LR ;从子程序返回

3.3 ARM指令详细介绍

3.3.1 数据处理指令

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

数据处理指令分类

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

数据传送指令;

算术运算指令;

逻辑运算指令;

比较指令;

测试指令;

乘法指令。

数据处理指令表



3.3.2 Load/Store指令

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

单寄存器的存取指令(LDR,STR)

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

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

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

前变址格式

LDR|STR {<cond>} {B} Rd, [Rn, <offset>] {!}

后变址格式

LDR|STR {<cond>} {B} {T} Rd, [Rn],<offset>

相对PC的形式

LDR|STR {<cond>} {B} Rd, LABEL

多寄存器存取指令(LDM,STM)

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



LDM/STM{<cond>}<add mode> Rn{!}, <registers>

单寄存器交换指令(SWP)

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

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

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

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

MRS

其汇编格式如下:

MRS{<cond>} Rd,CPSR|SPSR

MSR

其汇编格式如下:

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

MSR{<cond>} CPSR_<field> | SPSR_<field>,Rm

3.3.4 转移指令

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

B 转移指令

BL 带链接的转移指令

BX 带状态切换的转移指令

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

转移和转移链接指令(B,BL)

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

B{L}{<cond>} <target address>

转移交换和转移链接交换(BX,BLX)

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

汇编格式如下:

1: B{L}X{<cond>} Rm

2: BLX <target address>

3.3.5 异常中断指令

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

软件中断指令(SWI)

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

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

SWI

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

SWI {<cond>} <24位立即数>

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

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



汇编格式如下:

BKPT { immed_16}

3.3.6 协处理器指令

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

数据操作指令;

数据传送指令;

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

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



汇编格式如下:

CDP{<cond>} <CP#>,<Cop1>,CRd,CRn,CRm{,<Cop2>}

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



汇编格式如下:

前变址格式:

LDC|STC{<cond>}{L} <CP#>,CRd,[Rn <offset>]{!}

后变址格式:

LDC|STC{<cond>}{L} <CP#>,CRd,[Rn],<offset>

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



汇编格式如下:

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

MRC{<cond>} <CP#>,<Cop1>,Rd,CRn,CRm{,<Cop2>}

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

MCR{<cond>} <CP#>,<Cop1>,Rd,CRn,CRm{,<Cop2>}

相关阅读 更多 +
排行榜 更多 +
开局一个小兵最新版

开局一个小兵最新版

休闲益智 下载
火柴人联盟2腾讯qq登录版

火柴人联盟2腾讯qq登录版

体育竞技 下载
tsuki odyssey游戏(月兔冒险奥德赛)

tsuki odyssey游戏(月兔冒险奥德赛)

休闲益智 下载