ARM汇编指令

1.ARM寄存器那点知识

1.1 ARM处理器的八种工作模式(在ARMv8中加入了Monitor模式用于安全扩展)

usr模式:正常程序运行时的模式
fiq模式:当配置有快速中断时,如果产生fiq时间,ARM核将会切换到该模式
irq模式:中断模式,一般用于通用中断处理,被ROS使用
svc模式:操作系统使用的保护模式,当进行软中断,复位时会进入该模式
sys模式:运行具有特权的操作系统任务,属于特权模式
abt模式:当数据或者指令预取值终止则会进入该模式
und模式:当未定义指令执行时则会进入该模式
monitor模式:用于安全扩展,是安全世界TEE和普通世界REE中间的桥梁

1.2 通用寄存器和专用寄存器

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:表示运算结果为负数

2.ARM指令 (用到就更新)

2.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]这个内存存储单元

2.2.堆栈指令

在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

2.3 数据传送指令

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

2.4 算数逻辑运算指令

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)

2.5 移位指令

#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 (这里的右移是循环右移)

2.6比较指令

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不同的是它将对第二个操作数取反然后做比较

2.7 条件执行指令

TODO

2.8 跳转指令

TODO

2.9 ARM伪指令

(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为填充字节值

你可能感兴趣的:(arm)