ARM经典汇编指令集.docx
- 文档编号:4689085
- 上传时间:2022-12-07
- 格式:DOCX
- 页数:13
- 大小:365.14KB
ARM经典汇编指令集.docx
《ARM经典汇编指令集.docx》由会员分享,可在线阅读,更多相关《ARM经典汇编指令集.docx(13页珍藏版)》请在冰豆网上搜索。
ARM经典汇编指令集
寄存器:
在任何时候,通用寄存器R14-R0,程序计数器R15(PC),一个状态寄存器都是可以访问的。
在ARM工作状态下,任意时刻可以访问16个通用寄存器和一到二个状态寄存器。
在非用户模式下,则可访问到特定模式分组寄存器。
Thumb状态下的寄存器集是ARM状态下寄存器集的一个子集,程序可以直接访问8个通用寄存器(R7-R0),程序计数器PC,堆栈指针SP,连接寄存器LR和CPSR。
在Thumb状态下和ARM状态下的R0-R7是相同的。
在Thumb状态下和ARM状态下的CPSR和SPSR是相同的。
在Thumb状态下的SP对应ARM状态下的R13
在Thumb状态下的LR对应ARM状态下的R14
通用寄存器:
>不分组寄存器R0-R7
>分组寄存器R8-R14
>程序计数器R15
不分组通用寄存器:
R0-R7.,这意味者所有处理模式下,访问的都是同一个物理寄存器。
未分组寄存器没有被系统用于特别用途,任何可采用通用寄存器的应用场合都可以使用未分组寄存器。
分组模式寄存器:
1)FIQ模式分组寄存器R8-R12:
2)FIQ以外的分组寄存器R8-R12
3)寄存器R13通常用做堆栈指针SP
4)寄存器R4用作子程序链接寄存器LR,指向函数的返回地址。
程序计数器:
R15被用作程序计数器,也称为PC,其值等于当前正在执行的指令的地址+8。
因为在取地址和执行之间多了一个译码阶段。
状态寄存器:
ARM所有工作模式下都可以访问程序状态寄存器CPSR。
CPSR包含条件码标志、中断禁止位、当前处理器模式以及其它状态和控制信息。
CPSR在每种异常模式下都有一个对应的物理寄存器------程序状态保存寄存器SPSR。
当异常出现时,SPSR用于保存CPSR的值,以便异常返回后恢复异常发生时的工作状态。
多寄存器寻址:
采用多寄存器寻址方式,一条指令可以完成多个寄存器值的传送。
这寻址方式可以用一条指令完成传送最多16个通用寄存器的值。
例如:
LDMIAR0,{R1,R2,R3,R4};R1[R0]
;R2[R0+4]
;R3[R0+8]
;R4[R0+12]
该指令的后缀IA表示每次执行完加载、存储操作后,R0按字节长度增加,因此,指令可将连续存储单元的值送到R1-R4。
堆栈寻址:
堆栈是一种数据结构,按先进后出的方式工作,使用一个称作堆栈指针的专用寄存器至少当前的操作位置,堆栈指针总是指向栈顶。
递增堆栈:
向高地址方向生长。
递减堆栈:
向低地址方向生长
满堆栈:
堆栈指针指向最后压入堆栈的有效数据项。
空堆栈:
堆栈指针指向下一个要放入数据的空位置。
跳转指令用于实现程序流程的跳转,在ARM程序中有两种方法实现程序流程的跳转:
>使用专门的跳转指令
>直接向寄存器计数器PC写入跳转地址值,通过向程序计数器PC写入跳转地址值,可以实现在4G的地址空间中任意跳转,在跳转之前结合使用:
MOVLR,PC
等类似的指令,可以保存将来的返回地址值,从而实现在4G连续的线性地址空间的子程序调用。
ARM指令集中的跳转指令可以完全从当前指令向前或者向后的32MB的地址空间跳转,包括以下4条指令:
>B跳转指令
>BL带返回的跳转指令
>BLX带返回和状态切换的跳转指令
>BX带状态切换的跳转指令
B指令的格式为:
B{条件}目的地址//条件可有可无
B指令是最简单的跳转指令,一旦遇到一个B指令,ARM处理器将立即跳转到给定的目的地址,从那里开始继续执行。
>BLabel程序无条件跳转到标号Label处执行。
例子:
CMPR1,#0
BEQLabel
当寄存器中的Z条件码置位时,程序跳转到标号Label处执行。
BL指令的格式为:
BL{条件}目的地址
BL是另一个跳转指令,但跳转之前,会在寄存器R14中保留PC当前值,因此,可以通过将R14的内容重新加载到PC中,来返回到跳转指令之后的那个指令处执行。
该指令是实现子程序调用的一个基本但常用的手段。
>BLLabel;当程序无条件跳转到标号Label处执行时,同时当前的PC值保存到R14中
BLX指令的格式为:
>BLX目的地址
BLX指令从ARM指令集跳转到指令中所指定的地址,并将处理器工作状态有ARM状态切换到Thumb状态,该指令同时将PC的当前内容保存到寄存器R14中。
因此,当子程序使用Thumb指令集,而调用者使用ARM指令集时,可以通过BLX指令实现子程序的调用和处理器工作状态的切换。
同时,子程序的返回可以通过将寄存器R14值复制到PC中来完成。
BX指令的格式为:
>BX{条件}目的地址
BX指令跳转到指令中所指定的目标地址,目标地址处的指令即可以是ARM指令,也可以是Thumb指令。
数据指令处理:
数据指令处理可分为数据传送指令,算术逻辑运算指令和比较指令等。
数据传送指令用于在寄存器和存储器之间进行数据的双向传输。
算术逻辑运算指令完成常用的算术与逻辑的运算,该类指令不但将运算结果保存在目的寄存器中,同时更新CPSR中的相应条件位标志。
MOV指令:
格式:
MOV{条件}{S}目的寄存器,源操作数
MOV指令完成从另一个寄存器、被移位的寄存器或将一个立即数加载到目的寄存器。
其中S选项决定指令的操作是否影响CPSR中条件标志位的值,当没有S时,指令不更新CPSR中条件标志位的值。
例子:
MOVR1,R0;将寄存器R0的值传送到寄存器R1
MOVPC,R14;将寄存器R14的值传送到PC,常用于子程序的返回。
MOVR1,R0,LSL#3;将寄存器R0的值左移3位后传送到R1。
MVN指令:
格式:
MVN{条件}{S}目的寄存器,源操作数
MVN指令可完成从另一个寄存器、被移位的寄存器、或将一个立即数加载到目的寄存器。
与MOV指令不同的地方在于传送之前按位取反了,即把一个被取反的值传送到目的寄存器中。
其中S决定指令的操作是否影响CPSR中条件标志位的值。
当没有S时指令不更新CPSR中条件标志位的值。
例子:
MVNR0,#0xFF;0xFFFFFF00->R0
CMP指令:
格式:
CMP{条件}操作数1,操作数2
CMP指令用于把一个寄存器的内容和另一个寄存器的内容或立即数进行比较,同时更新CPSR中的条件标志位。
该指令进行一次减法运算,但不存储结果,只更新条件标志位。
标志位表示的是操作数1与操作数2的关系(大小,相等)。
例如:
当操作数1大于操作数2,则此后的有GT后缀的指令将可以执行。
例子:
CMPR1,R0;将寄存器R1的值与寄存器R0的值相减,并根据结果设置CPSR的标志位。
CMPR1,#100;将寄存器R1的值与立即数100相减,并根据结果设置CPSR的标志位。
TST指令:
格式:
TST{条件}操作数1,操作数2
TST指令用于把一个寄存器的内容和另一个寄存器的内容或立即数进行按位与运算。
并根据运算结果更新CPSR中条件标志位的值。
操作数1是要测试的数据,而操作数2是一个位掩码,根据测试结果设置相应标志位。
当位与结果为0时,EQ位被设置。
例子:
TSTR1,#%1;用于测试在寄存器R1中是否设置了最低位。
(%表示二进制)
ADD指令:
格式:
ADD{条件}{S}目的寄存器,操作数1,操作数2
ADD指令用于把两个操作数相加,并将结果存放到目的寄存器中。
操作数1应是一个寄存器,操作数2可以是一个寄存器、被移位的寄存器或者一个立即数。
例子:
ADDR0,R1,R2;R0=R1+R2
ADDR0,R1,#256;R0=R1+256
ADDR0,R2,R3,LSL#1;R0=R2+(R3<<1)
SUB指令:
格式:
SUB{条件}{S}目的寄存器,操作数1,操作数2
SUB指令用于把操作数1减去操作数2,并将结果存放在目的寄存器中。
操作数1应是一个寄存器,操作数2可以是一个寄存器、被移位寄存器、立即数。
例子:
SUBR0,R1,R2;R0=R1-R2
SUBR0,R1,#256;R0=R1-256
SUBR0,R2,R3,,LSL#1;R0=R2-(R3<<1)
AND指令:
格式:
AND{条件}{S}目的寄存器,操作数1,操作数2
AND指令用于在两个操作数上进行逻辑与运算,并把结果放置到目的寄存器中,操作数1对应一个寄存器,操作数2可以是一个寄存器、被移位寄存器、或一个立即寄存器。
该指令常用于屏蔽操作数1的某些位。
例子:
ANDR0,R0,#3;该指令保持R0的0,1位,其余位清零。
ORR指令:
格式:
ORR{条件}{S}目的寄存器,操作数1,操作数2
ORR指令用于在两个操作数上进行逻辑或运算,并把结果放置在目的寄存器。
操作数1应是一个寄存器,操作数2可以是一个寄存器、被移位寄存器、立即数。
该指令常用于设置操作数1的某些位。
例子:
ORRR0,R0,#3;该指令设置R0的0,1位,其余保持不变。
BIC指令:
格式:
BIC{cond}{S}Rd,Rn,operand2
BIC指令用于清除Rn中的某些位,并把结果存放在Rd中,操作数2为32位的掩码,如果掩码中设置了某一位为1,则清除这一位。
例子:
BICR0,R0,#%1011;将R0的0,1,3位清零,其余不变。
MUL指令:
格式:
MUL{条件}{S}目的寄存器,操作数1,操作数2
MUL指令完成将操作数1与操作数2的乘法运算,并把结果放置在目的寄存器中,同时可以根据运算结果设置CPSR中相应的条件标志位。
其中,操作数1和操作数2均为32位的有符号或无符号数。
例子:
MULR0,R1,R2;R0=R1*R2
MULR0,R1,R2;R0=R1*R2,同时设置CPSR中的相关条件标志位。
程序状态寄存器访问指令:
ARM微处理器支持程序状态寄存器访问指令,用于在程序状态寄存器和通用寄存器之间传送数据。
MRS指令:
格式:
MRS{条件}通用寄存器,程序状态寄存器(CPSR、SPSR)
MRS指令用于将程序状态寄存器的内容送到通用寄存器。
该指令一般用于以下几种情况:
>当需要改变程序状态寄存器的内容时,可用MRS将程序状态寄存器的内容读入通用寄存器,修改后在写回程序状态寄存器。
>当在异常处理或进程切换时,需要保存程序状态寄存器的值,可先用该指令读出程序状态寄存器的值,然后保存。
例子:
MRSR0,CPSR;传送CPSR的内容到R0
MRSR0,SPSR;传送SPSR的内容到R0
MSR指令:
格式:
MSR{条件}程序状态寄存器(SPSR、CPSR)_<域>,操作数
MSR指令用于将操作数的内容传送到程序状态寄存器的特定域中,其中,操作数可以为通用寄存器或立即数。
<域>用于设置程序状态寄存器中需要操作的位,32位的程序状态寄存器可分为4个域:
>位[31:
24]为条件标志位域,用f表示
>位[23:
16]为状态位域,用s表示
>位[15:
8]为扩展位域,用x表示
>位[7:
0]为控制位域,用c表示
该指令通常用于恢复或改变程序状态寄存器的内容,在使用时,一般要在MSR指令中指明要操作的域。
例子:
MSRCPSR,R0;传送R0的内容到CPSR
MSRSPSR,R0;传送R0的内容到SPSR
MSRCPSR_c,R0;传送R0的内容到SPSR,但仅仅修改CPSR中的控制域
加载/存储指令:
ARM微处理器支持加载/存储器指令用于寄存器和存储器之间传送数据,加载指令用于将存储器中的数据传送到寄存器,存储指令则完成相反的操作。
LDR指令:
格式:
LDR{条件}目的寄存器,<存储器地址>
LDR指令用于从存储器中将一个32位的字数据传送到目的寄存器中。
该指令通常用于从存储器中读取32位的字数据到通用寄存器,然后对数据进行处理。
例子:
LDRR0,[R1];将存储器地址为R1的字数据读入寄存器R0
LDRR0,[R1,R2];将存储器地址为R1+R2的字数据读入寄存器R0
LDRR0,[R1,#8];将存储器地址为R1+8的数据读入寄存器R0
LDRR0,[R1,R2]!
;将存储器地址为R1+R2的字数据读入寄存器R0,并将新的地址R1+R2写入R1
LDRR0,[R1,#8]!
;将存储器地址为R1+8的字数据读入寄存器R0,并将新地址R1+8写入R1
LDRR0,[R1],R2;将存储器地址为R1的字数据读入寄存器R0,并将新地址R1+R2写入R1
LDRR0,[R1,R2,LSL#2]!
;将存储器地址为R1+R2*4的字数据读入寄存器R0,并将新地址R1+R2*4写入R1
LDRR0,[R1],R2,LSL#2;将存储器地址为R1的字数据读入寄存器R0.,并将新地址R1+R2*4写入R1
LDRB指令:
格式:
LDR{条件}B目的寄存器,<存储器地址>
LDRB指令用于从存储器中将一个8位的字节数据传输到目的寄存器中,同时将寄存器的高24位清零。
该指令通常用于从存储器中读取8位字节数据到通用寄存器,然后对数据进行处理。
例子:
LDRBR0,[R1];将存储器地址为R1的字节数据读入寄存器R0,并将R0的高24位清零。
LDRBR0,[R1,#8];将存储器地址为R1+8的字节数据读入寄存器R0中,并将R0的高24位清零。
LDRH指令:
格式:
LDR{条件}H目的寄存器,<存储器地址>
LDRH指令用于从存储器中将一个16位的半字数据送到目的寄存器中,同时将寄存器的高16位清零,该指令通常用于从存储器中读取16位的半字数据到通用寄存器,然后对数据进行处理。
例子:
LDRHR0,[R1];将存储器地址为R1的半字数据读入寄存器R0,并将R0的高16位清零。
LDRHR0,[R1,R2];将存储器地址为R1+R2的半字数据读入寄存器R0,并将R0的高16位清零。
STR指令:
格式:
STR{条件}源寄存器,<存储器地址>
STR指令用于从源寄存器中将一个32的字数据传输到存储器中。
例子:
STRR0,[R1],#8;将R0中的字数据写入以R1为地址的存储器中,并将新地址R1+8写入R1
STRR0,[R1,#8];将R0的字数据写入以R1+8为地址的存储器中。
批量加载/存储指令:
ARM微处理器所支持的批量数据加载/存储器指令可以一次在一片连续的存储器单元和多个寄存器之间传送数据,批量加载指令用于将一片连续的存储器中的数据传送到多个寄存器中,批量数据存储指令则完成相反操作。
LDM指令:
格式:
LDM{条件}{类型}基址寄存器{!
},寄存器列表{^}
LDM或STM指令用于从由寄存器所指示的一片连续的存储器到寄存器列表所指示的多个寄存器之间传送数据。
该指令常见的用途是将多个寄存器的内容入栈或者出栈。
其中,{类型}为以下几种情况:
>IA每次传送后地址加1
>IB每次传送前地址加1
>DA每次传送前地址减1
>DB每次传送前地址减1
>FD满递减堆栈
>ED空递减堆栈
>FA满递增堆栈
>EA空递增堆栈
{!
}为可选后缀,若选用该后缀,则当数据传送完毕后,将最后的地址写入基址寄存器,否则基址寄存器的内容不变。
基址寄存器不允许为R15,寄存器列表可以为R0-R15的任意组合。
{^}为可选后缀,当指令为LDM且寄存器列表中包含R15,选用该后缀表示:
除了正常的数据传送外,还将SPSR复制到CPSR。
例子:
STMFDR13!
,{R0,R4-R12,LR};将寄存器列表中寄存器(R0,R4到R12,LR)存入堆栈。
LDMFDR13!
,{R0,R4-R12,PC};将堆栈内容恢复到寄存器(R0,R4-R12,LR)
数据交换指令:
ARM微处理器所支持数据指令能在存储器和寄存器之间交换数据。
数据交换指令有如下两条:
>SWP字数据交换指令
>SWPB字节数据交换指令
SWP指令:
格式:
SWP{指令}目的寄存器,源寄存器1,[源寄存器2]
SWP指令用于将源寄存器2所指向的存储器中的字数据传送到目的寄存器中,同时将源寄存器1中的字数据传送到源寄存器2所指向的存储器中。
显然,当源寄存器1和目的寄存器为同一个寄存器时,指令交换该寄存器和存储器的内容。
例子:
SWPR0,R1,[R2];将R2所指向的存储器中字数据传送到R0,同时将R1的字数据传送到R2所指向的存储单元。
SWPR0,R0,[R1];该指令完成将R1所指向的存储器中的字数据与R0中的字数据交换。
移位指令:
ARM微处理器支持数据的移位操作。
移位操作在ARM指令集中不作为单独的指令使用,它只能作为指令格式中一个字段。
在汇编语言中表示指令中的选项。
共有6中类型,ASL和LSL是等价的,可以自由交换:
>LSL逻辑左移
>ASL算术左移
>LSR逻辑右移
>ASR算术右移
>ROR循环右移
异常产生指令:
ARM微处理器所支持的异常指令有如下两条:
>SWI软件中断指令
>BKPT断点中断指令
SWI指令:
格式:
SWI{条件}24位的立即数
SWI指令用于产生软件中断,以便用户程序能调用操作系统API。
操作系统在SWI的异常处理程序找那个提供相应的系统服务,指令中24位的立即数指定用户程序调用的API类型。
例子:
SWI0x02;该指令调用系统编号为02的系统例程
伪指令:
伪指令没有操作码,是一些特殊指令助记符。
伪指令在源程序中的作用是为完成汇编程序做各种准备工作的,这些伪指令仅在汇编过程中起作用,一旦汇编结束,伪指令的使命就完成。
在ARM的汇编程序中,有以下几种:
符号定义伪指令、数据定义伪指令、汇编控制伪指令、宏指令以及其他伪指令。
AREA指令:
格式:
AREA段名属性1,属性2,……..
AREA伪指令用于定义一个代码段或数据段。
其他若以数字开头,则该段名需”|”括起来,如|1_test|,属性段表示该代码段或数据段的相关属性,多个属性用逗号分隔。
>CODE属性:
用于定义代码段,默认为READONLY
>DATA属性:
用于定义数据段,默认为READONLY
>READONLY属性:
指定本段为只读,代码段默认为READONLY
>READWRITE:
熟悉:
指定本段为可读可写,数据段的默认熟悉为READONLY
>ALIGN熟悉:
使用方式:
ALIGN{表达式{,偏移量}}
ALIGN伪指令可通过添加填充字节的方式,使当前位置满足一定的对齐方式,其中,表达式的值用于指定对齐方式,可能取值为2的幂,如1,2,4,8,16等。
若未指定表达式,则将当前位置对齐到下一个字的位置。
偏移量也为一个数字表达式,若使用该字段,则当前位置的对齐方式为:
2的表达式次幂+偏移量。
默认情况下,ELF(可执行连接文件)的代码段和数据段是按照字对齐的。
一个汇编语言程序至少要包含一个段,当程序太长时,也可以将程序分为多个代码段和数据段。
例子:
AREAInit,CODE,READONLY,ALIEN=3;定义一个代码段,段名为Init,属性为只读,8字节对齐。
ENTRY指令:
ENTRY伪指令用于指定汇编程序的入口点,在一个完整的汇编程序中至少有一个ENTRY(也可以有多个,当有多个ENTRY时,程序的真正入口点由连接器指定),但在一个源文件里最多只能有一个ENTRY(可以没有)。
EXPORT指令:
格式:
EXPORT标号
EXPORT伪指令用于在程序中声明一个全局的标号,该标号可在其他的文件中引用。
EXPORT可用GLOBAL代替。
标号在程序中区分大小写。
例子:
EXPORTStest;声明一个可全局引用的标号Stest
IMPORT伪指令:
格式:
IMPORT标号
IMPORT伪指令用于通知编译器要使用的标号在其他的源文件中定义,但要在当前源文件中引用。
标号在程序中区分大小写。
例子:
IMPORTMain;通知当前编译器要引用编号Main,但Main在其他源文件中定义。
END指令:
END伪指令用于通知编译器已经到了源程序的结尾。
例子:
…….
END;指定应用程序结束
- 配套讲稿:
如PPT文件的首页显示word图标,表示该PPT已包含配套word讲稿。双击word图标可打开word文档。
- 特殊限制:
部分文档作品中含有的国旗、国徽等图片,仅作为作品整体效果示例展示,禁止商用。设计者仅对作品中独创性部分享有著作权。
- 关 键 词:
- ARM 经典 汇编 指令