ARM汇编

数据操作(ALU操作)

1、数学操作

OpcodeOperandsDeacriptionFunction
ADCRd,Rn,Op2带进位的加Rd=Rn+Op2+c
ADDRd,Rn,Op2Rd=Rn+Op2
MOVRd,Op2数据传送Rd=Op2
MVPRd,Op2数据取反传送Rd=~Op2
RSBRd,Rn,Op2翻转减Rd=Op2-Rn
RSCRd,Rn,Op2反转减Rd=Op2-Rn-!C
SBCRd,Rn,Op2带进位的减法Rd=Rn-Op2-!C
SUBRd,Rn,Op2Rd=Rn-Op2
MULRd,RmRs32位乘法Rd=Rm*Rs
MLARd,Rm,Rs,Rn32位累加乘法Rd=Rm*Rs+Rn
UMULLRdLo,RdHi,Rm,Rs64位无符号乘法(RdLo,RdHi)=Rm*Rs

2、逻辑操作

OpcodeOperandsDeacriptionFunction
ANDRd,Rn,Op2逻辑与Rd=Rn&Op2
BICRd,Rn,Op2位清零Rd=&~Op2
EORRd,Rn,Op2逻辑或与Rd=Rn^Op2
ORRRd,Rn,Op2逻辑或Rd=Rn

3、比较操作

OpcodeOperandsDeacriptionFunction
CMPRn,Op2比较Rn-Op2
CMNRN,Op2负数比较Rn+Op2
TEQRn,Op2测试相等Rn&Op2
TSTRn,Op2测试Rn^Op2

ARM堆栈—先进后出

1、满堆栈
2、空堆栈
3、递增堆栈
4、递减堆栈

内存操作 - 读取内存


OpcodeOperandsDeacriptionFunction
单寄存器读写指令
LDRRn,Addr按照字节读取长度
STR
LDRB
LDRH
STRB
LDRH
STRH
LDRBT
STRBT
LDRT
STRT
LDRSB
LDRSH
LDRSH
多寄存器内存访问指令
LDMLDMIA R0!,{R3-R9}
STMSTMIA R1,{R3-R9}

地址模式:
数据块模式:IA(传输后地址加4),IB(传输前地址加4),DA(传输后地址减4),DB(传输前地址减4)

堆栈模式:满底层堆栈),EA(空递减堆栈),FD(满递减堆栈),ED(空递增堆栈),FA(满递增堆栈)


数据交换指令


SWAPRd,Rn,[Rn2]内存和寄存器字交换[Rn2]->Rd,Rn1->[Rn2]:如果Rd和Rn1相同就是直接交换
SWPB字节交换

跳转、状态操作


OpcodeOperandsDeacriptionFunction
B跳转指令pc<-label
BL带返回的连接跳转pc<-label
BX跳转并切换状态Thumb
BLX待返回的跳转并切换状态Thumb
状态寄存器操作把32位指令分为4个域:[7:0]控制位域c,[15:8]扩展位域x,[23:16]状态位域s,[31:24]:条件标志位域f
MRS把程序状态寄存器的值传送到通用寄存器
MSRCPSR,R0,SPSR,R0,CPSR_c,R0通用寄存器到程序状态寄存器
异常产生指令
SWISWI 0x02软中断指令
BKPTBKPT断点中断指令

伪指令

伪指令作用及类别
————我们的指令已经可以做各类操作库,但我们操作起来太麻烦了。
比如我现在要设置一个值给寄存器R0,但下次我修改了寄存器R0之后又需要都出来刚才的值,那我们就要先临时保存值到SPSR or CPSR,然后不断切换。
再比如,我们要做一个循环,就要用label结合BL不断进行,但如果我们要循环很多次。
我们就定义了一些类似带参数的宏的操作数一样,来定义我们的伪指令,方便我们更好的实现汇编程序逻辑。伪指令只是在汇编之前作用,汇编之后就会翻译成为标准的汇编指令。
我们又分为ARM汇编伪指令和GUN汇编伪指令。

基本常用伪指令


OpcodeOperandsDeacriptionFunction
AREAAREA test,CODE,READONLY声明区域段,数据区,代码区等等
CODE16,CODE32CODE32声明以下是32位还是16位指令,注意不是切换arm和thumb模式,只是告诉汇编器
ENTRYENTRY伪指令用于指定汇编程序的入口点。在一个完整的汇编程序中至少要有一个ENTRY(也可以有多个,当有多个ENTRY时,程序的真正入口点由链接器指定),单在一个源文件里最多有一个ENTRY(可以没有)。
ENDENDEND伪指令用于通知编译器到了源程序的结尾
EQUUARTLCON0 EQU 0x3FFD000EQU伪指令用于为程序的常量、标号等定义一个等效的字符名称,类似于c语言中的#define。其中EQU可用*代替
EXPORT.globalEXPORT伪指令用于在该程序中声明一个全局的标号,该编号可在其他的文件中引用。EXPORT可用GLOBAL代替,标号在程序中区分大小写,【WEAK】选项声明其他的同名标号优先于该标号被引用
IMPORT相当于静态引用IMPORT伪指令用于通知编译器要使用的标号在其他的源文件中定义,但要在当前源文件中引用,而且无论当前源文件是否引用该标号,该标号均会被加入当前源文件的符号中
EXTERN相当于动态引用EXTREN伪指令用于通知编译器要使用的标号在其他的源文件中定义,但要在当前源文件中引用,如果但当前源文件实际并未引用该标号。该标号就不会被加入到当前源文件的符号中
GET相当于引用文件GET伪指令用于将一个源文件包含的源文件中,并将被包含的源文件在当前位置进行汇编处理。可以实用INCLUDE代替GET|
RNRN伪指令用于给一个寄存器定义一个别名。采用这种方式可以方便程序员记忆寄存器的功能。其中,名称为给寄存器定义的别名,表达式为寄存器的编码

在汇编语言程序中常用的符号

符号命名约定  
- - -符号区分大小写,同名的大,小写符号会被编译器认为是两个不同的符号

- - -符号在其作用的范围内会被编译器认为是两个不同的符号
- - -自定义的符号名不能与系统的保留字相同
- - - 符号名不应与指令或伪指令同名
- - -关于ADS里面可恶的Tab和顶行“ADS Style”

符号,变量

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

OpcodeOperandsDeacriptionFunction
GBLA/GBLL/GBLSGBLA Test3定义全局数字/逻辑/字符串变量
LBLA/LBLL/LBLSLBLA Test3声明局部变量
SETA/SETL/SETSTest SETA 0xaa设置变量值不能有Tab
RLISTRegList RLIST{R0-R5,R8,R10}将寄存器立标名称定义为RegList ,可在ARM指令LDM/STM中通过该名称访问寄存器列表。不能有Tab

FAQ ?
定义变量存储在寄存器中还是内存中?

**变量代换 :  ”Sample- -LCLS S1    - -LCLS S2  - -S1 SETS “Test!” - -S2 SETS  “This is a $S1”;字符串变量S2的值为“This is a Test!”
表达式和运算 : -“+” , ”-“,   ” *”,“ /”及MOD算数运算符///”ROL“,”ROR“,”SHL“,及SHR移位运算符//”AND“,”OR“,”NOT“及”EOR“按位运算符/”=“,”>“,”<“,”>=“,”<=“,”/=“,”<>“运算符”LAND“,”LOR“,”LNOT“,及”LEOR“运算符

变量:数字常量一般为32为的整数,当作为无符号数时,起取值范围为0~232-1,当作为有符号数时,其取值范围为-231~231.//逻辑常量只有两种取值情况:真或假//字符串常量为一个固定的字符串,一般用于程序运行时的信息提示
寄存器操作

数据定义伪指令

OpcodeOperandsDeacriptionFunction
LDR R0,=0x12某时候可以提到MOV,MVN大范围寻址到寄存器-绝对寻址
ADR小范围寻址到寄存器+-255-相对寻址
ADR中范围寻这里写图片描述这里写图片描述

控制伪指令

这里写图片描述

©️2020 CSDN 皮肤主题: 编程工作室 设计师:CSDN官方博客 返回首页