arm64指令集-加载与储存
加载与存储指令
- 常见内存加载指令是LDR指令,储存指令是STR指令,基本格式如下:
- LDR 目标寄存器,<存储器地址> //把存储器地址中的数据加载到目标寄存器中
- STR 源寄存器,<存储器地址> //把源寄存器中的数据存储到存储器地址中
- 加载和存储指令的寻址模式:
寻址模式 | 描述 |
---|---|
基地址模式 | [Xn] |
基地址加偏移量模式 | [Xn,#offset] |
前变基模式 | [Xn,#offset]! |
后变基模式 | [Xn],#offset |
PC相对地址模式 | < label > |
- 基地址模式
- LDR Xt,[Xn] //以Xn寄存器中的数据作为内存地址,加载此地址中的数据到Xt寄存器
- STR Xt,[Xn] //以Xn寄存器中的数据作为内存地址,将Xt中的内容存储到此内存地址中
- 基地址加偏移量模式
- LDR Xt,[Xn,#offset] //以Xn寄存器中的数据加上offset的值作为一个内存地址,加载此地址中的数据到Xt寄存器
- STR Xt,[Xn,#offset] //以Xn寄存器中的数据加上offset的值作为一个内存地址,将Xt中的内容存储到此内存地址中
- 基地址扩展模式
- 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寄存器
- 前变基模式
- LDR < Xt >,[< Xn >, #< simm >]! //先更新Xn寄存器的值为Xn寄存器的值加simm,然后以新的Xn寄存器的值作为地址,加载该地址的数据到Xt寄存器
- 后变基模式
- LDR < Xt >,[< Xn >], #< simm > //首先以Xn寄存器的值作为地址,加载该地址的数据到Xt寄存器,然后更新Xn寄存器的值为Xn寄存器的值加simm
- 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指令集-加载与储存指令/