1、ARM指令组成
<opcode> {<c>} {S} <Rd> <Rn> <shifter_operand>
<opcode>:要执行的指令,例如ADD、MOV、LDR...
{<c>}:指令执行的条件。例如:两个操作数相等指令执行或者一些其他的条件。
{S}:1.我们运行结果是否要影响CPSR标志位
2.当在异常处理是,如果要操作的是PC指针,那么当有S时,则会同时将SPSR寄存器得知恢复到CPSR中
<Rd>:目标寄存器,用于存放指令
<Rn>:操作数1,用于存放要操作的数据
<shifter_operand>:操作数2,也是用于存放要操作的数据。只是可以是以下几种:
立即数、寄存器、移位运算
CPSR主要标志位:
N:表示正负
N=0,表示结果为整数或零
N=1,表示结果为负数
Z:表示结果是否为零
Z=0,表示结果不为0
Z=1,表示结果为0
C:表示在无符号数运算时是否有溢出
加法指令:C=0,表示结果未溢出,C=1,表示结果溢出
减法指令:C=0,表示运算发生借位,C=1,表示运算未发生借位
V:表示在有符号运算时是否发生溢出
V=0,表示有符号数运算未发生溢出
V=1,表示有符号数运算发生溢出
2、ARM指令寻址方式
数据指令处理寻址方式
1、立即数寻址:
通常一条指令如果使用立即数寻址的话通常通过12bit的立即数区域来表示立即数的,但是在实际开发过程中我们往往需要通过这12bit的编码来表示一个32bit的数据,那么这个时候我们无法通过12bit来标示32bit的数据。那么ARM将12bit的区域分为了两个部分x和y,其中x占[0:7]8bit,y占[8:11]4bit.那么立即数是通过如下公式计算得到:
立即数=X>>(Y*2) 32位循环右移
这里如果立即数在0~0xFF,那么直接由X表示,Y=0
其他情况则需要要通过计算公式得到立即数,如果无法找个一个算法得到X,Y,那么这个立即数被称为非法立即数
2、寄存器寻址
将寄存器中存放的数据取出,然后进行运算:
MOV R2,R1 将R1寄存器中的数据放入R2,R1即为寄存器寻址
3、寄存器移位寻址
LSL逻辑左移:移位后,寄存器低位补0,高位丢弃
LSR逻辑右移:移位后,寄存器高位补0,地位丢弃‘
ASR算术右移:在移位的过程中保证符号位不变
ROR循环右移:当低位数据右移之后在高位补充
RRX带扩展右移:就是在移位过程中空出来的高位由CPSR的C位补充
内存访问指令寻址方式
字、半字、无符号字节指令的寻址方式
字:在ARM处理器中位32bit也就是4Byte
半字:字的一半就是半字,16bit也就是2Byte
字节:8个bit位,也就是1Btye
批量指令的寻址方式
堆栈操作
LDM|STM {<amode>}{<cond>}<addressing_mode> <Rn>
<amode>可以取以下操作:
FD:满减栈
ED:空减栈
FA:满增栈
EA:空增栈
批量操作
IA:后递增
IB:先递增
DA:后递减
DB:先递减
协处理器指令的寻址方式
协处理器没有有对应的地址,都是通过协处理器名称和各种操作数决定了要访问的寄存器,不能通过地址加偏移的方式进行访问。
3、ARM处理器指令集
数据操作指令
mov {<c>} {S} <Rd>, <shifter_operand> # 将一个立即数、寄存器中的值、移位操作产生的值放入另一个寄存器中(Rd)
三种常见的用法
用于数据传送可以传送立即数、寄存器的值和移位操作产生的值
当目标寄存器是PC指针的时候,可以实现寄存器的跳转
当目标寄存器是PC指针的时候并且{S}位被设置那么在跳转指令的同时会把SPSR寄存器的值恢复到CPSR中,多用于异常返回
mvn {<c>} {S} <Rd>, <shifter_operand> # 反向数据传输指令,即将一个数的反码放入Rd寄存器
常用用法:
向寄存器中传送一个负数
生成一个数的位掩码
· 求一个数的反码
add {<c>} {S} <Rd>, <Rn>, <shifter_operand> 逻辑与 #通过Rn寄存器的值和shifter_operand做按位逻辑与操作,通常用于指定位清除,其余位保持不变
orr {<c>} {S} <Rd> <Rn> <shifter_operand> 逻辑或 #通过Rn寄存器的值和shifter_operand做按位逻辑或操作,通常用于指定位置1,其余位保持不变
bic {<c>} {S} <Rd>, <Rn>, <shifter_operand> 位清除 #将寄存器Rn的值与<shifter_operand>的值取反,然后将取反后的值与Rn按位做逻辑与运算,将结果放入Rd寄存器中。从而实现只用一条指令就可以实现位清除
eor {<c>} {S} <Rd>, <Rn>, <shifter_operand> 异或 # 将寄存器Rn的值与<shifter_operand>的值做逻辑异或运算,并将结果放入Rd寄存器中。 异或操作通常用于将指定位反转