ARM指令集效率高,但是代码密度高
Thumb指令集具有较高的代码密度,却仍然保持着ARM的大多数性能上的优势,它是ARM的子集。
所有的ARM置零都是可以条件执行的,而Thumb置零仅有一条指令具备条件执行的功能。
ARM和Thumb程序可以相互调用,相互之间状态切换开销几乎为零。
首先我们来看一下分类:
一、数据处理指令操作数寻址方式
1、立即数寻址方式
2、寄存器寻址方式
3、寄存器移位寻址方式
二、存储器访问指令操作数寻址方式
1、寄存器间接寻址
2、基址变址寻址
3、相对寻址
4、多寄存器寻址(块拷贝寻址)
5、堆栈寻址
下面来一一介绍:
ARM有9种寻址方式
寻址方式:
1、立即寻址:
立即寻址指令中的操作码字段后面的部分就是操作数本省,也就是说,数据就包含再指
令,取指令也就取出了可以立即使用的操作数。举例:
SUBS R0,R0,#1 ;R0减1,结果放入R0中,并且影响标志位
MOV R0,#0xFF000 ;将立即数0xFF000装入R0寄存器
ARM规定:这个立即数必须符合8位图格式,负责必须使用“文字池”方式,通过存储器访问指令加载,所谓的8位图格式就是指,这个数据能通过一个8bit的数循环右移偶数位得到。
2、寄存器寻址:
操作数的值在寄存器中,指令中的地址字段指出的是寄存器的编号,指令执行的时候直
出寄存器值来操作。举例:
MOV R1,R2 ;将R2的值存入R1
MOV R0,R1,R2 ;将R1的值减去R2的值,结构存到R0
3、寄存器移位寻址
寄存器移位寻址是ARM处理器特有的寻址方式。当第二个操作数是寄存器移位方式时,
第二个操作数在与第一个操作数结合之前,选择进行移位操作。举例:
MOV R0,R2,LSL #3 ;R2的值左移3位,结果放入R0,即R0=R2*8
ANDS R1,R1,R2,LSL R3 ;R2的值左移R3位,然后和R1相"与"操作,结构放入R1
可采用移位操作的指令如下:
LSL左移、LSR右移、ASR算术右移、ROR循环右移、RRX带扩展的循环右移
4、寄存器间接寻址:
寄存器间接寻址指令中的地址码给出的是一个通用寄存器的编号,所需的操作数保存
再寄存器指定地址的存储单元中,即寄存器为操作数的地址指针,举例:
LDR R1,[R2] ;将R2指向的单元中的数据保存再R1中
SWP R1,R1,[R2] ;将寄存器R1的值和R2指向的单元中进行内容交换
5、基址变址寻址:
基址寻址就是将基址寄存器的内容与指令中给出的偏移量进行相加,形成操作数的有效
地址。
基址寻址用于访问基址附近的存储单元,常用于查表、数组操作以及功能不见寄存器访
问等 举例:
LDR R2,[R3,#0x0c] ; 读取R3 0x0c地址指向的存储单元的内容,放入R2
STR R1,[R0,#-4]! ;先R0=R0-4,然后把R1的值寄存到R0所指向的单元中
LDR R1,[R0,R3,LSL #1] ;将R0 R3*2地址上的单元的内容读出,并存入R1中
6、相对寻址:
相对寻址是基址寻址的一种变通。由程序计数器PC提供基址地址,指令中的地址码字段为偏移量。两者相加后得到的地址即为操作数的有效地址。
7、多寄存器寻址:
多寄存器寻址即一次可传送几个寄存器的值,允许一条指令传送16个寄存器的任何子集或
所有的存储器,举例:
LDMIA R1!,{R2-R7,R12};将R1指向的单元中的数据读出到R2---R7、R12中(R1自自动 )
STMIA R0!,{R2-R7,R12};将R2---R7、R12中的数据一次读入到R0指向的单元中(R0自动 )
8、堆栈寻址(块拷贝寻址):
堆栈是一种按特定顺序进行存取的存储区,操作顺序分为“先进后出”和“后进先出”,堆栈寻址是隐含的,它使用一个专门的寄存器(堆栈指针)指向的存储区域(堆栈),指针所指向的存储单元即是堆栈的栈顶。
存储器堆栈可以分为两种:
向上生长:递增堆栈
向下生长:递减堆栈
还有从当前堆栈指针指向的内容是否有效可以分为:满递增、空递增、满递减、空递减
举例:
STMFD SP!,{R1-R7,LR} ;将R1---R7、LR入栈。满递减堆栈
LDMFD SP!,{R1-R7,LR} ;数据出栈,放入R1---R7、LR寄存器,满递减堆栈
问题:堆栈是先进后出 先把r1---r7放入堆栈中,再按照上述形式出栈,数据能还原么?还原了数据不是翻转了么