ARM汇编语言最常用指令
一、ARM汇编语言的特点:
1.所有运算处理都是发生在通用寄存器(一般是R0~R14)之中。所有存储器空间(如C语言变量的本质就是一个存储器空间上的几个BYTE)的值的处理,都是要传送到通用寄存器来完成.因此代码中大量看到LDR,STR指令来传送值.
2.ARM汇编语句中.当前语句很多时候要隐含的使用上一句的执行结果.而且上一句的执行结果,是放在CPSR寄存器里,(比如说进位,为0,为负…)
CMP R0,R1
BNE NoMatch
比如上一BNE隐含的使用的上一句CMP执行结果.NE后缀表示使用Z标志位.两句合起来的意思就是,如果R0,R1的值不相等,就跳转到NoMatch处执行.
注意:PC=R15,CPSR=R16
3.ARM伪指令不是必须的,但是一个完整程序没有伪指令几乎很难写出来.
①比如一个程序至少包含READONLY AREA和ENTRY,否则CPU都无法知道从哪里开始运行。
②ARM属于RISC,指令并不多,但是可以带后缀表示扩展出不同用法,这里与X86汇编完全不同风格。
③如BNE实际上是B指令的变种,本质还是同一类指令.只是多一个对CPSR的Z标志位的判断。
二、ARM处理器的指令集
ARM处理器的指令集可以分为跳转指令、数据处理指令、程序状态寄存器(PSR)处理指令、加载/存储指令、协处理器指令和异常产生指令6大指令。
1、BL指令
格式:BL{条件}目标地址
用法:BL是另一个跳转指令,但跳转之前,会在寄存器R14中保存PC的当前内容,因此,可以通过将R14的内容重新加载到PC中,来返回到跳转指令之后的那个指令处执行。该指令是实现子程序调用的一个基本但常用的手段。
指令示例:
BL Label ;当程序无条件跳转到标号Label处执行时,同时将当前的 PC值保存到R14(LR)中
2、MOV指令(传送)
格式:MOV{条件}{S}目的寄存器,源操作数
MOV指令可完成从另一个寄存器、被移位的寄存器或将一个立即数加载到目的寄存器。其中S选项决定指令的操作是否影响CPSR中条件标志位的值,当没有S 时指令不更新CPSR中条件标志位的值。
指令示例:
MOV R1,R0 ;将寄存器R0的值传送到寄存器R1
MOV PC,R14 ;将寄存器R14的值传送到 PC,常用于子程序返回
MOV R1,R0,LSL#3 ;将寄存器R0的值左移3位后传送到R1
3、CMP指令(比较)
格式:CMP{条件}操作数1,操作数2
CMP指令用于把一个寄存器的内容和另一个寄存器的内容或立即数进行比较,同时更新CPSR中条件标志位的值。该指令进行一次减法运算,但不存储结果,只更改条件标志位。 标志位表示的是操作数1与操作数2的关系(大、小、相等),例如,当操作数1大于操作操作数2,则此后的有GT后缀的指令将可以执行。
指令示例:
CMP R1,R0 ;将寄存器R1的值与寄存器R0的值相减,并根据 结果设置CPSR的标志位
CMP R1,#100 ;将寄存器R1的值与立即数100相减,并根 据结果设置CPSR的标志位
4、ADD指令(相加)
格式:ADD{条件}{S}目的寄存器,操作数1,操作数2
ADD指令用于把两个操作数相加,并将结果存放到目的寄存器中。操作数1应是一个寄存器,操作数2可以是一个寄存器,被移位的寄存器,或一个立即数。
指令示例:
ADD R0,R1,R2 ; R0 = R1 + R2
ADD R0,R1,#256 ; R0 = R1 + 256
ADD R0,R2,R3,LSL#1 ; R0 = R2 + (R3 << 1)
类似算数指令:
①SUB指令(相减):
格式:SUB{条件}{S} 目的寄存器,操作数1,操作数2
示例:SUB R0,R1,#256 ; R0 = R1 – 256
②MUL指令(相乘)
格式:MUL{条件}{S} 目的寄存器,操作数1,操作数2
示例:MUL R0,R1,R2 ;R0 = R1 × R2
③MLA指令(带累加的相乘)
格式:MLA{条件}{S} 目的寄存器,操作数1,操作数2,操作数3
示例:MLA R0,R1,R2,R3 ;R0 = R1 × R2 + R3
5、AND指令(逻辑位与)
格式:AND{条件}{S}目的寄存器,操作数1,操作数2
AND指令用于在两个操作数上进行逻辑与运算,并把结果放置到目的寄存器中。操作数1应是一个寄存器,操作数2可以是一个寄存器,被移位的寄存器,或一个 立即数。该指令常用于屏蔽操作数1的某些位。
指令示例:
AND R0,R0,#3 ;该指令保持R0的0、1位,其余位清零。
类似逻辑运算指令:
①ORR指令(逻辑位或)
格式:ORR{条件}{S} 目的寄存器,操作数1,操作数2
示例:ORR R0,R0,#3 ;该指令设置R0的0、1位,其余位保持不变。
②EOR指令(逻辑位异或)
格式:EOR{条件}{S} 目的寄存器,操作数1,操作数2
示例:EOR R0,R0,#3 ;该指令反转R0的0、1位,其余位保持不变。
6、LDR指令
格式:LDR{条件}目的寄存器,[存储器地址]
LDR指令用于从存储器中将一个32位的字数据传送到目的寄存器中。该指令通常用于从存储器中读取32位的字数据到通用寄存器,然后对数据进行处理。当程序计数器PC作为 目的寄存器时,指令从存储器中读取的字数据被当作目的地址,从而可以实现程序流程的跳转。该指令在程序设计中比较常用,且寻址方式灵活多样,请读者认真掌握。
指令示例:
LDR R0,[R1] ;将存储器地址为R1的字数据读入寄存器R0。
LDR R0,[R1,R2] ;将存储器地址为R1+R2的字数据读入寄存器R0。
LDR R0,[R1,#8] ;将存储器地址为R1+8的字数据读入寄存器R0。
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]!;将存储器地址为R1+R2×4的字数据读入寄存器R0,并将新地址R1+R2×4写入R1。
LDR R0,[R1],R2,LSL#2 ;将存储器地址为R1的字数据读入 寄存器R0,并将新地址R1+R2×4写入R1。
7、STR指令
格式:STR{条件}源寄存器,[存储器地址]
STR指令用于从源寄存器中将一个32位的字数据传送到存储器中。 该指令在程序设计中比较常用,且寻址方式灵活多样,使用方式可参考指令LDR。
指令示例:
STR R0,[R1],#8 ;将R0中的字数据写入以R1为地址的存储器中,并 将新地址R1+8写入R1。
STR R0,[R1,#8] ;将R0中的字数据写入以R1+8为地址的存储器中。
8、LSL(或ASL)
格式:通用寄存器,LSL(或ASL) 操作数
LSL(或ASL)可完成对通用寄存器中的内容进行逻辑(或算术)的左移操作,按操作数所指定的数量向左移位,低位用零来填充。 其中,操作数可以是通用寄存器,也可以是立即数(0~31)。
指令示例:
MOV R0, R1, LSL#2 ;将R1中的内容左移两位后传送到R0 中。
9、LSR
格式:通用寄存器,LSR 操作数
LSR可完成对通用寄存器中的内容进行右移的操作,按操作数所指定的数量向右移位,左端用零来填充。其中,操作数可以 是通用寄存器,也可以是立即数(0~31)。
指令示例:
MOV R0, R1, LSR #2 ;将R1中的内容右移两位后传送到R0 中,左端用零来填充。
10.条件语句
①CMP R0,R1
BEQ 地址
*:如果R0、R1相等,跳到所给地址处执行,否则继续执行下一句。
②CMP R0,R1
BNE 地址
*:不相等
③CMP R0,R1
BLE 地址
*:小于等于
④CMP R0,R1
BGT 地址
*:大于
11.循环语句:
CMP R0,R1
B条件 地址
*:所给地址在当前地址前面,即可循环执行所给地址到当前地址的语句。