arm64体系结构编程与实践

1、arm64体系结构基础知识

1.1 ARM v8 中的通用寄存器 零寄存器 系统寄存器 特殊寄存器 (XZR、WXR PC SP ) 功能 使用方法

1.2 PSTATE 寄存器中 NZCV DAIF EL 标志位含义

1.3 备份程序状态寄存器(Saved Program Status Register)

3、A64指令集 加载与存储指令 (第一位是寄存器,后面是内存或者立即数)

3.1 MOV STR LDR

`MOV X0, X1`会将X1的值复制到X0中,这里的目标寄存器是X0,源是X1

`MOV X0, #5`,目标寄存器同样是第一个操作数,立即数是第二个

`STR X0, [X1]`会将X0的值存储到X1寄存器所指向的内存地址。这里的目标是内存位置,源是寄存器X0


`MOV`是数据传输到寄存器,`STR`是传输到内存 


`LDR X0, [X1]`是将内存中的数据加载到X0

3.2 前变基模式,后变基模式

LDR X0, [X1, #8] //内存地址为X1寄存器的值加上8的偏移量, 加载此内存地址的值到X0寄存器LDR X0, [X1, #8]! //前变基模式。 先更新X1寄存器的值为X1寄存器的值加8, 然后以新的值
//加载该内存地址的值到X0寄存器
LDR X0, [X1], #8 //后变基模式。 以X1寄存器的值为内存地址, 加载该内存地址的值到X0寄存
//新X1寄存器的值为X1寄存器的值加8

3.4 加载和存储指令 、前变基模式 后变基模式

LDR 目标寄存器, <存储器地址> 

STR 源寄存器,<存储器地址>

前变基模式 : 先更新偏移量地址,后访问内存地址

后变基模式 : 先访问内存地址,后更新偏移量地址

3.4.1 多字节内存加载和储存指令

LDP <Xt1>, <Xt2>,[<Xn>|SP{,#<imm>}]

以 <Xn>|SP 为基地址,读取 <Xn>|SP{,#<imm>} 寄存器的值到  <Xt1> 寄存器中,读取X n /SP寄存器的值 + imm + 8地址的值到X t 2寄存器中

●X t 1: 目标寄存器1, 它对应指令编码中的R t 字段。 t 可以取0~30的整数。
●X t 2: 目标寄存器2, 它对应指令编码中的R t 2字段。 t 可以取0~30的整数。
●X n /SP: 用于基地址寄存器, 它对应指令编码中的R n 字段, 也可以使用SP寄存器。 n 可以取0~
30的整数。
●imm7: 偏移量, 该值必须是8的整数倍, 取值范围为-512~504。
 

STP <Xt1>, <Xt2>, [<Xn|SP>{, #<imm>}]
它以X n /SP寄存器的值为基地址, 然后把X t 1寄存器的内容存储到[X n /SP + imm]处, 把X t 2寄存
器的内容存储到[X n /SP + imm + 8]处。
 

3.4.4 独占内存访问指令

在A64指令集中, LDXR指令尝试在内存总线中申请一个独占访问的锁, 然后访问一个内存地址。 STXR指令会往刚才LDXR指令已经申请独占访问的内存地址中写入新内容。 LDXR和STXR指令通常组合使用来完成一些同步操作, 如Linux内核的自旋锁。

3.5 MOV指令


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

在寄存器之间搬移的 MOV 指令 : MOV <Xd|SP>, <Xn|SP>

用立即数搬移的 MOV 指令 : MOV <Xd>, #<imm>

3.6 加载和存储指令陷阱

3.6.1 怎么加载一个很大的立即数到通用寄存器

MOV 指令通常用于加载 16 位立即数,16位立即数左移16位 32位 或者48位后的立即数

 在遇到大数据比如 0xffff0000ffffffff 是,可以使用 LDR,伪指令来实现

#define BIG_DATA 0xFFFF0000FFFFFFFF

ldr x0, =BIGDATA

3.6.2 ldr 和 mov 指令的区别

MOV 用于在寄存器之间移动数据,或者将立即数加载到寄存器,但是立即数的范围有限

mov r0, #42     @ 将立即数 42 加载到 r0
mov r1, r2      @ 将 r2 的值复制到 r1

MOV 的限制是不能操作大立即数

ldr 用于在内存加载数据到寄存器,也可以用来加载大立即数(伪指令形式)

ldr{条件} 目标寄存器, [内存地址或标签]   @ 真实指令(内存加载)
ldr 目标寄存器, =立即数或地址         @ 伪指令(加载大立即数或地址)


ldr r0, =0x12345678   @ 加载大立即数到 r0
ldr r1, =main         @ 加载函数 main 的地址到 r1

4 A64指令集 算术和移位指令

PSTATE寄存器中有4个条件标志位, 即 N 、 Z 、 C、 V

4.1 ADD指令

ADD <Xd|SP>, <Xn|SP>, #<imm>{, <shift>}
 

add x0, x1, #1 //把x1寄存器的值加上立即数1, 结果写入x0寄存器中
add x0, x1, #1, LSL 12 //把立即数1算术左移12位, 然后再加上x1寄存器的值, 结果写入
 

add x0, x1, #4096
add x0, x1, #1, LSL 1
汇编器会报如下错误, 其中第一条语句中立即数超过了范围, 第二条语句中左移的位数只能是0或
者12。
 

4.1.2 使用寄存器的加法指令

add x0, x1, x2 //x0 = x1 + x2
add x0, x1, x2, LSL 2 //x0 = x1 + x2 << 2
 

4.2.2 ADDS指令

ADDS指令是ADD指令的变种, 唯一的区别是指令执行结果会影响PSTATE寄存器的 N 、 Z 、C、V 标志位, 例如当计算结果发生无符号数溢出时, C =1。

4.2 SUB 指令
 

4.3 CMP 指令

CMP指令用来比较两个数的大小。 在A64指令集的实现中, CMP指令内部调用SUBS指令来实现。
 

4.5 移位指令

● LSL: 逻辑左移指令, 最高位会被丢弃, 最低位补0, 如图4.10(a) 所示。
● LSR: 逻辑右移指令, 最高位补0, 最低位会被丢弃, 如图4.10(b) 所示

4.6 位操作指令

4.6.1 与操作指令

●AND: 按位与操作。
●ANDS: 带条件标志位的与操作, 影响 Z 标志位。


4.6.2 或操作指令

ORR <Xd|SP>, <Xn>, #<imm>
ORR <Xd>, <Xn>, <Xm>{, <shift> #<amount>}
 

4.6.3 异或指令

4.6.4 位清除指令

BIC <Xd>, <Xn>, <Xm>{, <shift> #<amount>}

BIC指令支持寄存器方式: 先对X m 寄存器的值做移位操作, 然后再与X n 寄存器的值进行位清除
操作。 BIC指令的参数说明如下。
●shift表示移位操作, 支持LSL、 LSR、 ASR以及ROR。
●amount表示移位数量, 取值范围为0~63。
 

5.比较指令与跳转指令

5.1 CMN 指令

CMN指令用来将一个数与另一个数的相反数进行比较
 

CMN <Xn|SP>, #<imm>{, <shift>}
CMN <Xn|SP>, <R><m>{, <extend> {#<amount>}}
上述两条CMN指令分别等同于如下的ADDS指令。
ADDS XZR, <Xn|SP>, #<imm> {, <shift>}
ADDS XZR, <Xn|SP>, <R><m> {, <extend> {#<amount>}}
 

5.2 返回指令 ret 和 ERET 的区别

RET指令: 通常用于子函数的返回, 其返回地址保存在LR里。
●ERET指令: 从当前的异常模式返回。 它会把SPSR的内容恢复到PSTATE寄存器中, 从ELR中获取跳转地址并返回到该地址。 ERET指令可以实现处理器模式的切换, 比如从EL1切换到EL0。
 

5.3 跳转指令

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值