arm汇编 , 指令详解

http://blog.csdn.net/tigerjibo/article/details/6201716

一.前言

1.   看一个程序:

                 AREA    TigerJohn,CODE,READONLY;声明代码段

                     CODE32                       ;声明为32位ARM指令

                     ENTRY                         ;声明程序入口

START           MOV      R0 ,#0

                     MOV R1 ,#1

                     ADD R1, R1,R0

                     B     START

                     END

2.   在ARM汇编程序中用“;”号进行注释。

二.汇编语言程序格式

一个完整的ARM汇编由两部分组成:声明,实际代码段两部分组成。

1.   声明:在一个程序之前先要进行声明

1>都要声明什么

l  声明代码段:

用AREA指令定义一个段,说明所定义段的相关属性

(说明段的名字,段的属性)

l  声明ARM指令:

用CODE32或CODE16来声明程序为32位ARM指令或是16位Thumb指令。

l  声明程序入口:用ENTRY指令标识程序的入口点。

2>这3个声明缺一不可。

3>在程序完成后要用END 指令声明程序结束。每一个汇编程序段都必须有一条END指令,指示代码段的结束。

2.   段

1>在ARM汇编语言程序中,以程序段为单位组织代码。段是相对独立的指令或数据序列,具有特定的名称。

2>段的分类

Ø 代码段:代码段的内容为执行代码

Ø 数据段:数据段存放代码运行时需要用到的数据。

注:一个汇编程序至少有一个代码段。如果程序较长时,可以分割为多个代码段和数据段。多个段在程序编译连接时最终形成一个可执行的映像文件。

3>段具有以下的属性

Ø READONLY

Ø READWRITE

三.汇编语言的语句格式

[LABEL]  OPERATION  [OPERAND] [;COMMENT]

标号域 操作助记符域 操作数域   注释域 

1.   标号域(LABLE)

1>标号域用来表示指令的地址、变量、过程名、数据的地址和常量。

2>标号是可以自己起名的标识符,语句标号可以是大小写字母混合,通常以字母开头,由字母、数字、下划线等组成。

3> 语句标号不能与寄存器名、指令助记符、伪指令(操作)助记符、变量名同名。

4> 语句标号必须在一行的开头书写,不能留空格。     

2.   操作助记符域(OPERATION)

1>操作助记符域可以为指令、伪操作、宏指令或伪指令的助记符。

2> ARM汇编器对大小写敏感,在汇编语言程序设计中,每一条指令的助记符可以全部用大写、或全部用小写,但不允许在一条指令中大、小写混用

3> 所有的指令都不能在行的开头书写,必须在指令的前面有空格,然后再书写指令。

4> 指令助记符和后面的操作数或操作寄存器之间必须有空格,不可以在这之间使用逗号。

3.   操作数域(OPERAND)

操作数域表示操作的对象,操作数可以是常量、变量、标号、寄存器名或表达式,不同对象之间必须用逗号“,”分开。

四.ARM指令集格式

opcode  {<cond>}{S}    <Rd>,<Rn>  {,<operand2>}

1.   其中<>中的项是必须的,{}中的项是可选的。

2.   opcode  表示指令助记符。

cond:表示执行条件。

S:表示是否影响CPSR寄存器的值,如果+s则表示将影响写入到SPSR。  nzcvqIFt_SVC

Rd:表示目标寄存器。

Rn:表示第一个操作数的寄存器。

operand2:表示第2个操作数。

3.“operand2”具有如下的形式:

1>#immed_8r:常数表达式

eg:MOV  R0,#1

      ADD   R0,R1,#0X0F 



2>Rm:寄存器形式。

即在寄存器方式下,操作数即为寄存器的数值。

eg:MOV     PC,R0

      ADD     R1,R1,R2

3>Rm,shift:寄存器移位方式。

将寄存器的移位结果作为操作数,当Rm值保持不变。

Ø ASR #n:表示算术右移n位。

Ø LSR  #n:表示逻辑右移n位。

Ø ROR #n:表示循环右移n位。

Ø RRX    #n:带扩展的循环右移n位。

Ø LSL  #n:逻辑左移n位。

3.   使用条件码“cond”可以实现高效的逻辑操作,提高代码的效率。

Ø 所有的ARM指令都可以条件执行。

Ø Thumb指令只有B(跳转)指令具有条件执行功能。

注:如果执行中不表明条件码,默认为无条件(AL)执行。

五.汇编程序中常用的符号

在汇编语言程序设计中,经常使用各种符号表示变量、常量和地址

Ø 符号由大小写字母、数字以及下划线组成。

Ø 符号区分大小写,同名的大、小写符号会被编译器认为是两个不同的符号。

Ø 符号在其作用范围内必须唯一,即在其作用范围内不可有同名的符号。

Ø 自定义的符号名不能与系统的保留字相同。

  符号名不应与指令或伪指令同名。

1.   程序中的变量:

1>ARM汇编程序所支持的变量有数字变量,逻辑变量和字符串变量

2>在ARM汇编程序设计中,可使用GBLA,GBLL,GBLS伪定义声明全局变量,使用LCLA,LCLL,LCLS声明局部变量,并可使用SETA,SETL和SETS对其经行初始化。

2.   程序中的常量

1>ARM汇编程序所支持常量有数字常量,逻辑常量和字符串常量。

3.   程序中的变量代换

1>程序中的变量可通过代换操作取的一个常量。代换操作符为”$”

2>使用示例:

LCLS    S1

LCLS    S2    ;定义局部字符串变量S1和S2

S1       SETS        “Test!”

S2       SETS        “This is a $ S1”;S2的值为“This is a Test




---------------------------------- 指令详解-----------------------------------------

  

ARM汇编指令集

一、跳转指令。跳转指令用于实现程序流程的跳转,在ARM程序中有以下两种方法可以实现程序流程的跳转。
.使用专门的跳转指令。.直接向程序计数器PC写入跳转地址值。
通过向程序计数器PC写入跳转地址值,可以实现在4GB的地址空间中的任意跳转,在跳转之前结合使用
MOV LR
PC等类似指令,可以保存将来的返回地址值,从而实现在4GB连续的线性地址空间的子程序调用。ARM指令集中的跳转指令可以完成从当前指令向前或向后的32MB的地址空间的跳转,包括以下4条指令:
1
B指令
B指令的格式为:
B{
条件}目标地址
B
指令是最简单的跳转指令。一旦遇到一个B指令,ARM处理器将立即跳转到给定的目标地址,从那里继续执行。注意存储在跳转指令中的实际值是相对当前PC值的一个偏移量,而不是一个绝对地址,它的值由汇编器来计算(参考寻址方式中的相对寻址)。它是24位有符号数,左移两位后有符号扩展为32位,表示的有效偏移为26(前后32MB的地址空间)。以下指令:
B    Label            
程序无条件跳转到标号Label处执行
CMP R1
,#0     CPSR寄存器中的Z条件码置位时,程序跳转到标号Label处执行
BEQ Label     
2
BL指令
BL
指令的格式为:
BL{
条件}目标地址
BL
是另一个跳转指令,但跳转之前,会在寄存器R14中保存PC的当前内容,因此,可以通过将R14的内容重新加载到PC中,来返回到跳转指令之后的那个指令处执行。该指令是实现子程序调用的一个基本但常用的手段以下指令:
BL   Label         ;当程序无条件跳转到标号Label处执行时,同时将当前的PC值保存到R14(LR)中

......

Label

.....

MOV PC,LR  ;在执行完Label函数这部分后,再跳回去原来地方继续执行


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


二、数据处理指令。数据处理指令可分为数据传送指令、算术逻辑运算指令和比较指令等。
数据传送指令用于在寄存器和存储器之间进行数据的双向传输。
算术逻辑运算指令完成常用的算术与逻辑的运算,该类指令不但将运算结果保存在目的寄存器中,同时更新CPSR中的相应条件标志位。
比较指令不保存运算结果,只更新CPSR中相应的条件标志位。
数据处理指令共以下16条。
1
MOV指令(传送)
MOV指令的格式为:
MOV{
条件}{S}目的寄存器,源操作数
MOV
指令可完成从另一个寄存器、被移位的寄存器或将一个立即数加载到目的寄存器。其中S选项决定指令的操作是否影响CPSR中条件标志位的值,当没有S时指令不更新CPSR中条件标志位的值。
指令示例:
MOV R1
R0                   将寄存器R0的值传送到寄存器R1
MOV PCR14                 将寄存器R14的值传送到PC,常用于子程序返回
MOV R1R0LSL3    将寄存器R0的值左移3位后传送到R1
2MVN指令(求反)
MVN
指令的格式为:
MVN{
条件}{S}目的寄存器,源操作数
MVN
指令可完成从另一个寄存器、被移位的寄存器、或将一个立即数加载到目的寄存器。与MOV指令不同之处是在传送之前按位被取反了,即把一个被取反的值传送到目的寄存器中。其中S决定指令的操作是否影响CPSR中条件标志位的值,当没有S时指令不更新CPSR中条件标志位的值。
指令示例:
MVN R0
,#0           将立即数0取反传送到寄存器R0中,完成后R0=-1
3
CMP指令(比较)
CMP指令的格式为:
CMP{
条件}操作数1,操作数2
CMP
指令用于把一个寄存器的内容和另一个寄存器的内容或立即数进行比较,同时更新CPSR中条件标志位的值。该指令进行一次减法运算,但不存储结果,只更改条件标志位。标志位表示的是操作数1与操作数2的关系(大、小、相等),例如,当操作数1大于操作操作数2,则此后的有GT后缀的指令将可以执行。
指令示例:
CMP   R1
R0             将寄存器R1的值与寄存器R0的值相减,并根据结果设置CPSR的标志位
CMP R1,#100         将寄存器R1的值与立即数100相减,并根据结果设置CPSR的标志位
4CMN指令(负数比较)
CMN指令的格式为:
CMN{
条件}操作数1,操作数2
CMN
指令用于把一个寄存器的内容和另一个寄存器的内容或立即数取反后进行比较,同时更新CPSR中条件标志位的值。该指令实际完成操作数1和操作数2相加,并根据结果更改条件标志位。
指令示例:
CMN   R1
R0             将寄存器R1的值与寄存器R0的值相加,并根据结果设置CPSR的标志位
CMN R1,#100        将寄存器R1的值与立即数100相加,并根据结果设置CPSR的标志位
5TST指令(测试)
TST
指令的格式为:
TST{
条件}操作数1,操作数2
TST
指令用于把一个寄存器的内容和另一个寄存器的内容或立即数进行按位的与运算,并根据运算结果更新CPSR中条件标志位的值。操作数1是要测试的数据,而操作数2是一个位掩码,该指令一般用来检测是否设置了特定的位。
指令示例:
TST   R1
,#%1            用于测试在寄存器R1中是否设置了最低位(%表示二进制数)
TST R1
,#0xffe          将寄存器R1的值与立即数0xffe按位与,并根据结果设置CPSR的标志位
6
TEQ指令(测试相等)
TEQ指令的格式为:
TEQ{
条件}操作数1,操作数2
TEQ
指令用于把一个寄存器的内容和另一个寄存器的内容或立即数进行按位的异或运算,并根据运算结果更新CPSR中条件标志位的值。该指令通常用于比较操作数1和操作数2是否相等。
指令示例:
TEQ   R1
R2         将寄存器R1的值与寄存器R2的值按位异或,并根据结果设置CPSR的标志位
7
ADD指令(相加)
ADD指令的格式为:
ADD{
条件}{S}目的寄存器,操作数1,操作数2
ADD
指令用于把两个操作数相加,并将结果存放到目的寄存器中。操作数1应是一个寄存器,操作数2可以是一个寄存器,被移位的寄存器,或一个立即数。
指令示例:
ADD     R0
R1R2                 R0 = R1 + R2
ADD     R0
R1#256               R0 = R1 + 256
ADD     R0R2R3LSL#1      R0 = R2 +(R3 << 1)
8ADC指令(带进位相加)
ADC
指令的格式为:
ADC{
条件}{S}目的寄存器,操作数1,操作数2
ADC
指令用于把两个操作数相加,再加上CPSR中的C条件标志位的值,并将结果存放到目的寄存器中。它使用一个进位标志位,这样就可以做比32位大的数的加法,注意不要忘记设置S后缀来更改进位标志。操作数1应是一个寄存器,操作数2可以是一个寄存器,被移位的寄存器,或一个立即数。
以下指令序列完成两个128位数的加法,第一个数由高到低存放在寄存器R7R4,第二个数由高到低存放在寄存器R11R8,运算结果由高到低存放在寄存器R3R0
ADDS    R0
R4R8         加低端的字
ADCS    R1
R5R9         加第二个字,带进位
ADCS    R2R6R10       加第三个字,带进位
ADC      R3R7R11       加第四个字,带进位
9SUB指令(相减)
SUB指令的格式为:
SUB{
条件}{S}目的寄存器,操作数1,操作数2
SUB
指令用于把操作数1减去操作数2,并将结果存放到目的寄存器中。操作数1应是一个寄存器,操作数2可以是一个寄存器,被移位的寄存器,或一个立即数。该指令可用于有符号数或无符号数的减法运算。
指令示例:
SUB     R0
R1R2                R0 = R1 - R2
SUB     R0R1#256           R0 = R1 -256
SUB     R0
R2R3LSL#1     R0 = R2 -(R3 << 1)
10
~~~~C指令
~~~~C
指令的格式为:
~~~~C{
条件}{S}目的寄存器,操作数1,操作数2
~~~~C
指令用于把操作数1减去操作数2,再减去CPSR中的C条件标志位的反码,并将结果存放到目的寄存器中。操作数1应是一个寄存器,操作数2可以是一个寄存器,被移位的寄存器,或一个立即数。该指令使用进位标志来表示借位,这样就可以做大于32位的减法,注意不要忘记设置S后缀来更改进位标志。该指令可用于有符号数或无符号数的减法运算。
指令示例:
SUBS    R0
R1R2       R0 = R1 - R2 - C,并根据结果设置CPSR的进位标志位
11R~~~~指令
R~~~~
指令的格式为:
R~~~~{
条件}{S}目的寄存器,操作数1,操作数2
R~~~~
指令称为逆向减法指令,用于把操作数2减去操作数1,并将结果存放到目的寄存器中。操作数1应是一个寄存器,操作数2可以是一个寄存器,被移位的寄存器,或一个立即数。该指令可用于有符号数或无符号数的减法运算。
指令示例:
R~~~~     R0
R1R2                        R0 = R2 R1
R~~~~     R0R1#256                    R0 = 256 R1
R~~~~     R0R2R3LSL#1          R0 = (R3<< 1) - R2
12RSC指令(反向带进位减)
RSC指令的格式为:
RSC{
条件}{S}目的寄存器,操作数1,操作数2
RSC
指令用于把操作数2减去操作数1,再减去CPSR中的C条件标志位的反码,并将结果存放到目的寄存器中。操作数1应是一个寄存器,操作数2可以是一个寄存器,被移位的寄存器,或一个立即数。该指令使用进位标志来表示借位,这样就可以做大于32位的减法,注意不要忘记设置S后缀来更改进位标志。该指令可用于有符号数或无符号数的减法运算。
指令示例:
RSC     R0
R1R2          R0 = R2 R1 - C
13
AND指令(逻辑位与)
AND
指令的格式为:
AND{
条件}{S}目的寄存器,操作数1,操作数2
AND
指令用于在两个操作数上进行逻辑与运算,并把结果放置到目的寄存器中。操作数1应是一个寄存器,操作数2可以是一个寄存器,被移位的寄存器,或一个立即数。该指令常用于屏蔽操作数1的某些位。
指令示例:
AND R0
R0,#3         该指令保持R001位,其余位清零。
14
ORR指令(逻辑位或)
ORR指令的格式为:
ORR{
条件}{S}目的寄存器,操作数1,操作数2
ORR
指令用于在两个操作数上进行逻辑或运算,并把结果放置到目的寄存器中。操作数1应是一个寄存器,操作数2可以是一个寄存器,被移位的寄存器,或一个立即数。该指令常用于设置操作数1的某些位。
指令示例:
ORR R0
R0,#3       该指令设置R001位,其余位保持不变。
15
EOR指令(逻辑位异或)
EOR
指令的格式为:
EOR{
条件}{S}目的寄存器,操作数1,操作数2
EOR
指令用于在两个操作数上进行逻辑异或运算,并把结果放置到目的寄存器中。操作数1应是一个寄存器,操作数2可以是一个寄存器,被移位的寄存器,或一个立即数。该指令常用于反转操作数1的某些位。
指令示例:
EOR R0
R0,#3       该指令反转R001位,其余位保持不变。
16
BIC指令(位清零)
BIC
指令的格式为:
BIC{
条件}{S}目的寄存器,操作数1,操作数2
BIC
指令用于清除操作数1的某些位,并把结果放置到目的寄存器中。操作数1应是一个寄存器,操作数2可以是一个寄存器,被移位的寄存器,或一个立即数。操作数232位的掩码,如果在掩码中设置了某一位,则清除这一位。未设置的掩码位保持不变。
指令示例:
BIC R0
R0,#%1011   该指令清除R0中的位 01、和 3,其余的位保持不变。


三、乘法指令与乘加指令。ARM微处理器支持的乘法指令与乘加指令共有6条,可分为运算结果为32位和运算结果为64位两类,与前面的数据处理指令不同,指令中的所有操作数、目的寄存器必须为通用寄存器,不能对操作数使用立即数或被移位的寄存器,同时,目的寄存器和操作数1必须是不同的寄存器。
乘法指令与乘加指令共有以下6条:
1
MUL指令(相乘)
MUL
指令的格式为:
MUL{
条件}{S}目的寄存器,操作数1,操作数2
MUL
指令完成将操作数1与操作数2的乘法运算,并把结果放置到目的寄存器中,同时可以根据运算结果设置CPSR中相应的条件标志位。其中,操作数1和操作数2均为32位的有符号数或无符号数。
指令示例:
MUL R0
R1R2           R0 = R1× R2
MULS R0R1R2           R0 = R1 × R2,同时设置CPSR中的相关条件标志位
2MLA指令(带累加的相乘)
MLA指令的格式为:
MLA{
条件}{S}目的寄存器,操作数1,操作数2,操作数3
MLA
指令完成将操作数1与操作数2的乘法运算,再将乘积加上操作数3,并把结果放置到目的寄存器中,同时可以根据运算结果设置CPSR中相应的条件标志位。其中,操作数1和操作数2均为32位的有符号数或无符号数。
指令示例:
MLA   R0
R1R2R3           R0 = R1 × R2 + R3
MLAS R0
R1R2R3           R0 = R1× R2 + R3,同时设置CPSR中的相关条件标志位
3
SMULL指令
SMULL
指令的格式为:
SMULL{
条件}{S}  目的寄存器Low,目的寄存器High,操作数1,操作数2
SMULL
指令完成将操作数1与操作数2的乘法运算,并把结果的低32位放置到目的寄存器Low中,结果的高32位放置到目的寄存器High中,同时可以根据运算结果设置CPSR中相应的条件标志位。其中,操作数1和操作数2均为32位的有符号数。
指令示例:
SMULL   R0
R1R2R3    R0 =R2 × R3)的低32
                                               R1 =R2 × R3)的高32
4SMLAL指令
SMLAL
指令的格式为:
SMLAL{
条件}{S}  目的寄存器Low,目的寄存器High,操作数1,操作数2
SMLAL
指令完成将操作数1与操作数2的乘法运算,并把结果的32位同目的寄存器Low中的值相加后又放置到目的寄存器Low中,结果的高32位同目的寄存器High中的值相加后又放置到目的寄存器High中,同时可以根据运算结果设置CPSR中相应的条件标志位。其中,操作数1和操作数2均为32位的有符号数。
对于目的寄存器Low,在指令执行前存放64位加数的低32位,指令执行后存放结果的低32位。
对于目的寄存器High,在指令执行前存放64位加数的高32位,指令执行后存放结果的高32位。
指令示例:
SMLAL   R0
R1R2R3       R0 =R2 × R3)的低32 R0
                                                
R1 =R2 × R3)的高32 R1
5
UMULL指令
UMULL
指令的格式为:
UMULL{
条件}{S}  目的寄存器Low,目的寄存器High,操作数1,操作数2
UMULL
指令完成将操作数1与操作数2的乘法运算,并把结果的低32位放置到目的寄存器Low中,结果的高32位放置到目的寄存器High中,同时可以根据运算结果设置CPSR中相应的条件标志位。其中,操作数1和操作数2均为32位的无符号数。
指令示例:
UMULL   R0
R1R2R3      R0 =R2 × R3)的低32
                                                R1 =R2 × R3)的高32
6UMLAL指令
UMLAL指令的格式为:
UMLAL{
条件}{S}  目的寄存器Low,目的寄存器High,操作数1,操作数2
UMLAL
指令完成将操作数1与操作数2的乘法运算,并把结果的32位同目的寄存器Low中的值相加后又放置到目的寄存器Low中,结果的高32位同目的寄存器High中的值相加后又放置到目的寄存器High中,同时可以根据运算结果设置CPSR中相应的条件标志位。其中,操作数1和操作数2均为32位的无符号数。
对于目的寄存器Low,在指令执行前存放64位加数的低32位,指令执行后存放结果的低32位。
对于目的寄存器High,在指令执行前存放64位加数的高32位,指令执行后存放结果的高32位。
指令示例:
UMLAL   R0
R1R2R3           R0 = R2 × R3)的低32 R0
                                                      
R1 =R2 × R3)的高32 R1
四、程序状态寄存器访问指令

1MRS指令
MRS指令的格式为:
MRS{
条件}   通用寄存器程序状态寄存器(CPSRSPSR
MRS
指令用于将程序状态寄存器的内容传送到通用寄存器中。该指令一般用在以下两种情况:
.当需要改变程序状态寄存器的内容时,可用MRS将程序状态寄存器的内容读入通用寄存器,修改后再写回程序状态寄存器。
.当在异常处理或进程切换时,需要保存程序状态寄存器的值,可先用该指令读出程序状态寄存器的值,然后保存。
指令示例:
MRS R0
CPSR                        传送CPSR的内容到R0
MRS R0SPSR                        传送SPSR的内容到R0
2
MSR指令
MSR指令的格式为:
MSR{
条件}   程序状态寄存器(CPSRSPSR_<>,操作数
MSR
指令用于将操作数的内容传送到程序状态寄存器的特定域中。其中,操作数可以为通用寄存器或立即数。<>用于设置程序状态寄存器中需要操作的位,32位的程序状态寄存器可分为4个域:
[3124]为条件位域,用f表示;
[2316]为状态位域,用s表示;
[158]为扩展位域,用x表示;
[70]   为控制位域,用c表示;
该指令通常用于恢复或改变程序状态寄存器的内容,在使用时,一般要在MSR指令中指明将要操作的域。
指令示例:
MSR CPSR
R0       传送R0的内容到CPSR
MSR SPSRR0       传送R0的内容到SPSR
MSR CPSR_cR0    传送R0的内容到SPSR但仅仅修改CPSR中的控制位域

五、加载/存储指令。ARM微处理器支持加载/存储指令用于在寄存器和存储器之间传送数据,加载指令用于将存储器中的数据传送到寄存器,存储指令则完成相反的操作。常用的加载存储指令如下:
1
LDR指令
LDR
指令的格式为:
LDR{
条件}目的寄存器,<存储器地址>
LDR
指令用于从存储器中将一个32位的字数据送到目的寄存器中。该指令通常用于从存储器中读取32位的字数据到通用寄存器,然后对数据进行处理。当程序计数器PC作为目的寄存器时,指令从存储器中读取的字数据被当作目的地址,从而可以实现程序流程的跳转。该指令在程序设计中比较常用,且寻址方式灵活多样,请读者认真掌握。
指令示例:
LDR R0
[R1]               将存储器地址为R1的字数据读入寄存器R0一次load一个字,4字节
LDR R0[R1R2]      将存储器地址为R1+R2的字数据读入寄存器R0

LDR R0[R1#8]       将存储器地址为R1+8的字数据读入寄存器R0
LDR R0
[R1R2]   将存储器地址为R1+R2的字数据读入寄存器R0,并将新地址R1R2写入R1
LDR R0
[R1,#8]  将存储器地址为R1+8的字数据读入寄存器R0,并将新地址R18写入R1
LDR R0
[R1]R2       将存储器地址为R1的字数据读入寄存器R0,并将新地址R1R2写入R1
LDR R0
[R1R2LSL2]将存储器地址为R1R2×4的字数据读入寄存器R0,并将新地址R1R2×4写入R1
LDR R0[R1]R2LSL2     将存储器地址为R1的字数据读入寄存器R0,并将新地址R1R2×4写入R1
2LDRB指令
LDRB
指令的格式为:
LDR{
条件}B目的寄存器,<存储器地址>
LDRB
指令用于从存储器中将一个8的字节数据传送到目的寄存器中,同时将寄存器的24位清零。该指令通常用于从存储器中读取8位的字节数据到通用寄存器,然后对数据进行处理。当程序计数器PC作为目的寄存器时,指令从存储器中读取的字数据被当作目的地址,从而可以实现程序流程的跳转。
指令示例:
LDRB R0
[R1]                 将存储器地址为R1的字节数据读入寄存器R0,并将R0的高24位清零。
LDRB R0
[R1,#8]      将存储器地址为R18的字节数据读入寄存器R0,并将R0的高24位清零。
3
LDRH指令
LDRH指令的格式为:
LDR{
条件}H目的寄存器,<存储器地址>
LDRH
指令用于从存储器中将一个16的半字数据传送到目的寄存器中,同时将寄存器的16位清零。该指令通常用于从存储器中读取16位的半字数据到通用寄存器,然后对数据进行处理。当程序计数器PC作为目的寄存器时,指令从存储器中读取的字数据被当作目的地址,从而可以实现程序流程的跳转。
指令示例:
LDRH   R0
[R1]            将存储器地址为R1的半字数据读入寄存器R0,并将R0的高16位清零。
LDRH R0
[R1,#8]    将存储器地址为R18的半字数据读入寄存器R0,并将R0的高16位清零。
LDRH R0
[R1R2]    将存储器地址为R1R2的半字数据读入寄存器R0,并将R0的高16位清零。
4
STR指令
STR
指令的格式为:
STR{
条件}源寄存器,<存储器地址>
STR
指令用于从源寄存器中将一个32位的字数据传送到存储器中。该指令在程序设计中比较常用,且寻址方式灵活多样,使用方式可参考指令LDR
指令示例:
STR R0
[R1],#8          R0中的字数据写入以R1为地址的存储器中,并将新地址R18写入R1
STR R0
[R1,#8]         R0中的字数据写入以R18为地址的存储器中。
5STRB指令
STRB
指令的格式为:
STR{
条件}B源寄存器,<存储器地址>
STRB
指令用于从源寄存器中将一个8的字节数据传送到存储器中。该字节数据为源寄存器中的低8位。
指令示例:
STRB    R0
[R1]            将寄存器R0中的字节数据写入以R1为地址的存储器中。
STRB    R0
[R1,#8]    将寄存器R0中的字节数据写入以R18为地址的存储器中。
6STRH指令
STRH
指令的格式为:
STR{
条件}H源寄存器,<存储器地址>
STRH
指令用于从源寄存器中将一个16的半字数据传送到存储器中。该半字数据为源寄存器中的低16位。
指令示例:
STRH   R0
[R1]           将寄存器R0中的半字数据写入以R1为地址的存储器中。
STRH   R0[R1,#8]   将寄存器R0中的半字数据写入以R18为地址的存储器中。


六、批量数据加载/存储指令。ARM微处理器所支持批量数据加载/存储指令可以一次在一片连续的存储器单元和多个寄存器之间传送数据,批量加载指令用于将一片连续的存储器中的数据传送到多个寄存器,批量数据存储指令则完成相反的操作。常用的加载存储指令如下:LDM(或STM)指令
LDM
(或STM)指令的格式为:
LDM
(或STM{条件}{类型}基址寄存器{},寄存器列表{}
LDM
(或STM)指令用于从由基址寄存器所指示的一片连续存储器到寄存器列表所指示的多个寄存器之间传送数据,该指令的常见用途是将多个寄存器的内容入栈或出栈。其中,{类型}为以下几种情况:
IA   
每次传送后地址加11个字 4字节)
IB     
每次传送前地址加1
DA  
每次传送后地址减1
DB  
每次传送前地址减1
FD   满递减堆栈;
ED  
空递减堆栈;
FA  
满递增堆栈;
EA  
空递增堆栈;
{
}为可选后缀,若选用该后缀,则当数据传送完毕之后,将最后的地址写入基址寄存器,否则基址寄存器的内容不改变。
基址寄存器不允许为R15,寄存器列表可以为R0R15的任意组合。
{
}为可选后缀,当指令为LDM且寄存器列表中包含R15,选用该后缀时表示:除了正常的数据传送之外,还将SPSR复制到CPSR。同时,该后缀还表示传入或传出的是用户模式下的寄存器,而不是当前模式下的寄存器。
指令示例:
STM
FD R13!{R0R4-R12LR}       将寄存器列表中的寄存器(R0R4R12LR)存入堆栈。
LDMFDR13!{R0R4-R12PC}      将堆栈内容恢复到寄存器(R0R4R12LR)。


七、数据交换指令
1
SWP指令
SWP
指令的格式为:
SWP{
条件}目的寄存器,源寄存器1[源寄存器2]
SWP
指令用于将源寄存器2所指向的存储器中的字数据传送到目的寄存器中,同时将源寄存器1中的字数据传送到源寄存器2所指向的存储器中。显然,当源寄存器1和目的寄存器为同一个寄存器时,指令交换该寄存器和存储器的内容。
指令示例:
SWP   R0
R1[R2]    R2所指向的存储器中的字数据传送到R0,同时将R1中的字数据传送到R2所指向的存储单元。
SWP   R0R0[R1]    该指令完成将R1所指向的存储器中的字数据与R0中的数据交换。
2
SWPB指令
SWPB指令的格式为:
SWP{
条件}B目的寄存器,源寄存器1[源寄存器2]
SWPB
指令用于将源寄存器2所指向的存储器中的字节数据传送到目的寄存器中,目的寄存器的高24清零,同时将源寄存器1中的字节数据传送到源寄存器2所指向的存储器中。显然,当源寄存器1和目的寄存器为同一个寄存器时,指令交换该寄存器和存储器的内容。
指令示例:
SWPB   R0
R1[R2]      R2所指向的存储器中的字节数据传送到R0R0的高24位清零,同时将R1中的低8位数据传送到R2所指向的存储单元。
SWPB   R0R0[R1]     该指令完成将R1所指向的存储器中的字节数据与R0中的8数据交换。


八、移位指令

1、LSL(或ASL)
LSL
(或ASL)的格式为:
通用寄存器,LSL(或ASL操作数    
LSL
(或ASL)可完成对通用寄存器中的内容进行逻辑(或算术)的左移操作,按操作数所指定的数量向左移位,低位用零来填充。其中,操作数可以是通用寄存器,也可以是立即数(031)。
操作示例
MOV   R0, R1, LSL #2         
R1中的内容左移两位后传送到R0中。
2
LSR
LSR
的格式为:
通用寄存器,LSR操作数    
LSR
可完成对通用寄存器中的内容进行右移的操作,按操作数所指定的数量向右移位,左端用零来填充。其中,操作数可以是通用寄存器,也可以是立即数(031)。
操作示例:
MOV   R0, R1, LSR #2        
R1中的内容右移两位后传送到R0中,左端用零来填充。
3ASR
ASR
的格式为:
通用寄存器,ASR操作数    
ASR
可完成对通用寄存器中的内容进行右移的操作,按操作数所指定的数量向右移位,左端用第31位的值来填充。其中,操作数可以是通用寄存器,也可以是立即数(031)。
操作示例:
MOV    R0, R1, ASR #2       
R1中的内容右移两位后传送到R0中,左端用第31位的值来填充。
4
ROR
ROR
的格式为:
通用寄存器,ROR操作数    
ROR
可完成对通用寄存器中的内容进行循环右移的操作,按操作数所指定的数量向右循环移位,左端用右端移出的位来填充。其中,操作数可以是通用寄存器,也可以是立即数(031)。显然,当进行32位的循环右移操作时,通用寄存器中的值不改变。
操作示例:
MOV    R0, R1, ROR #2      
R1中的内容循环右移两位后传送到R0中。
5RRX
RRX
的格式为:
通用寄存器,RRX操作数    
RRX
可完成对通用寄存器中的内容进行带扩展的循环右移的操作,按操作数所指定的数量向右循环移位,左端用进位标志位C来填充。其中,操作数可以是通用寄存器,也可以是立即数(031)。
操作示例:
MOV   R0, R1, RRX #2        
R1中的内容进行带扩展的循环右移两位后传送到R0中。


九、协处理器指令
1、CDP指令

CDP
指令的格式为:
CDP{
条件}协处理器编码,协处理器操作码1,目的寄存器,源寄存器1,源寄存器2,协处理器操作码2
CDP
指令用于ARM处理器通知ARM协处理器执行特定的操作,若协处理器不能成功完成特定的操作,则产生未定义指令异常。其中协处理器操作码1和协处理器操作码2为协处理器将要执行的操作,目的寄存器和源寄存器均为协处理器的寄存器,指令不涉及ARM处理器的寄存器和存储器。
指令示例:
CDP   P3
2C12C10C34  该指令完成协处理器P3的初始化
2
LDC指令
LDC
指令的格式为:
LDC{
条件}{L}协处理器编码,目的寄存器,[源寄存器]
LDC
指令用于将源寄存器所指向的存储器中的字数据传送到目的寄存器中,若协处理器不能成功完成传送操作,则产生未定义指令异常。其中,{L}选项表示指令为长读取操作,如用于双精度数据的传输。
指令示例:
LDC   P3
C4[R0]       ARM处理器的寄存器R0所指向的存储器中的字数据传送到协处理器P3的寄存器C4中。
3STC指令
STC
指令的格式为:
STC{
条件}{L}协处理器编码,源寄存器,[目的寄存器]
STC
指令用于将源寄存器中的字数据传送到目的寄存器所指向的存储器中,若协处理器不能成功完成传送操作,则产生未定义指令异常。其中,{L}选项表示指令为长读取操作,如用于双精度数据的传输。
指令示例:
STC   P3
C4[R0]    将协处理器P3的寄存器C4中的字数据传送到ARM处理器的寄存器R0所指向的存储器中。
4MCR指令
MCR指令的格式为:
MCR{
条件}协处理器编码,协处理器操作码1,源寄存器,目的寄存器1,目的寄存器2,协处理器操作码2
MCR
指令用于将ARM处理器寄存器中的数据传送到协处理器寄存器中,若协处理器不能成功完成操作,则产生未定义指令异常。其中协处理器操作码1和协处理器操作码2协处理器将要执行的操作,源寄存器为ARM处理器的寄存器,目的寄存器1和目的寄存器2均为协处理器的寄存器。
指令示例:
MCR   P3
3R0C4C56    ARM处理器寄存器R0中的数据传送到协处理器P3的寄存器C4C5中。
5MRC指令
MRC
指令的格式为:
MRC{
条件}协处理器编码,协处理器操作码1,目的寄存器,源寄存器1,源寄存器2,协处理器操作码2
MRC
指令用于将协处理器寄存器中的数据传送到ARM处理器寄存器中,若协处理器不能成功完成操作,则产生未定义指令异常。其中协处理器操作码1和协处理器操作码2为协处理器将要执行的操作,目的寄存器为ARM处理器的寄存器,源寄存器1和源寄存器2均为协处理器的寄存器。
指令示例:
MRC   P3
3R0C4C56    该指令将协处理器P3的寄存器中的数据传送到ARM处理器寄存器中。


十、异常产生指令
1
SWI指令
SWI
指令的格式为:
SWI{
条件} 24位的立即数
SWI
指令用于产生软件中断,以便用户程序能调用操作系统的系统例程。操作系统在SWI的异常处理程序中提供相应的系统服务,指令中24位的立即数指定用户程序调用系统例程的类型,相关参数通过通用寄存器传递,当指令中24位的立即数被忽略时,用户程序调用系统例程的类型由通用寄存器R0的内容决定,同时,参数通过其他通用寄存器传递。
指令示例:
SWI   0x02                
该指令调用操作系统编号位02的系统例程。
2BKPT指令
BKPT指令的格式为:
BKPT   16
位的立即数
BKPT
指令产生软件断点中断,可用于程序的调试

 






  • 1
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值