arm64指令集-加载与储存

加载与储存指令

加载与存储指令

  • 常见内存加载指令是LDR指令,储存指令是STR指令,基本格式如下:
    • LDR 目标寄存器,<存储器地址> //把存储器地址中的数据加载到目标寄存器中
    • STR 源寄存器,<存储器地址> //把源寄存器中的数据存储到存储器地址中
  • 加载和存储指令的寻址模式:
寻址模式 描述
基地址模式 [Xn]
基地址加偏移量模式 [Xn,#offset]
前变基模式 [Xn,#offset]!
后变基模式 [Xn],#offset
PC相对地址模式 < label >
  1. 基地址模式
    • LDR Xt,[Xn] //以Xn寄存器中的数据作为内存地址,加载此地址中的数据到Xt寄存器
    • STR Xt,[Xn] //以Xn寄存器中的数据作为内存地址,将Xt中的内容存储到此内存地址中
  2. 基地址加偏移量模式
    • LDR Xt,[Xn,#offset] //以Xn寄存器中的数据加上offset的值作为一个内存地址,加载此地址中的数据到Xt寄存器
    • STR Xt,[Xn,#offset] //以Xn寄存器中的数据加上offset的值作为一个内存地址,将Xt中的内容存储到此内存地址中
  3. 基地址扩展模式
    • LDR < Xt >, [< Xn >,(< Xm >){,< extend >{< amount >}}]
    • STR < Xt >, [< Xn >,(< Xm >){,< extend >{< amount >}}]
      • Xt:目标寄存器
      • Xn:基地址寄存器
      • Xm:表示偏移的寄存器
      • extend:扩展/移位指示符,默认LSL,可选LSL、UXTW、SXTW、SXTX
      • amount:索引偏移量,只能为#0或者#3
    • LDR X0, [X1, X2] //内存地址为X1的值加上X2的值,将此内存地址中的值加载到X0寄存器
    • LDR X0, [X1, X2, LSL #3] //内存地址为X1的值加上(X2的值<<3),将此内存地址中的值加载到X0寄存器
    • LDR X0, [X1, W2 SXTW] //先对W2中的值做有符号扩展,再和X1的值相加,结果作为内存地址,将此内存地址中的值加载到X0寄存器
  4. 前变基模式
    • LDR < Xt >,[< Xn >, #< simm >]! //先更新Xn寄存器的值为Xn寄存器的值加simm,然后以新的Xn寄存器的值作为地址,加载该地址的数据到Xt寄存器
  5. 后变基模式
    • LDR < Xt >,[< Xn >], #< simm > //首先以Xn寄存器的值作为地址,加载该地址的数据到Xt寄存器,然后更新Xn寄存器的值为Xn寄存器的值加simm
  6. PC相对地址模式
    • LDR < Xt >, < label > //读取label所在内存地址的内容到Xt寄存器中,label地址必须在当前PC前后1M的地址范围内
    • ```s
      my_data:
      .word 0x40
      ldr x0, my_data
      //将my_data标签中的数据0x40载入x0寄存器
      1
      2
      3
      4
      -    ```s
      #define MY_LABEL 0x20
      ldr x6, MY_LABEL
      //以当前PC的值加上0x20作为内存地址,将此地址中的值载入x6寄存器中

出栈与入栈

armv8取消了push与pop指令,使用ldr和str指令完成出入栈的操作

  • 入栈
    • str x29,[sp,#-8]!
    • 前变基 首先sp的值减8,栈空间是向下增长,也就是新增8byte的栈空间,然后将x29的值写入当前sp指针指向的地址处,也就是栈顶
  • 出栈
    • ldr x29,[sp],#8
    • 后变基 首先将sp的值指向的内存中的数据存入x29,然后sp的值加8,也就是释放8byte的栈空间

MOV指令

mov指令用于寄存器之间的搬移和立即数搬移

  • mov < Xd >, < Xn >

  • mov < Xd >, #< imm >

    • 立即数只能为16位的立即数或者16位立即数左移16位、32位、48位后的立即数

arm64指令集-加载与储存
http://example.com/2022/11/21/arm64指令集-加载与储存指令/
作者
Hector
发布于
2022年11月21日
许可协议