ARMV8 - A64 - 存储器读写指令

说明

  • 存储器读写指令是用来读写内存/SRAM/外设寄存器等存储器的汇编指令。
  • ARM指令集属于RISC指令集,RISC指令集采用典型的加载/存储体系结构,CPU无法对内存里的数据直接操作,只能通过Load/Store指令来实现,当我们需要对内存中的数据进行操作时,要首先将这个数据从内存加载到寄存器,然后在寄存器中对数据进行处理,再将结果重新存储到内存中,如下:
  • Load/Store 示例:
char c = 6;
* 对应的汇编代码
mov w0, 6    //先将6保存到通用寄存器w0中
strb    w0, [sp, 31] //再将w0数据store到内存栈([sp, 31])中。

int c = a + b;
* 对应汇编代码
ldr w1, [sp, 12] //从栈上将a load到通用寄存器w1
ldr w0, [sp, 8] //从栈上将b load到通用寄存器w0
add w0, w1, w0  //将寄存器w0和w1中的数据相加,在保存到w0
str w0, [sp, 28] //将w0中的数据保存到栈上

对应汇编指令

  • aarch64通过str系列指令实现:将寄存器中的数据保存(store)到内存中,以及通过ldr系列指令实现:将内存中数据读取(load)到寄存器中。

数据类型

  • 与高级编程语言类似,ARM汇编支持load/store不同的数据类型,可以是有符号或无符号的字、半字或字节, 对应的汇编指令如下:
ldr = Load Word
ldrh = Load unsigned Half Word
ldrsh = Load signed Half Word
ldrb = Load unsigned Byte
ldrsb = Load signed Bytes

str = Store Word
strh = Store unsigned Half Word
strsh = Store signed Half Word
strb = Store unsigned Byte
strsb = Store signed Byte
  • 默认(ldr/str)支持无符号的word(4字节)或者8字节,带h表示支持半字(2字节),带b表示支持1个字节,带s表示有符号,

str(store register)/ldr(load register)系列指令

  1. str/ldr指令
  • 操作对象:一个寄存器,操作数据size:和使用的寄存器相关。
str x0, [sp] //将通用寄存器x0中的值(64bits)存储到栈顶指针sp指向的存储地址
str w0, [sp] //将通用寄存器w0中的值(32bits)存储到栈顶指针sp指向的存储地址
ldr x0, [sp, 8] //将栈顶指针sp+8指向地址的数据保存到通用寄存器x0中(64bits)
ldr w0, [sp, 8] //将栈顶指针sp+8指向地址的数据保存到通用寄存器w0中(32bits)
  1. stp/ldp指令
  • 能够同时操作两个寄存器,p表示pair,数据size和str指令一致,常用来做出入栈操作。
stp x29, x30, [sp, -16]!
 //将通用寄存器x29和x30的值存储到栈顶指针sp和sp+64指向的存储地址
ldp x29, x30, [sp], 16 //将栈顶指针sp和sp+64指向地址的数据分别保存到通用寄存器x29和x30中
  1. strb/ldrb指令
  • 操作对象:一个寄存器,操作数据size:一个字节(8位)。
strb w0, [sp, 31] //将通用寄存器w0的低8位的字节数据存储到sp+31指向的存储地址
ldrb w1, [sp, 31] //将栈顶指针sp+31指向地址的数据保存到通用寄存器w1的低8位,w1的高24位会被清零
  1. strh/ldrh指令
  • 操作对象:一个寄存器,操作数据size:两个字节(16位)。
strh w0, [sp, 30] //将通用寄存器w0的低16位的两个字节数据存储到sp+30指向的存储地址
ldrh w1, [sp, 31] //将栈顶指针sp+31指向地址的数据保存到通用寄存器w1的低16位,w1的高16位会被清零
  1. stur/ldur指令
  • 功能和str/ldr一样, 但是stur/ldur后面的立即数通常是负数。
ldur x1,[x0,#-1] //负数立即数
ldr x1,[x0,#1]   //正数立即数

伪指令

  • ldr既是一个汇编指令,也是一个伪指令的助记符,作为伪指令,其用于加载一个立即数或地址值到寄存器。
  • 语法
LDR{condition} register,=[expression | label-expression]

汇编指令/伪指令区分

  • 使用"[]“的是指令,使用”="的是伪指令,如下:
ldr x0, [sp, 8]  //汇编指令
ldr x4, =0x04140000 //伪指令,将地址0x04140000 保存(load)到x4中。

和mov指令区别

  • 伪指令ldr作用和mov指令比较类似,但是有些立即数,mov指令无法支持,如果mov能表示,替换成mov指令也是可以。

变址寻址方式

  • 使用str/ldr系列指令,有三种变址情况
  1. 自身不变化
ldr x5, [x6, #0x8]  //等同于 *x5 = *(x6 + 0x8),x6中的数据不变化
  1. 返回后变化
ldr x5, [x6], #0x8  //等同于 *x5 = *x6, x6 += 0x8,将x6指向地址的数据保存到x5,x6中的地址数据偏移8字节(+8)
  1. 返回前变化
ldr x5, [x6, #0x8]! //等同于 x6 += 0x8,*x5 = *x6,先将x6中的地址数据偏移8字节(+8),再取出其指向的数据到x5中
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值