ARM64指令快查

加载和存储指令

#J基地址偏移
LDR X0,[X1,#8]    //立即数是12位且为8的倍数,所以offset取值范围: 0~(2^12 *8) = 0~32760,存的时候,编译器会把这个值除以8存进去的
LDR X0,[X1,#8]!   //前变基,立即数9位,不需要是8的倍数,-256~255
LDR X0,[X1],#8    //后变基,立即数9位,同前变基
#K扩展模式
LDR X0,[X1,X2]	  //X0 = [X1+X2]
LDR X0,[X1,X2,LSL #3] //X0 = [X1 + X2<<3],立即数只能是0或3
LDR X0,[X1,W2,SXTW]	//W2有符号扩展,再与X1相加
LDR X0,[X1,W2,SXTW #3]	//W2有符号扩展,左移3,再与X1相加
#PC相对地址
my_data:
	.word 0x40
#define MY_LABLE 0x20
ldr x0,my_data	//x0= [PC+ (&my_data-PC)] = 0x20,my_data这个lable需要在PC上下1M内
ldr x0,=my_data	//x0=&my_data
ldr x0,MY_LABLE	//x0=[PC+0x20],这个偏移地址需要小于1M
ldr x0,=MY_LABLE	//x0=0x20

#S上述my_data如果超了PC 1M内,可以这样加载
ldr x5,=my_data
ldr x0,[x5]

#J加载和存储变种
LDRSW	有符号数据加载,4B,32b
LDRB	数据加载,1B,8b
LDRSB	有符号数据加载,1B,8b
LDRH	数据加载,2B
LDRSH	有符号数据加载 2B
STRB	数据存储,1B
STRH	数据存储,2B

my_data
	.quad 0x8a
ldr x5,=my_data
ldrb x0,[x5]	//x0=0x8a
ldrsb x1,[x5]	//x1=0x ff ff ff ff ff ff ff 8a,有符号扩展

#B不可扩展的加载和存储指令
//偏移量按照字节来扩展,可以是正数或者负数, 范围-256~255
LDUR <Xt>,[ <Xn|SP>, #<simm> ]//simm是9位的,表示Xn/SP可以加 -256~255的范围
STUR <Xt>,[ <Xn|SP>, #<simm>]	//同理
//也有变种,类似于LDURB/LDURSB/LDURH/LDURSH/STURB/STURH等

#D多字节内存加载和存储
//1.基地址偏移
LDP X1,X2,[ <Xn>|SP {,#<imm>}]	//[Xn+imm]放到X1,[Xn+imm+8]放到X2,imm是7位的,8的倍数,所以范围是-512~504
SDP X1,X2,[ <Xn>|SP {,#<imm>}]	//同上
//2.前变基模式
LDP X1,X2,[ <Xn>|SP ,#<imm>]!	//注意:最终 Xn=Xn+imm,不是Xn+imm+8
STP X1,X2,[ <Xn>|SP ,#<imm>]!
//3.后变基模式
LDP X1,X2,[ <Xn>|SP ], #<imm>	//X1=[Xn],X2=[Xn+8],Xn=Xn+imm
STR X1,X2,[ <Xn>|SP ], #<imm>	//同理

#D独占内存访问
LDXR X1,[ Xn|SP {,#0} ]
STXR Ws X1,[ Xn|SP {,#0} ]
LDXR X1,X2,[ Xn|SP {,#0} ]
STXR Ws X1,X2,[ Xn|SP {,#0} ]
//用于原子访问(锁会用到原子访问)
LDXR 在读内存时,会标记内存
STXR 在写内存时,会清标记,且Ws=0;如果发现内存没有独占,那么就不写内存,并把Ws=1
原子操作原理 伪代码:
LABEL:
	LDXR X0,[Xn]
	ADD X0,X0,#1
	STXR Ws,X0,[Xn]
	if(Ws !=0)	//写失败,标明内存标记被其他线程清掉
		goto LABEL	//重新执行整个读写操作

#N内存屏障
LDAR	加载-获取指令,LDAR后面的读写内存指令,必须在LDAR指令之后执行
STLR	存储-释放指令,所有加载和存储指令,都必须在STLR之前完成

#F非特权访问级别的加载、存储
适用于在EL0下的访问
LDTR/LDTRB/LDTRSB/LDTRH/LDTRSH/LDTRSW
STTR/STTRB/STTRH

入栈和出栈

ARM64去掉了PUSH和POP指令
入栈:
str X1,[SP,#-8]!		//SP=SP-8, [SP]=X1
stp X1,X2,[SP,#-16]!	//SP=SP-16, [SP]=X1, [SP+8]=X2
出栈:
ldr	X1,[SP],#8			//X1=[SP],SP=SP+8
ldp X1,X2,[SP],#16		//X1=[SP], X2=[SP+8], SP=SP+16 

MOV

MOV Xn, Xm|SP|#imm
#imm要求:
116位的无符号数(16位的立即数)
216位的立即数左移16位、32位、48位

MOV X1,0x1abcd	//错,超过了16位
MOV X1,ABCD0000	//对,ABCD左移16位

MOVZ:将一个16位立即数移动到寄存器的指定16位位置,其他位清零。
MOVK:将一个16位立即数移动到寄存器的指定16位位置,其他位保持不变。
MOVN:与MOVZ类似,但是将立即数取反后再使用。
  • 3
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值