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中

相关推荐

  1. ARMV8 - A64 - 存储器指令

    2023-12-07 18:08:02       31 阅读
  2. ARMV8 - A64 - 跳转和返回指令

    2023-12-07 18:08:02       29 阅读
  3. armv8-a 介绍

    2023-12-07 18:08:02       30 阅读

最近更新

  1. TCP协议是安全的吗?

    2023-12-07 18:08:02       18 阅读
  2. 阿里云服务器执行yum,一直下载docker-ce-stable失败

    2023-12-07 18:08:02       19 阅读
  3. 【Python教程】压缩PDF文件大小

    2023-12-07 18:08:02       18 阅读
  4. 通过文章id递归查询所有评论(xml)

    2023-12-07 18:08:02       20 阅读

热门阅读

  1. 记录一下npm包的关键字段

    2023-12-07 18:08:02       42 阅读
  2. TCP套接字编写

    2023-12-07 18:08:02       36 阅读
  3. pm2部署vue项目,Vue项目的部署在服务器

    2023-12-07 18:08:02       33 阅读
  4. StarRocks 存算分离最佳实践,让降本增效更简单

    2023-12-07 18:08:02       40 阅读
  5. STM32h7 接收各种can id情况下滤波器的配置

    2023-12-07 18:08:02       33 阅读
  6. 解决SpringBoot jar包下resources目录下文件读取不到

    2023-12-07 18:08:02       41 阅读
  7. Conda常用指令---(频率很高)

    2023-12-07 18:08:02       41 阅读
  8. 无图谱不AI之三元组数据保存Neo4j

    2023-12-07 18:08:02       29 阅读
  9. git-5

    git-5

    2023-12-07 18:08:02      31 阅读
  10. 【Appium】解决搜索输入框无搜索按钮

    2023-12-07 18:08:02       34 阅读
  11. Node.js 的 https 模块介绍

    2023-12-07 18:08:02       27 阅读