ARM指令分类及指令格式

ARM指令集使用标准的、固定长度的32位指令格式,所有ARM指令都是用4位的条件编码来决定指令是否执行,以解决指令执行的条件判断。由于ARM处理器是RISC结构,因此ARM处理器的指令集是加载/存储型的,也即数据处理类的指令仅能处理寄存器中的数据。无论对外部设备还是对系统存储器的访问都需要通过加载/存储指令来完成。

  1. ARM指令分类

ARM微处理器的指令集可以分为分支指令、数据处理指令、程序状态寄存器(CPSR)处理指令、加载/存储指令、协处理器指令和异常产生指令六大类,具体的指令及功能如表1-1所示。

  • 表1-1ARM指令及功能描述

助记符(按字母为序)

指令功能描述

所属类型

ADC

带进位加法指令

数据处理类之算术运算指令

ADD

加法指令

数据处理类之算术运算指令

AND

逻辑与指令

数据处理类之逻辑运算指令

B

跳转指令

分支类指令

BIC

位清零指令

数据处理类之逻辑运算指令

BKPT

断点中断指令

异常中断类指令

BL

带返回的跳转指令

分支类指令

BLX

带返回和状态切换的跳转指令

分支类指令

BX

带状态切换的跳转指令

分支类指令

CDP

协处理器数据操作指令

协处理器类指令

CMN

比较反值指令

数据处理类之比较类指令

CMP

比较指令

数据处理类之比较类指令

EOR

异或指令

数据处理类之逻辑运算指令

LDC

存储器到协处理器的数据传送指令

加载/存储类指令

LDM

加载多个寄存器指令

加载/存储类指令

LDR

存储器到寄存器的数据传送指令

加载/存储类指令

MCR

从寄存器到协处理器寄存器的数据类传送指令

协处理器类指令

MLA

乘加运算指令

数据处理类之算术运算指令

MOV

数据传送指令

数据处理类之数据传送指令

MRC

从协处理器寄存器到寄存器的数据传送指令

协处理器类指令

MRS

传送CPSR或SPSR的内容到通用寄存器指令

程序状态寄存器与通用寄存器传输类指令

MSR

传送通用寄存器到CPSR或SPSR的指令

程序状态寄存器与通用寄存器传输类指令

MUL

32位乘法指令

数据处理类之算术运算指令

MLA

32位乘加指令

数据处理类之算术运算指令

MVN

数据取反传送指令

数据处理类之数据传送指令

ORR

逻辑或指令

数据处理类之逻辑运算指令

RSB

逆向减法指令

数据处理类之算术运算指令

RSC

带借位的逆向减法指令

数据处理类之算术运算指令

SBC

带借位减法指令

数据处理类之算术运算指令

STC

协处理器寄存器写入存储器指令

协处理器类指令

STM

批量内存字写入指令

加载/存储类指令

STR

寄存器到存储器的数据传送指令

加载/存储类指令

SUB

减法指令

数据处理类之算术运算指令

SWI

软件中断指令

异常中断类指令

SWP

交换指令

数据处理类之交换指令

TEQ

相等测试指令

数据处理类之测试指令

TST

位测试指令

数据处理类之测试指令

一、数据处理类指令

  • 常用指令示例如下:

[例1-1] 数据传送指令:

MOV R1,R0 ;将寄存器R0的值传送到寄存器R1
MOV R1,R0,LSL#3 ;将寄存器RO的值左移3位后传送到R1

[例1-2]比较指令:

CMP R1,R0 ;将寄存器R1的值与寄存器RO的值相减,并根据结果设置CPSR的标志位
CMP R1,#100 ;将寄存器R1的值与立即数100相减,并根据结果设置CPSR的标志位

[例1-3] 位测试指令:

TST R1, #0x01 ;用于测试在寄存器R1中是否设置了最低位
TST R1,#0xFE ;将寄存器R1的值与立即数0xFE按位与,并据结果设置CPSR的标志位

[例1-4]相等测试指令:

TEQ R1,R2
将寄存器R1的值与寄存器R2的值按位异或,并根据结果设置CPSR的标志位

[例1-5]加法指令:

ADD R0,R1,R2 ;R0=R1+R2
ADD0,R1,#256 :R0=R1+256
ADD R0,R2,R3,LSL#1 ;R0=R2+(R3<<1)
ADCS R5,R6,R7 ;R5=R6+R7+C且更新CPSR状态
最后一条指令ADCS是带进位的加法。加S表示相加的结果会更新CPSR的状态标志位。

[例1-6]带进位加法指令:
以下指序列完成两个128位数的加法,第一个数由高到低存放在寄存器R7~ R4,第二个数由高到低存放在寄存器RI1- R8.运算结果由高到低存放在寄存器R3~ R0。

ADDS R0,R4,R8 ;加低端的字
ADCS R1,R5, R9 ;加第二个字,带进位
ADCS R2 ,R6,R10 ;加第三个字,带进位
ADC R3,R7,R1I ;加第四个字,带进位

[例1-7] 减法指令:

SUB R0,R1,R2 ;R0=R1-R2
SUB R0,R1,#256 ;R0=R1-256
SUB R0,R2, R3,LSL#1 ;R0=R2-(R3<<1)
SBCS R0,R1,R2 ;R0= R1-R2-!C,并根据结果设置CPSR的进位标志位

[例1-8] 逻辑操作指令:

AND R0,R0,#3 ;R0与3按位相与,结果放RO中

;该指令保持RO的0、1位不变,其余位清零

ORR R0,R0,#3 ;该指令将RO的0、1位置为1,其余位保持不变

AND指令经常用于屏蔽有些位(清零),ORR 指令经常用于置某些位为1。

[例1-9] 位清除指令:

BIC R0,R0,#0x0B ;该指令清除R0中的位0、1和3,其余的位保持不变

二、程序状态寄存器访问指令
ARM微处理器支持程序状态寄存器访问指令,用于在程序状态寄存器和通用寄存器之间传送数据。程序状态寄存器访问指令包括以下两条: MIRS (程序状态寄存器到通用寄存器的数据传送指令)和MSR(通用寄存器到程序状态寄存器的数据传送指令)。

1)MRS 一 程序状态寄存器到通用寄在器的数据传送指令

格式: MRS {cond} Rd, <PSR>;PSR可以是CPSR或SPSR
用途:MRS指令用于将程序状态寄存器的内容传送到通用寄存器中。该指令一般用在以下几种情况。
(1)当需要改变程序状态寄存器的内容时,可用MRS将程序状态寄存器的内容读人通用寄存器,修改后再写回程序状态寄存器。
(2)当在异常处理或进程切换时,需要保存程序状态寄存器的值,可先用该指令读出程序状态寄存器的值,然后保存。

[例2-1]

MRS R0,CPSR   ;传送CPSR的内容到R0
MRSR1,SPSR ;传送SPSR的内容到R1
  1. MSR 一 通用寄存器到程序状态寄存器的数据传送指令

格式: MSR {cond} <PSR> _ <fields>, Rm;PSR可以是CPSR或SPSR, fields为域

用途: MSR指令用于将操作数的内容传送到程序状态寄存器的特定域中。其中,操作数可以为通用寄存器或立即数。<fields>域用于 设置程序状态寄存器中需要操作的位,32位的程序状态寄存器可分为4个域:

PSR [31:24]为条件标志位域,用f表示,f为小写。
PSR [23:16]为状态位域,用s表示,s为小写。
PSR [15:8] 为扩展位域,用x表示,x为小写。
PSR [7:0]为控制位域,用c表示,e为小写。

该指令通常用于恢复或改变程序状态寄存器的内容,使用时一般要在 MSR指令中指明将要操作的域。

[例2-2]

MSR    CPSR,R0 ;传送R0的内容到CPSR
MSR SPSR,R1 ;传送RI的内容到SPSR
MSR CPSR_c,R2 ;传送R2的内容到CPSR,但仅仅修改CPSR中的控制位城

三、分支指令
分支指金用于实现阳店流时的路转在ARM程序中有两种方法可以实现程序流程的转移:一是使用专门的跳转指令,二是直直接向程序计数器PC写人跳转地址值(这在基于x86系统中是不可以的)。
通过向程序计数器PC写人跳转地址值,可以实现在4GB的地址空间中的任意跳转。在跳转之前结合使用MOVLR, PC等类似指令,可以保存将来的返回地址值,从而实现在4GB连续的线性地址空间的子程序调用。
ARM指令集中的分支指令可以完成从当前指令向前或向局的:(32 MP的地址空间的跳转包括4条指令: B转移指令、BL 带返回的转移指令、BLX带返回且带状态切换的转移指令,以及BX带状态切换的转移指令。

1)B 一 转移指令

格式: B { cond}   Label    ;Label为目标地址

用途: B指令是最简单的跳转指令。一旦遇到一个B指令,ARM处理器将立即跳转到给定的目标地址,从那里继续执行。注意,存储在跳转指令中的实际值是相对当前PC值的一个偏移量,而不是一个绝对地址,它的值由汇编器来计算(参考寻址方式中的相对寻址)。它是24位有符号数,左移两位后有效偏移为26位(前后32 MB的地址空间,即土32 MB)。
注意:如果使用指令: B .;这里的“.”表示当前地址,如x86 系统中的$,本条指令执行的效果是自循环,即进人死循环以等待系统复位,等于Label B Label。

[例3-1]

B         Label ;程序无条件跳转到标号Label处执行
CMP R1,#0 ;当CPSR寄存器中的Z条件码置位时,程序跳转到标号Label处执行
BEQ Label ;带条件等于EQ的转移

2)BX 一 带状态切换的转移指令

格式: BX {cond}<*Rn*>

用途:BX指令跳转到指令中所指定的由寄存器Rn与0xFFFF FFFE相与后的结果指示的天地址(即Rn [0]并不作为目标地址,而是作为状态切换位),目标地址处的指令既可以是ARM指令,也可以是Thumb指令。如果Rn中的最低位Rn [0] =1则指令将CPsR的T标志置1,且将目标地址的代码解释为Thumb(状态切换到Thumb指令集)。

[例3-2]

LDR   R6,=0x12000000+1
BX R6 ;转换到地址为0x12000000处,并切换到Thumh状态

3)BL一 带返回的转移指令

格式: BL {cond}   Label

用途: BL是带返回的跳转指令,在跳转之前,会在寄存器R14中保存PC的当前值。因此,可以通过将R14的内容重新加载到PC中,以返回到跳转指令之后的那个指令处执行。该旨令是实现子程序调用的一个基本且常用的手段。

[例3-3]

BL Label   ;程序无条件跳转到标号Label处执行同时将当前的PC值保存到R14中

4)BLX 一 带返回且带状态切换的转移指习

格式: BLX  目标地址

用途:BLX指令从ARM指令集跳转到指令中所指定的目标地址,并将处理器的工作状态由ARM状态切换到Thumb状态,该指令同时将PC的当前内容保存到寄存器R14中。因此,当子程序使用Thumb指令集,而调用者使用ARM指令集时,可以通过BLX指令实现子程序的调用和处理器工作状态的切换。同时,子程序的返回可以通过将寄存器R14值复制到PC中来完成。

[例3-4]

BLX LabelA    ;程序转移到LabelA处且切换到Thumb状态

四、加载/存储指令
ARM处理器对于存储器均采用加载/存储指令用于在寄存器和存储器之间传送数据。加载指令用于将存储器中的数据传送到寄存器,存储指今用于将寄存器中的数据传送到存储器。

1)单一数据加载/存储指令

单一数据加载/存储指令包括: LDR (字数据加载指令)、LDRB (字节数据加载指令)、LDRH (半字数据加载指令)、STR (字数据存储指令)、STRB (字节数据存储指令)和STRH(半字数据存储指令)。

(1)LDR 一 字数据加载指令

用途: LDR指令用于从存储器中将一个32位的字数据传送到目的寄存器中。
当程序计数器PC作为目的寄存器时,指令从存储器中读取的字数据被当作目的地址,从而可以实现程序流程的跳转。该指令在程序设计中比较常用,且寻址方式灵活多样。
[例4-1]

LDR R0,[R1]            ;将由 RI指示的存储器中的字数据读入寄存器R0 
LDR R4,[R1,R2] ;将由R1+R2指示的存储器中的字数据读入寄存器R4
LDR R2,[R1,#8 ;将由R1+8指示的存储器中的字数据读入寄存器R2
LDR R0,[R1,R2]! ;将由R1+R2指示的存储器中的字数据读入寄存器R0
;并将新地址R1+R2写入R1
LDR R0,[R1,#8]! ;将由R1+8指示的存储器中的字数据读入寄存器R0
;并将新地址R1+8写入R1
LDR R0,[R1],R2 ;将由R1指示的存储器的字数据读入寄存器R0,
;并将新地址R1+R2写入R1
LDR R0,[R1,R2,LSL#2]! ;将由 RI+R2x4指示的存储器中的字数据读入寄存器R0,
;并将新地址RI+R2x4写入R1。R2左移2位等于R2乘以4
LDR R0,[R1] ,R2,LSL#2 ;将由RI指示的存储器的字数据读入寄存器R0,
;并将新地址RI+R2x4写入RI

(2)LDRB 一 字节数据加载指令。
用途: LDRB指令用于从存储器中将一个8位的字节数据传送到目的寄存器中,同时将寄存器的高24位清零。当程序计数器PC作为目的寄存器时,指令从存储器中读取的字数据被当作目的地址,从而可以实现程序流程的跳转。

[例4-2]

LDRBR0,[ R1]      ;将由R1指示的存储器中的字节数据读人寄存器R0,并将R0的高24位清零
LDRB R0,[R1,#8] ;将由R1+8指示的存储器中的字节数据读人寿存器R0.并将R0的高24位清零

(3) LDRH 一 半字数据加载指令。
用途: LDRH指令用于从存储器中将 一个16位的半字数据传送到目的寄存器中, 同时将寄存器的高16位清零。当程序计数器PC作为目的寄存器时,指令从存储器中读取的字数据被当作目的地址,从而可以实现程序流程的跳转。

[例4-3]

LDRH R0,[R1];将由R1指示的存储器中的半字数据读人寄存器R0,并将R0的高16位清零LDRH R0,[R1,#8] ;将由R1+8指示的存储器中的半字数据读入寄存器R0,并将R0的高16位清零LDRH R0,[R1,R2] ;将由R1+R2指示的存储器中的半字数据读入寄存器R0,并将R0的高16位清零

(4)STR—字数据存储指令。
用途: STR指令用于从源寄存器中将一个32位的字数据传送到存储器中。该指令在程序设计中比较常用,且寻址方式灵活多样,使用方式可参考指令LDR。

[例4-4]

STR R0,[R1],#8     ;将R0中的字数据写入以RI为地址的存储器中,并将新地址R1+8写人RI
STR R0,[R1,#8 ] ;将RO中的字数据写入以R1+8为地址的存储器中

(5) STRB 一 字节数据存储指令。
用途: STRB指令用于从源寄存器中将一个8 位的字节数据传送到存储器中。该字节数据为源寄存器中的低8位。

[例 4-5]

STRB R0,[ R1]     ;将寄存器RO中的字节数据写入以R1为地址的存储器中
STRB R0,[ R1,#8] ;将寄存器RO中的字节数据写入以R1+8为地址的存储器中

(6) STRH 一 半字数据存储指令。
用途: STRH指令用于从源寄存器中将一个16位的半字数据传送到存储器中。该半字数据为源寄存器中的低16位。

[例4-6]

STRH R0,[R1]       ;将寄存器RO中的半字数据写入以R1为地址的存储器中
STRH R0,[R1,#8] ;将寄存器RO中的半字数据写入以R1+8为地址的存储器中

2 )批量数据加载/存储指令

ARM微处理器所支持的批量数据加载/存储指令可以一-次在一片连续的存储器单元和多个寄存器之间传送数据,批量加载指令用于将一片连续的存储器中的数据传送到多个寄存器,批量数据存储指令则完成相反的操作。
常用的加载/存储指令包括: LDM (批量数据加载指令)和STM (批量数据存储指令)。

(1) LDM 一 批量数据加载指令。

格式: LDM {条件} {类型} 基址寄存器 { ! },寄存器列表{ ^ }
用途: LDM指令用于将由基址寄存器所指示的一片连续在储器读到寄存器列表所指示的多个寄存器中,该指令的常见用途是将多个寄存器的内容出栈。
其中,{类型}见表2-1-1。

  • 表2-1-1批量数据传送中的类型

类型

LA

IB

DA

DB

含义

传送后地址加

传送前地址加

传送后地址减

地址加地址减

{ ! }为可选后缀,若选用该后缀,则当数据传送完毕之后将最后的地址写入基址寄存器,否则基址寄存器的内容不变。
基址寄存器不允许为R15,寄存器列表可以为RO~ RI5的任意组合。
{ ^ }为可选后缀,当指令为LDM且寄存器列表中包含RI5, 选用该后缀时表示:除了正常的数据传送之外,还将SPSR复制到CPSR。同时,该后级还表示传人或传出的是用户模式下的寄存器,而不是当前模式下的寄存器。

[例4-7]

LDMIA R1!,1R0,R4-R12}   ;将由RI指示的内在数据加载到寄存器R0,R4~R12中,
;传输完毕更新R1的值

(2) STM 一 批量数据存储指令。

用途: STM指令用于将寄存器列表所指示的多个寄存器的数据存储到由基址寄存器所指示的一片连续存储器中,该指令的常见用途是将多个寄存器的内容人栈。

[例4-8]

STMIA R3!,IR0, R4-R12,LR}  ;将寄存器R0,R4~R12以及LR的值存储到由R3
;指示的内存区域,传输完更新R3的值

五、协处理器指令

ARM微处理器可支持多达16个协处理器,用于各种协处理操作。在程序执行的过程中,每个协处理器只执行针对自身的协处理器指令,忽略ARM处理器和其他协处理器的指令。
ARM的协处理器指令主要用于ARM处理器初始化ARM协处理器的数据处理操作,在ARM处理器的寄存器和协处理器的寄存器之间传送数据,以及在ARM协处理器的寄存器和存储器之间传送数据。
ARM协处理器指令包括5条:CDP(协处理器数据操作指令)、LDC(协处理器数据加载指令)、STC(协处理器数据存储指令)、MCR(ARM处理器寄存器到协处理器寄存器的数据传送指令)以及MRC(协处理器寄存器到ARM处理器寄存器的数据传送指令)。
对协处理器指令不作要求,有兴趣的读者可以参考ARM指令集。

六、异常中断指令

ARM微处理器所支持的异常中断指令有如下两条: SWI(软件中断指令)和BKPT (断点中断指令)。

1)SWI 一 软件中断指令

格式: SWI { cond }imm24 ; imm24 为24位立即数
用途: SWI指令用于产生软件中断,以便用户程序能调用操作系统的系统例程。操作系统在s的并常处理程序中提供相应的系统服务,指全中2位的文即数指定用户程序调用系统例程的类型,相关参数通过通用寄存器传递,当指令中24位的立即数被忽略时,用户程调用系统例程的类型由通用许存器R0的内容决定,同时,参数通过其他通用寄存器传递。

[例6-1]

SWI 0x01    ;该指令调用操作系统编号为01的系统例程

2)BKPT 一 断点中断指令

格式: BKPT imm16   ; imm16 为16位立即数

用途: BKPT指令产生软件断点中断,可用于程序的调试。16位立即数用于保存软件调用中额外的断点信息。

[例6-2]

BKPT0xF010  ;产生断点中断,并保存断点信息0xF010
BKPT 64 ;产生断点中断,并保存断点信息64
  1. ARM指令格式
  • 表2-1指令格式说明

项目

含义

备注

<opcode>

指令的操作码

即助记符,如MOV、ADD、B等

{cond}

条件域,满足条件才执行指令

可不加条件即可省略条件,如EQ、NE等

{S}

条件执行时是否更新CPSR

可省略

Rd

目的寄存器

Rd可为任意通用寄存器

Rn

第一个源操作数

Rn可为任意通用寄存器,Rn可以与Rd相同

op2

第二个源操作数

可为#imm8m、寄存器Rm及任意移位寄存器

关于#imm8m的说明

  • 对于ARM指令集,#imm8m表示一个由8为立即数经循环右移任意偶数位次形成的32位操作数。
  • 对于Thumb指令集,#imm8m表示一个由8为立即数经左移任意偶数位次形成的32位操作数。
  1. 指令的条件域
    当处理器工作在ARM状态时,几乎所有的指令均根据CPS中条件码的状态和指令的条件域有条件的执行。当指令的执行满足条件时,指令被执行,否则指令被忽略。每一条ARM指令包含4位的条件码,位于指令的最高4位[31 : 28]。条件码共有16种,每种条件码可用两个字符表示,这两个字符可以添加在指令助记符的后面与指令同时使用。例如,跳转指令B可以加上后缀EQ变为BEQ表示“相等则跳转”,即当CPSR中的Z标志置位时发生跳转。
    在16种条件码中,只有15种可以使用,如下表3-1所示,第16种1111为系统保留,暂时不能使用。通常使用CMP指令产生条件标志。
  • 表3-1指令的条件码

条件码

助记符后缀

标志

含义

0000

EQ

Z置位

相等

0001

NE

Z清零

不相等

0010

CS

C置位

无符号数大于或等于

0011

CC

C清零

无符号数小于

0100

MI

N置位

负数

0101

PL

N清零

正数或零

0110

VS

V置位

溢出

0111

VC

V清零

未溢出

1000

HI

C置位Z清零

无符号数大于

1001

LS

C清零Z置位

无符号数小于或等于

1010

GE

N等于V

带符号数大于或等于

1011

LT

N不等于V

带符号数小于

1100

GT

Z清零且(N等于V)

带符号数大于

1101

LE

Z置位或(N不等于V)

带符号数小于或等于

1110

AL

忽略

无条件执行

  1. ARM指令中操作数符号
    ARM指令格式中,操作数有不同符号,现说明如下:
    (1) “#” 一 立即数符号
    “#”符号表示立即数,其后是十进制数或十六进制数。
    (2) “0x” 一 十六进制符号
    “0x”后面的数据( 每位可以是0-9、A~F)表示十六进制数,如0FFFF表示十六进制数FFFF,即十进制数65535。如果操作数为十进制数,则前面除了#外,没有其他符号, 如#65535,它与0xFFFF是等效的。
    (3) “!” 一 更新基址寄存器符号
    “!”符号表示指令在完成操作后最后的地址应该写人基址寄存器中。
    (4) “^” 一 复制SPSR到CPSR符号
    "^"符号用于批量数据存储指令中放在寄存器之后作为后缀,当其前面的寄存器不包含PC时,该符号表示所用的寄存器是用户模式的寄存器;当其前面的寄存器包含PC时,该符号指示将SPSR寄存器的值复制到CPSR寄存器中。
    (5) “–” 一 指示寄存器列表范围符号
    在有些指令中,表示多个连续寄存器(寄存器列表),中间用“–”。如R0-R7表示共8个寄存器: RO、 R1、R2、R3、R4、R5、R6、R7,即含义是“从…到……”。
  2. ARM指令中的移位操作数

ARM微处理器内嵌的桶型移位器(Barrel Shifter)支持数据的各种移位操作。移位操作在ARM指令集中不作为单独的指令使用,它只能在指令格式中作为一个字段, 在汇编语言中表示为指令中的选项。例如,数据处理指令的第2个操作数为寄存器时,就可以加人移位操作选项对它进行各种移位操作。
移位操作包括如下6种类型: LSL (逻辑左移)、ASL (算术左移)、LSR (逻辑右移)、Asr (算术右移)、ROR (循环右移)以及RRX (带扩展的循环右移)。
对通用寄存器进行移位操作的格式如下:
Rm,<opsh>#<shif>
其中,Rm为要移位的通用寄存器; <opsh>为移位操作符,包括LSL、ASL、 LSR、 ASR、 ROR及RRX; <shif>为移位次数 (0~31)。 移位操作及示例见表5-1。

  • 表5-1移位操作及示例

移位操作符opsh

操作含义

示例

示例说明

LSL

逻辑左移

MOV R0, R1, LSL.#2

将 R1中的内容左移2位送R0中。低位用0填充

ASL

算术左移

MOV R0, R2,ASL#3

将R2中的内容左移3位送R0中,LSL与ASL效果相同,可以互换

LSR

逻辑右移

MOV R0,R1,LSR#2

将R1中的内容右移两位后送到R0中,左端用0来填充

ASR

算术右移

MOV R0,R1,ASR#2

将RI中的内容右移两位后送到R0中,左端用第31位的值来填充

ROR

循环右移

MOV R0,R1, ROR#2

将R1中的内容循环右移两位后送到R0中

RRX

扩展的循环右移

MOV R0,R1, RRX#2

将R1中的内容进行带扩展(C标志)的循环右移两位后送到R0中

ARM 指令的寻址方式

所谓寻址方式,就足处理器根据指令中给出的源操作数地址信息来寻找物理地址的方式,目前ARM指令系统支持如下7种常见的寻址方式。

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

MOV R0, #0x12 ;R0=0x12
ADC R0,R0,#100 ;R0←R0+100+C
在以上两条指令中,第二个源操作数即为立即数,要求以“”为南缀,对于以士六进制表示的立即数,还要求在“#” 后加上“0x"," 不加0x表示十进制数。

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

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

  1. 寄存器间接寻址
    寄存器间接寻址就是以寄存器中的值作为操作数地址,而操作数本身存放在存储器中。甩于间接寻址的寄存器必须用[]括起来。例如以下指令:

LDR R5,[R4] ;R5←-[R4] ,间接寻址的寄存器是R4
STR RI,[R2] ;[R2]←RI,间接寻址的寄存器是R2
第1条指令是将以R4的值为地址的存储器中的数据传送到R5中。
第2条指令是将RI的值传送到以R2的值为地址的存储器中。
值得注意的是,由于ARM对存储器只有加载和存储两种操作,因此凡是与存储器操作有关的指令仅限于两类指令,即LDR和STR,其他类指令无效。

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

LDR R0, [R1, #4] ;R0←[R1+4]
本指令将寄存器RI的内容自动增加4,形成操作数的有效地址,从中取得32位操作数存人寄存器R0中。

STRRI, [R2, #8] ;[R2+8] ←R1
本指令将寄存器RI的32位操作数存储到R2+8指示地址开始的存储区域中。

LDR R0, [R1, #4]! ;R0←[R1+4]、R1←R1+4
本指令将寄存器R1的内容自动增加4形成操作数的有效地址,从中取得32位操作数存人寄存器R0中,然后R1的内容自增4。符号“!”表示指令在完成数据传送后应该更新基址寄存器。

LDR R0, [R1],#4 ;R0←[R1]、R1←R1+4
本指令以寄存器RI的内容作为操作数的有效地址,从而取得操作数存人寄存器R0中,然后R1的内容自动增加4。

LDR R0, [R1, R2] ; R0← [R1+R2]
本指令将寄存器RI的内容加上寄存器R2的内容形成操作数的有效地址,从而取得操作数存人寄存器R0中。

STR R0, [ R1, R2] ;[R1+R2]←R0
本指令将寄存器R0的内容存储到由R1+R2指示的有效地址对应的存储单元中。

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

Subroutine_ A

MOV PC,LR ;从子程序返回

示例中假设BL指令所在地址(PC值)为0x3100000,Subrouine _A对应偏移量为0x0100则转移到Subroutine_A处对应的地址为0100100此地址在汇编时自动形成。

  1. 堆栈寻址
    堆栈是一种数据结构, 按先进后出(FILO) 的方式工作,使用一个称作堆栈指针的专用寄存器指示当前的操作位置,堆栈指针总是指向栈顶。
    当堆栈指针指向最后压人堆栈的数据时,称为满堆栈(Full Stack),而当堆栈指针指向下一个将要放人数据的空位置时,称为空堆栈( Empty Stack)。
    同时,根据堆栈的生成方式,又可以分为递增堆栈(Ascending Stack) 和递减堆栈(De-scending Stack)。当堆栈由低地址向高地址生成时,称为递增堆栈;当堆栈由高地址向低地址生成时,称为递减堆栈。这样就有四种类型的堆栈工作方式:

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

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

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

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

7.块拷贝寻址
块拷贝寻址又称多寄存器寻址,来用多哥仔备寻址方式,一条指令可以完成多个寄存器值的传送。这种寻址方式可以用条指令完成传送报多16 个通用寄存器的值、例如以下指令:

LDMIA R0,{R1,R2,R5,R9} ;R1←[R0]
;R2←[R0+4]
;R5←[R0+8]
;R9←[R0+12]

此类指令的后级1A表示在每次执行完加载,存储操作后,RO按字长度增加,因此,指令可将连续存储单元的值传送到R1~R4。

STMIA RO,{R1-R7} ;[R0]←R1
;[R0+4]←R2
;[R0+8]←R3
;[R0+12]←R4
;[R0+16]←R5
;[R0+20]←R6
;[R0+24]←R7

块拷贝寻址是多寄存器传送指令LDM/STM的寻址方式。LDM/STM 指令可以将存储器中的一个数据块加载到多个寄存器中,也可以将多个寄存器中的内容存储到存储器中。寻址操作中的寄存器可以是R0~R15这16个寄存器的子集或全集。LDM/STM 依据后缀名的不同,其寻址方式有很大区别。