做人呢,最紧要就系开心啦

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

600次阅读
没有评论

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 的存储和加载指令

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 的存储和加载指令

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

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

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

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

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

加载指令 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 的存储和加载指令

读 / 写特殊寄存器 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

正文完
 
admin
版权声明:本站原创文章,由 admin 2021-11-02发表,共计1762字。
转载说明:除特殊说明外本站文章皆由CC-4.0协议发布,转载请注明出处。
评论(没有评论)