usr模式:正常程序运行时的模式
fiq模式:当配置有快速中断时,如果产生fiq时间,ARM核将会切换到该模式
irq模式:中断模式,一般用于通用中断处理,被ROS使用
svc模式:操作系统使用的保护模式,当进行软中断,复位时会进入该模式
sys模式:运行具有特权的操作系统任务,属于特权模式
abt模式:当数据或者指令预取值终止则会进入该模式
und模式:当未定义指令执行时则会进入该模式
monitor模式:用于安全扩展,是安全世界TEE和普通世界REE中间的桥梁
ARM处理器中的寄存器可分为通用寄存器和专用寄存器两种。寄存器R0-R12属于通用寄存器,除了FIQ工作模式,在其他工作模式下这些寄存器都是共用、共享的。R0-R3通常用来传递函数的参数,R4-R11用来保存程序运算的中间结果或者函数的局部变量等,R12常用来作为函数调用过程中的临时寄存器。ARM处理器有多种工作模式,除了这些在各个模式下通用的寄存器,还有一些寄存器在各自的工作模式下独立存在,如R13,R14,R15,CPSP,SPSR寄存器。
寄存器 | 备注 |
---|---|
R0-R3 | 通用寄存器,用于c 函数的形参传递 |
R4-R11 | 通用寄存器,用来保存程序运算的中间结果或函数的局部变量等 |
R12 | 临时寄存器,作为函数调用过程中的临时寄存器 |
R13 | 堆栈指针寄存器SP,用来维护和管理函数调用过程中的返回值 |
R14 | 链接寄存器LR,在函数调用过程中主要用来保存上一级函数调用者的返回地址 |
R15 | 程序计数器PC,CPU从内存取指令执行,默认从PC保存的地址中取的 |
CPSR | 当前处理器状态寄存器,主要用于表征当前处理器的运行状态,能查询处理器当前的工作模式,中断使能控制,以及其他的一些状态位、标志位 |
SPSR | 程序状态保存寄存器,当处理器切换工作模式或者发生异常时,SPSR用来保存当前工作模式下的处理器现场,即将CPSR寄存器的保存到当前工作模式下的SPSR寄存器中,当处理器从异常返回时,就可以从SPSR寄存器中恢复原先的处理器状态 |
CRSR寄存器 每一位的作用如下
BIT[0:4] 处理器模式
BIT[5] 0:ARM指令集 1:Thumb指令集
BIT[6] 0:启动FIQ中断 1:关闭FIQ中断
BIT[7] 0:启动IRQ中断 1:关闭IRQ中断
BIT[8:27] 保留
BIT[28] 对于加/减法运算指令,当操作数和运算结果为二进制的补码表示的带符号数时V=1表示符号位溢出。
BIT[29] 0:ARM指令集 1:Thumb指令集
BIT[30]调用CMP指令 0:运算结果不为0 1:运算结果为0
BIT[31] 0:表示结果为正数或零 1:表示运算结果为负数
LDR R1, [R0] ;将R0中的值作为地址,将该地址上的数据保存到R1
STR R1, [R0] ;将R0中的值作为地址,将R1中的值存储到这个内存地址
LDRB/STRB ;每次读写一字节,LDR/STR默认每次读写4字节
LDM/STM ;批量加载/存储指令,在一组寄存器和一片内存之间传输数据
SWP R1,R1,[R0] ;将R1与R0中地址指向的内存单元中的数据进行交换
SWP R1,R2,[R0] ;将[R0]存储到R1,将R2写入[R0]这个内存存储单元
在ARM中堆栈有四种形式
堆栈格式 | 备注 |
---|---|
FA | 满递增堆栈 |
FD | 满递减堆栈 |
EA | 空递增堆栈 |
ED | 空递减堆栈 |
在一个堆栈内存结构中,如果堆栈指针SP总是指向栈顶元素,那么这个栈就是满栈,否则指向栈后的一个元素就是空栈。ARM处理器使用的一般都是满递减堆栈,将一组寄存器入栈,或者从栈中弹出一组寄存器时,使用一下指令
LDMFD SP!,{R0-R2,R14}; //将内存栈中的数据依次弹出到R14,R2,R1,R0中
STMFD SP!,{R0-R2,R14}; //将R0,R1,R2,R14依次压入内存栈
除此之外,ARM还专门提供了PUSH和POP指令来执行栈元素的入栈和出栈操作。PUSH和POP的使用方法如下:
PUSH{R0-R2,R14} // 将R0、R1、R2、R14的值依次压入栈
POP{R0-R2,R14} // 将栈中的数据依次弹到R14、R2、R1、R0
MOV R1, #1 ;将立即数1传送到寄存器R1中
MOV R1, RO ;将R0寄存器中的值传送到R1寄存器中
MOV PC,LR ;将R14也就是LR中的返回地址给PC
MVN R0, #0xFF ;将立即数0xFF取反后赋值给R0
MVN R0,R1 ;将R1寄存器的值取反后赋值给R0
ADD R2,R1,#1 ;R2 = R1 + 1
ADC R1,R1,#1 ;R1 = R1 + 1 + C (其中C为CPSR寄存器中的进位)
SUB R1,R1,R2 ;R1 = R1 - R2
SBC R1,R1,R2 ;R1 = R1 - R2 - C
AND R0,R0,#3 ;R0 = R0 & 3
ORR R0,R0,#3 ;R0 = R0 | 3
EOR R0,R0,#3 ;R0 = R0 异或 3
BIC R0,R0,#3 ;R0 = R0 & (~3)
#constant,n ;将立即数constant循环右移n位
ASR #n ;算数右移n位,n的取值范围:[1-32]
LSL #n ;逻辑左移n位,n的取值范围:[0-31]
LSR #n ;逻辑右移n位,n的取值范围:[1-32]
ROR #n ;向右循环移n位,n的取值范围:[1-31]
RRX ;向右循环移1位,带扩展位
type Rs ;仅在ARM中可用,其中type指ASR ,LSL,LSR,ROR, Rs是提供位移量的寄存器名称
//type Rs 和 #constant,n 具体使用方法如下
ADD R3,R2,R1, LSL #3 ;R3 = R2 + R1 << 3
ADD IP,IP, #16,20 ;IP = IP + 16 >> 20 (这里的右移是循环右移)
CMP R1 , #10 ;R1-10,运算结果会影响CPSR寄存器中的N、Z、C、V位
CMP R1 , R2 ;R1-R2,运算结果会影响CPSR寄存器中的N、Z、C、V位
CMN R0 , #1 ;R0-(-1),与CMP不同的是它将对第二个操作数取反然后做比较
TODO
TODO
(1).align val_1 , val_2, val_3
其中第 1 个参数值 val_1 是所需要的对齐值;第 2 个是填充字节的值,填充值可以省略,若省略则编 译器使用 0 值填充。第 3 个用来指明最大用于填充或跳过的字节数。如果进行边界对齐会超过 val_3 指定的最大字节数,那么就根本不进行对齐操作。如果需要省略第 2 个参数 val_2 但还是需要使用第 3 个参数 val_3 ,那么只需要放置两个逗号即可。
.align 11, 0 // 11为对齐值 0为填充字节值