ARM64基础5:A64的存储和加载指令

ldr和str指令
ARMv8也是基于指令加载和存储的架构,即不能直接操作内存;

LDR <reg_dst>,<addr>  //把存储器地址的数据加载到目的寄存器中;
STC <reg_src>,<addr> //把原寄存器的值,存储到内存中;

ldr指令寻址1:地址偏移模式

ldr Xd,[Xn,$offset]
.global ldr_test //申明全局函数
ldr_test:
	// 1. ldr地址偏移模式
	mov x1, 0x80000
	mov x3, 16

	/* 读取0x80000地址的值, 到x0寄存器*/
	ldr x0, [x1]

	/* 读取0x80000+8地址的值*/
	ldr x2, [x1, #8]

	/* 读取x1+x3地址=0x80000+16的值*/
	ldr x4, [x1, x3]

	/* 读取(x1+ x3<<3) =0x80080地址的值*/
	ldr x5, [x1, x3, lsl #3]

	ret

用qemu+Eclipse单步调试,查看寄存器值如下
ARM64基础5:A64的存储和加载指令_第1张图片

ldr指令寻址2:变基模式

LDR X0,[X1, #8]! //前变基模式,先更新x1=x1+8,再加载x1地址的值到x0
LDR X0,[X1],#8   //后变基模式,先读取x1的地址处的值到x0, 再更新x1=x1+8

STR X2,[X1, #8]! //前变基模式,先更新x1=x1+8,再存储x2的值到x1地址处
LDR X2,[X1],#8   //后变基模式,先存储x2的值到x1地址处, 再更新x1=x1+8

测试代码:

mov x2,0x400000
ldr x6, =0x1234abcd
str x6,[x2,#8]! 

观察内存值如下图
ARM64基础5:A64的存储和加载指令_第2张图片

mov x2,0x500000
ldr x6, =0x1234abcd
str x6,x2,#8

观察内存值如下图
ARM64基础5:A64的存储和加载指令_第3张图片

ldr指令寻址3:加载标签模式

LDR LABEL //读取(PC指针+label offset)地址的值
#define MY_label 0x20
ldr x6,MY_label  //此时PC=0x802e4,读取内存值如下图
ldr x7,=MY_label //立即数, 伪指令

ARM64基础5:A64的存储和加载指令_第4张图片

加载指令mov

mov:
(1) 16位立即数;
(2)或者16为立即数,左移16,32,48位;

多字节加载和存储指令ldp和stp

ldp和stp可以一条指令价值或存储16个字节;

LDP X1,X2,[X0]  //加载x0地址的值到x1,加载x0+8地址的值到x2
STP X1,X2,[X0]  //存储x1的值到x0地址处,存储x2到x0+8地址处

汇编实现: 假设16bytes对齐;

.global my_memset_16bytes
my_memset_16bytes:
	mov x4, #0

1:
	stp x1, x1, [x0], #16
	add x4, x4, #16
	cmp x4, x2
	bne 1b

	ret

C语言调用的结果如下:

my_memset_16bytes(0x600000,0xaabbccdd,4096);

ARM64基础5:A64的存储和加载指令_第5张图片

读/写特殊寄存器mrs,msr

mrs x0,TTBR0_EL1   //把TTBR0_EL1寄存器的值读到x0中
msr TTBR0_EL1,X0   //把X0寄存器的值,写入TTBR0_EL1寄存器

访问标签

/*lab07: test for label acess*/
#define my_label 0x30

.globl string1
string1:
	.string  "Hello a64"

.align 3
.globl my_data
my_data:
	.word 0xaa

.align 3
.global  access_label_test
access_label_test:
	//1.load a big num
	//mov,x0,0xffff0000ffff0000 //err,mov, 16bit
	ldr x1,=0xffff0000ffff0000

	//2,init reg for bit
	ldr x2,=(1<<1)|(1<<15)|(48)

	//3.acess a macro
	ldr x1,=my_label  //0x30
	ldr x2,my_label   //pc+0x30

	//4.access a string
	ldr x3,string1    //ascii of string
	ldr x4,=string1   //addr of string1

	//5, access a data
	ldr x5,my_data   //value of my_data
	ldr x6,=my_data  //addr of my_data

	ret

你可能感兴趣的:(ARM+Linux,A64汇编,LDR,STR,存储和加载指令)