什么是ARM

ARM架构,曾称为进阶精简指令集机器(Advanced RISC Machine)是一个32位精简指令集(RISC) 处理器架构

ARM大小端

最高有效位 MSBMost Significant Bit)对应大端(Big-endian

最低有效位LSBLeast Significant Bit)对应小端(Little-endian

  • armelarm eabi little endian的缩写,软件浮点
  • armhfarm hard float的缩写,硬件浮点
  • arm64:64位的arm默认就是hf的

ARM运行模式

一共有9种模式,下图有7种模式。还有Hyp模式和Monitor模式

image-20241009211117833

ARM工作状态

  • ARM状态:32位,执行字对准的ARM指令
  • Thumb状态:16位,字对准的Thumb指令。通过缩短指令长度来提高代码密度。

进入不同工作状态的方法

进入Thumb状态

(1)执行BX指令,并设置操作数寄存器的状态(位[0])为1。

(2)在Thumb状态进入异常(所有的异常都是ARM状态),当异常处理返回时自动转换Thumb指令

进入ARM状态

(1)执行BX指令,并设置操作数寄存器的状态(位[0])为0

(2)进入异常时,将pc放入异常模式链接寄存器中,从异常向量地址开始执行也可进入ARM状态

Thumb状态与ARM状态寄存器

寄存器是ARM架构的一个重点,在x86架构上指令可以直接对内存的数据进行操作,而在ARM架构中必须将内存的数据放入寄存器中再进行操作。而寄存器的数量取决于ARM的版本,而ARM32架构下共30个寄存器:

1
2
3
4
5
6
7
•R0在常规操作中可用于存储临时值,也可以用于存储函数的第一个参数或返回结果
•在ARM架构中约定指定函数前四个参数存储在R0~R3寄存器中
•R7寄存器在函数调用中负责存储系统调用号
•R11寄存器即可以用来记录回溯信息,也可以当做局部变量来使用
•R13寄存器SP(堆栈指针)指向堆栈的顶部
•R14寄存器LR(链接寄存器)在进行函数调用时,LR寄存器内保存调用函数的下一条指令地址,用于被调用函数(子函数)结束工作后返回调用函数(父函数)
•R15寄存器PC(程序计数器)类似于X86架构下的EIP寄存器负责保存目标地址,与x86不同的点在于PC在ARM状态下存储当前指令+8的地址。

ARM使用场景

  • CPU流水线,把一条指令分为多个处理阶段
  • ARM使用三级流水线,加速指令处理速度
  • ARM的三级流水分别是:取址(fetch)、译码(decode)、执行(execute)。PC指向fetch的指令。

ARM指令集

Intel和ARM之间的区别主要是指令集,Intel采用复杂指令集而ARM则是精简指令集,精简指令集通过减少每条指令的时钟周期来缩短执行时间可以更快的执行指令,但因为指令较少因此在实现功能时会显得比Intel冗长。

数据处理指令

mov指令格式

1
MOV{条件}{S} 目的寄存器,源操作数

S决定指令的操作是否影响CPSR中条件标志位的值

示例:

1
2
3
4
MOV R1,R0		;将寄存器R0的值传送到寄存器R1
MOV PC,R14 ;将寄存器R14的值赋值给PC,常用于子程序返回
MOV R1,R0,LSL #3 ;将寄存器R0的值左移3位后传送到R1(即乘8)
MOVS PC,R14 ;将寄存器R14的值传送到PC中,返回到调用代码并恢复标志位

mvn指令格式

1
MVN{条件}{S} 目的寄存器,源操作数

S决定指令的操作是否影响CPSR中条件标志位的值

示例:

1
MVN R0, #0		;将立即数0取反传送到寄存器R0中,完成后R0=-1(有符号位取反)

算数运算指令

加法指令:ADD

ADD指令格式

1
ADD{条件}{S} 目的寄存器,操作数1,操作数2

示例

1
2
3
ADD R0,R1,R2			;R0 = R1 + R2
ADD R0,R1,#256 ;R0 = R1 + 256
ADD R0,R2,R3,LSL#1 ;R0 = R2 + (R3<<1)

带进位的加法指令:ADC

ADC指令格式

1
ADC{条件}{s} 目的寄存器,操作数1,操作数2

ADC指令用于将两个操作数相加,再加上CPSR中的C条件标志位的值,并将结果存放到目的寄存器中。

减法指令:sub

sub指令格式

1
SUB{条件}{S} 目的寄存器,操作数1,操作数2

示例:

1
2
3
SUB R0,R1,R2			;R0 = R1 -R2
SUB R0,R1,#256 ;R0 = R1 - 256
SUB R0,R2,R3,LSL#1 ;R0 = R2 - (R3<<1)

比较指令

直接比较指令:CMP

CMP指令的格式为:

1
CMP{条件} 操作数1,操作数2

示例:

1
2
CMP R1,R0		;将寄存器R1的值与寄存器R0的值相减。并根据结果设置CPSR的标志位
CMP R1,#100 ;将寄存器R1的值与立即数100相减,并根据结果设置CPSR的标志位

位测试指令:TST

TST指令的格式:

1
TST{条件} 操作数1,操作数2

TST指令用于把一个寄存器的内容和另一个寄存器的内容或立即数进行按位与运算,并根据运算结果更新CPSR中条件标志位的值。

示例:

1
2
TST R1,#%1		;用于测试在寄存器R1中是否设置了最低位(%表示二进制数)
TST R1,#0xffe ;将寄存器R1的值与立即数0xffe按位与,并根据结果设置CPSR的标志位

逻辑运算指令

逻辑与指令:AND

AND指令格式:

1
AND{条件}{S} 目的寄存器,操作数1,操作数2

示例:

1
AND R0,R0,#3		;该指令保持R0的0、1位,其余位清0

逻辑异或指令:EOR

EOR指令格式:

1
EOR{条件}{S} 目的寄存器,操作数1,操作数2

示例:

1
EOR R0,R0,#3			;该指令反转R0的0、1位,其余位保持不变

位清零指令

位清零指令:BIC

BIC指令格式为:

1
BIC{条件}{S} 目的寄存器,操作数1,操作数2

示例:

1
BIC R0,R0,#%1011		;该指令清楚R0中的位0、1和3,其余位保持不变

转移指令

B指令

B指令格式

1
B{条件} 目标地址

示例:

1
2
3
B Label			;程序无条件跳转到标号Label处执行
CMP R1,#0 ;当CPSR寄存器中的z条件码置位时,程序跳转到标号Label处执行
BEQ Label

BL指令

BL指令格式

1
BL{条件} 目标地址

示例:

1
BL Lavel		;当程序无条件跳转到标号Label处执行时,同时将当前的PC值保存到R14中

BLK指令

BLK指令格式

1
BLK 目标地址

BLX指令从ARM指令集跳转到指令中所指定的目标地址,并将处理器的工作状态有ARM状态切换到Thumb状态,该指定同时将PC的当前内容保存到寄存器R14中。

BX指令

BX指令格式

1
BX{条件} 目标地址

BX指令跳转到指令中所指定的目标地址,目标地址处的指令既可以是指ARM指令,也可以是Thumb指令。

加载/存储指令

  • LDR用于将某些内容从内存加载到寄存器中,例如LDR R2, [R0]R0寄存器中存储的内存地址的值读入R2寄存器
  • STR用于将某些内容从寄存器存储到内存地址中,例如STR R2, [R1]R2寄存器中将值存储到R1寄存器中的内存地址中