ARMV7 /ARM7s/ARM64 代表不同的架构,也代表这不同的指令集
X0~X30 是64位通用寄存器,是向下兼容32位,其32位不是独立存在的,只是64位的低32位(W0~W30)
FP (X29) 栈底指针
LR (X30) 链接寄存器,保存子程序结束够需要执行的下一条指令,一般ret指令后,都要从该寄存器中读取下一条指令
PC 程序计数器 指向即将要执行的下一条指令,ARM64中,不可以软件修改PC寄存器,一般是要通过bl指令修改
X0~X7 用于子程序调用时的参数传递,X0还用于返回值的传递
CPSR 状态寄存器(32位的),其低8位成为控制位,程序无法修改,我们可不管,中间8~27位是保留位,也不用管。我们只关注31~28这四位,分别对应的标志位为:N(31位)、Z(30位)、C(29位)、V(28位);
NZCV 是CPSR状态寄存器的条件标志位,分别代表运算(算术或逻辑运算)中产生的状态,其可决定某条指令是否执行。
(1) N (Negative负号标志)代表运算结果为负,N=1,如果为非负,N=0
(2)Z(Zero0标志位) 指令结果为0时 Z=1,否则Z=0
(3)C (Carry进位标志)无符号数运算,加法运算,如果结果有进位,说明无符号运算溢出 C = 1,否则C = 0; 减法运算(含CMP),如果结果有借位,说明无符号溢出 C= 0,否则C= 1;
(4)V (OverFlow溢出标志)有符号运算,因为第一位是符号位,有溢出 V = 1
* 正数 + 正数 为负数 溢出
* 负数 + 负数 为正数 溢出
* 正数 + 负数 不可能溢出
MOV X1,X0 ;将寄存器X0的值传递给寄存器X1 ,MOV指令只能用于寄存器内传值,寄存器与内存之间使用STR/LDR 或者STP/LDP
ADD X0, X1, X2 ;X0 = X1+X2 加指令
SUB X0, X1, X2 ;X0 = X1 - X2 减指令
AND X0, X0, #0XF; X0 = X0 & 0Xf 与指令
ORR X0, X0, #9; X0 = X0 | 9 或指令
EOR X0, X0, #0XF; X0 = X0 ^0xF 异或指令
STR X0, [SP, #0X8] ; st : store,往内存中写数据(偏移值为正),X0寄存器的数据传送到SP+0X8地址指向的存储空间
LDR X5, [X6, #0X08] ;ld:load,X6寄存器与0X08的和指向的地址内的数据传送到X5寄存器,读取内存数据到寄存器
STP X29, X30, [SP, #0x10] ; store pair 存放一对数据,入栈指令
LDP X29, X30 ,[SP ,#0x10] ;store pair 将SP+0X10指向的地址数据放到X29,X30寄存器
STUR W0, [X29, #-0X8] ;往内存写数据(偏移值为负)
CBZ ;比较,如果结果为zero,就转移,只能跳转到后面的指令
CBNZ ;比较,如果为非0,就跳转,只能跳转到后面的指令
CMP ;比较指令,相当于SUBS,影响程序状态寄存器CPSR
B ;跳转指令,可带条件跳转与CMP配合使用
BL ;带返回值的跳转指令,返回值地址保存在LR(X30)寄存器
BLR ;带返回值的跳转指令,跳转到指令后边跟随寄存器中执行 eg:BLR X8 ;跳转到X8保存的地址中去执行
RET ;子程序返回指令,返回地址保存到LR(X30寄存器)
adrp指令 (address page)内存地址按页寻址
adrp x0, 1 ;将1左移12位,低12位补零,意思就是将PC寄存器的低12位清零
补充
ARM处理器的寻址方式有:
寄存器寻址:
如:mov x1,x0 ;x0 ---> x1
sub x0, x1, x2 ;x1-x2 --->x0
立即寻址:
如:subs x0, x0, #1 ; x0 - 1 --> x0
mov x0, 0xff00 ;0xff --> x0
寄存器偏移寻址:(这是ARM指令集特有的寻址方式)
mov x0, x1, lsl, #3 ;x1的值左移3位,结果存入x0,即X0 = x1 * 8
ands x1, x1, x2, lsl, x3 ;x2左移x3位,和x1相与,再赋值给x1
lsl ;逻辑左移,低位空出补0
lsr ;逻辑右移,高位空出补0
asr ;算术右移,移位时符号位不变,即操作源为正数,高位补0,若为负数,补1
ror ;循环右移,低位移出补到高位 相应的rol:循环左移
rrx ;操作数右移一位,左侧空位有CPSR的C填充
寄存器间接寻址:
LDR R1, [R2] ;寄存器R2中的数值作为地址,取出地址中的数值存到R1中
SWP R1, R1, [R2] ;将R2中数值作为地址,取出地址中的值与R1中的值交换
基址寻址:
LDR R2, [R3, #0x0f] ;将R3的值加0x0f作为地址,取出值存到R2寄存器中
STR R2, [R0,#-2] ;把R2中的值,存到R0的值减2作为地址的内存中
多寄存器寻址
堆栈寻址:
块拷贝寻址
相对寻址
跳转指令 BL
条件跳转指令