arm常用指令

1:400M主频,64M SDRAM 32bit数据总线。

2:arm寻址方式:寻址方式就是寻找操作数或操作数地址的方式

 目前ARM处理器支持9种寻址方式,分别是立即数寻址寄存器寻址寄存器偏移寻址寄存器间接寻址基址变址寻址多寄存器寻址相对寻址堆栈寻址块拷贝寻址

3:立即数寻址:操作数本身就在指令中给出,

ADD R0,R0,#1   ;R0←R0+1
ADD R0,R0,#0x3f   ;R0←R0+0x3f

主要数字前的#号  

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←[R1+R2]
5:多寄存器寻址:

采用多寄存器寻址方式,一条指令可以完成多个寄存器值的传送。这寻址方式可以用一条指令完成传送最多16个通用寄存器的值。以下指令:

LDMIA R0,{R1,R2,R3,R4} ;R1←[R0]

            ;R2←[R0+4]
            ;R3←[R0+8]  
            ;R4←[R0+12]  
该指令的后缀IA表示在每次执行完加载/存储操作后,R0按字长度增加,因此,指令可将连续存储单元的值传送到R1~R4。
6:基址变址寻址方式

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

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

递增堆栈:向高地址方向生长

递减堆栈:向低地址方向生长

满堆栈:堆栈指针指向最后压入堆栈的有效数据项

空堆栈:堆栈指针指向下一个要放入数据的空位置

8:arm指令集:

实现跳转的两种方式:

1:使用专门的跳转指令。
2:直接向程序计数器PC写入跳转地址值

在跳转之前结合使用
MOV   LR,PC
等类似指令,可以保存将来的返回地址值,从而实现在4GB连续的线性地址空间的子程序调用。
9:跳转指令

4条指令:
B        跳转指令
BL      带返回的跳转指令
BLX    带返回和状态切换的跳转指令
BX     带状态切换的跳转指令
10:使用方法:

(1:B 指令的格式为:
    B{条件}  目标地址  B lable  程序无条件跳转到标号lable处。
(2:指令条件


标志位 
指令条件              含义
EQ   Z置位        相等
NE   Z清零       不相等
CS   C置位       无符号数大于或等于
CC   C清零       无符号数小于
MI    N置位       负数
PL    N清零       正 数或零
VS    V置位        溢出
VC   V清零          未溢出
HI     C置位Z清零     无符号数大于
LS      C清零Z置位      无符号数小于或等于
GE    N等于V       带符号数大于或等于
LT   N不等于V     带符号数小于
GT   Z清零且(N等于V)    带符号数大于
LE Z置位或(N不等于V)   带符号数小于或等于
AL   忽略       无条件执行

12:BL

  B{条件}  目标地址

是另一个跳转指令,但跳转之前,会在寄存器R14(LR(指令)寄存器)中保存PC当前值
13:BLX {条件}  目标位值    相对于BL会增加一个转换到thumb状态

14:mvn指令:

      MVN {条件} {S} 目的寄存器,源操作数
#####与MOV指令不同之处是在传送之前按位被取反了,即把一个被取反的值传送到目的寄存器中。
15:比较指令:实际是一个减法。

CMP{条件} 操作数1,操作数2。。。同时更新CPSR中条件标志位的值

16:与运算

TST{条件} 操作数1,操作数2

TST指令用于把一个寄存器的内容和另一个寄存器的内容或立即数进行按位的与运算,并根据运算结果更新CPSR中条件标志位的值。操作数1是要测试的数据,而操作数2是一个位掩码,根据测试结果设置相应标志位。当位与结果为0时,EQ位被设置。
指令示例:
TSTR1,#%1
;用于测试在寄存器R1中是否
设置了最低位(%表示二进制数)。
 

17: 减法指令

SUB R0,R1,R2 ; R0 = R1 - R2
 SUB R0,R1,#256 ; R0 = R1 - 256
 SUB R0,R2,R3,LSL#1 ; R0 = R2 - (R3 << 1)
18:与运算:

AND{条件}{S} 目的寄存器,操作数1(必须是寄存器),操作数2

19:或运算:

ORR{条件}{S} 目的寄存器,操作数1(寄存器),操作数2

20:掩码运算:

BIC{cond}{S} Rd,Rn,operand2
BIC指令用于清除Rn 中的某些位,并把结果存放在Rd中,操作数operand2 为32位的掩码,如果掩码中设置了某一位为1,则清除这一位。
例:BIC R0,R0,#%1011 ;将R0的0,1,3位清零,其余位不变。 其中的%是说明1011为二进制。

21:乘法指令:

MUL R0,R1,R2 ;R0 = R1 × R2
MULS R0,R1,R2 ;R0 = R1 × R2,同时
设置CPSR中的相关条件标志位

22:MULL指令家族(详见百度)

   SMULL指令:

   SMULL 指令完成将操作数1与操作数2的乘法运算,并把结果的低32位放置到目的寄存器Low中,结果的高32位放置到目的寄存器High中,同时可以根据运算结果设置CPSR中相应的条件标志位

指令格式:SMULL{条件}{S} 目的寄存器Low,目的寄存器低High,操作数1,操作数2

SMULL R0,R1,R2,R3 ;R0 = (R2 × R3)的低32 位;R1 = (R2 × R3)的高32 位

23:MRS{条件} 通用寄存器,程序状态寄存器(CPSR或SPSR)
MRS指令用于将程序状态寄存器的内容传送到通用寄存器中。

当需要改变程序状态寄存器的内容时,可用MRS将程序状态寄存器的内容读入通用寄存器,修改后再写回程序状态寄存器。

当在异常处理或进程切换时,需要保存程序状态寄存器的值,可先用该指令读出程序状态寄存器的值,然后保存。
MRS R0,CPSR ;传送CPSR的内容到R0
MRS R0,SPSR ;传送SPSR的内容到R0
24:MSR{条件} 程序状态寄存器(CPSR或SPSR)_<域>,操作数MSR指令用于将操作数的内容传送到程序状态寄存器的特定域中。其中,操作数可以为通用寄存器或立即数。<域>用于设置程序状态寄存器中需要操作的位,32位的程序状态寄存器可分为4个域:
位[31:24]为条件标志位域,用f表示;位[23:16]为状态位域,用s表示;
位[15:8]为扩展位域,用x表示;
位[7:0]为控制位域,用c表示;
该指令通常用于恢复或改变程序状态寄存器的内容,在使用时,一般要在MSR指令中指明将要操作的域。
指令示例: 
 MSR CPSR,R0 
;传送R0的内容到CPSR

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

25:加载指令用于将存储器中的数据传送到寄存器,存储指令则完成相反的操作。

26:LDR指令LDR指令用于从存储器中将一个32位的字数据传送到目的寄存器中
v LDR R0,[R1]
将存储器地址为R1的字数据读入寄存器R0。
v LDR R0,[R1,R2]
将存储器地址为R1+R2的字数据读入寄存器R0。
v LDR R0,[R1,#8]
将存储器地址为R1+8的字数据读入寄存器R0。
v LDR R0,[R1,R2] !
将存储器地址为R1+R2的字数据读入寄存器R0,并将新地址R1+R2写入R1。

27 :LDRB格式

^LDR{条件}B 目的寄存器,<存储器地址>
LDRB指令用于从存储器中将一个8位的字节数据传送到目的寄存器中,同时将寄存器的高24位清零
同时将寄存器的高24位清零
例程参考LDR。

28 :LDRH

^LDR{条件}H 目的寄存器,<存储器地址>
LDRB指令用于从存储器中将一个16位的字节数据传送到目的寄存器中,同时将寄存器的高16位清零
同时将寄存器的高24位清零
例程参考LDR。


29:STR指令的格式为:
STR{条件} 源寄存器,<存储器地址>STR指令用于从源寄存器中将一个32位的字数据传送到存
储器中。
指令示例:
v STRR0,[R1],#8   ;将R0中的字数据写入以R1为地址的存储器中,并将新地址R1+8写入R1。
v STRR0,[R1,#8]   ;将R0中的字数据写入以R1+8为地址的存储器中。

30 :批量数据传递:

LDM指令的格式为:
LDM {条件}{类型} 基址寄存器{!},寄存器列表{∧}     (基址寄存器不允许为R15,寄存器列表可以为R0~R15的任意组合。)
LDM(或STM)指令用于从由基址寄存器所指示的一片连续存储器到寄存器列表所指示的多个寄存器之间传送数据,该指令的常见用途是将多个寄存器的内容入栈或出栈 
{类型}为以下几种情况:
v IA 每次传送后地址加1;
v IB 每次传送前地址加1;
v DA 每次传送后地址减1;
v DB 每次传送前地址减1;
v FD 满递减堆栈;
v ED 空递减堆栈;
v FA 满递增堆栈;
v EA 空递增堆栈;
{!}为可选后缀,若选用该后缀,则当数据传送完之后,将最后的地址写入基址寄存器,否则基址寄存器的内容不改变。
{∧}为可选后缀,当指令为LDM且寄存器列表中包含R15,选用该后缀时表示:除了正常的数据传送之外,还将SPSR复制到CPSR。
指令示例:
v STMFD R13!,{R0,R4-R12,LR}  ;将寄存器列表中的寄存器(R0,R4到R12,LR)存入堆栈。
v LDMFD R13!,{R0,R4-R12,PC}  ;将堆栈内容恢复到寄存器(R0,R4到R12,LR)。

31:SWP指令的格式为:

SWP{条件} 目的寄存器,源寄存器1,[源寄存器2]
SWP指令用于将源寄存器2所指向的存储器中的字数据传送到目的寄存器中,同时将源寄存器1中的字数据传送到源寄存器2所指向的存储器中。显然,当源寄存器1和目的寄存器为同一个寄存器时,指令交换该寄存器和存储器的内容

指令示例:
v SWP R0 , R1 , [R2]  ;将R2所指向的存储器中的字数据传送到R0,同时将R1中的字数据传送到R2所指向的存储单元。
v SWP R0 , R0 , [R1]  ;该指令完成将R1所指向的存储器中的字数据与R0中的字数据交换。

32:移位指令

v LSL    逻辑左移
v ASL   算术左移
v LSR   逻辑右移
v ASR   算术右移
v ROR   循环右移

一般格式:LSL操作的格式为: 

通用寄存器,LSL操作数(既可以为寄存器,也可以是立即数(前面别忘加#号))

示例:MOV R0, R1, LSL#2  ;将R1中的内容左移两位后传送到R0中(其他也一样

33:中断指令

vSWI      软件中断指令
vBKPT   断点中断指令 

SWI {条件}  24位的立即数 (立即数指定用户程序调用的API类型)
SWI指令用于产生软件中断,以便用户程序能调用操作系统的系统API。
指令示例:
  SWI  0x02

34: 伪指令:
在源程序中的作用是为完成汇编程序作各种准备工作的,这些伪指令仅在汇编过程中起作用,一旦汇编结束,伪指令的使命就完成。

35:符号定义伪指令

v 定义全局变量的GBLA、GBLL和GBLS
v 定义局部变量的LCLA、LCLL和LCLS
v 对变量赋值的SETA、SETL、SETS
v 为通用寄存器列表定义名称的RLIST
36:使用示例:
v

GBLA  Test1
定义一个全局的数字变量,变量名为Test1
v

Test1 SETA  0xaa
将该变量赋值为0xaa
v
GBLL    Test2
定义一个全局的逻辑变量,变量名为Test2
v
Test2  SETL  {TRUE}
将该变量赋值为真
v
GBLS  Test3
定义一个全局的字符串变量,变量名为Test3
v
Test3  SETS   “Testing”
将该变量赋值为“Testing”
37:名称 RLIST{寄存器列表}
RLIST伪指令用于对一个通用寄存器列表定义名称,使用该伪指令定义的列表名称可在ARM指令LDM/STM中使用。在LDM/STM指令中,列表中的寄存器访问次序为根据寄存器的编号由低到高,而与列表中的寄存器排列次序无关。

38:
标号 DCB 表达式
DCB伪指令用于分配一片连续的字节存储单元并用伪指令中指定的表达式初始化。其中,表达式可以为0~255的数字或字符串。

DCB也可用“=”代替。

Str DCB “This is a test!”   ;分配一片连续的字节存储单元并初始化。
39:

标号  SPACE  表达式
SPACE伪指令用于分配一片连续的存储区域并初始化为0。 其中,表达式为要分配的字节数SPACE也可用“%”代替。

DataSpace  SPACE  100  ;分配连续100字节的存储单元并初始化为0。

40:当基址寄存器选项不存在时,表达式的值即为内存表的首地址,当该选项存在时,内存表的首地址为表达式的值与基址寄存器的和。
MAP 0x100,R0  ;定义结构化内存表首地址的值为0x100+R0 
41:MAP 与 FIELD联合使用的例子

MAP   0x100       ;定义结构化内存表首地址的值为0x100。
A   FIELD   16     ;定义A的长度为16字节,位置为0x100
B   FIELD   32     ;定义B的长度为32字节,位置为0x110
S   FIELD   256   ;定义S的长度为256字节,位置为0x130
42:

GBLL  Test   ;声明一个全局的逻辑变量,变量名为Test
......
IF
Test = TRUE  
//注意等号 指令序列1
ELSE     指令序列2
ENDIF
43 :while

WHILE 逻辑表达式
指令序列
WEND

44:AREA 段名 属性1,属性2,......
AREA伪指令用于定义一个代码段或数据段。其中,段名若以数字开头,则该段名需用“|”括起来,如|1_test|。属性字段表示该代码段(或数据段)的相关属性,多个属性用逗号分隔。
常用的属性如下:
v CODE属性  :用于定义代码段,默认为READONLY。
v DATA属性  :用于定义数据段,默认为READWRITE。

45 :利用code16 与 code32 来进行Thumb和arm间的混合编程并进行切换

46:
ENTRY 
ENTRY伪指令用于指定汇编程序的入口点.在一个完整的汇编程序中至少要有一个ENTRY(也可以有多个,当有多个ENTRY时,程序的真正入口点由链接器指定),但在一个源文件里最多只能有一个ENTRY(可以没有). 
使用示例: 
AREA Init,CODE,READONLY 
ENTRY ;指定应用程序的入口点 ……

47:EQU 

语法格式: 

名称 EQU 表达式{,类型} 

EQU伪指令用于为程序中的常量、标号等定义一个等效的字符名称,类似于C语言中的#define.其中EQU可用“*”代替. 

名称为EQU伪指令定义的字符名称,当表达式为32位的常量时,可以指定表达式的数据类型,可以有以下三种类型: 

CODE16、CODE32和DATA 

使用示例: 

Test EQU 50 ;定义标号Test的值为50 

Addr EQU 0x55,CODE32 ;定义Addr的值为0x55,且该处为32位的ARM指令.

48: EXPORT(或GLOBAL) 

语法格式: 

EXPORT   标号  {[WEAK]} 

EXPORT伪指令用于在程序中声明一个全局的标号,该标号可在其他的文件中引用.EXPORT可用GLOBAL代替.标号在程序中区分大小写,[WEAK]选项声明其他的同名标号优先于该标号被引用. 

使用示例: 

AREA Init,CODE,READONLY 

EXPORT Stest ;声明一个可全局引用的标号Stest 

…… 

END

49:

对于第二操作数是立即数的情况 
ARM的指令系统的立即数只允许立即数是八位位图数,具体的意思好像是必须是八位二进制数的位移数,因此对于任意的32位二进制数不能直接使用
于是就出现了伪指令LDR R0,=OP2,
这样可以使用任意32位的二进制数

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值