ARM64寄存器
ARM64有34个寄存器,包括31个通用寄存器、SP、PC、CPSR
- 通用寄存器可以使用64位或者低32位
ARM64中有31个64位的通用寄存器,即x0-x30,低32位用Wn表示。读Wn寄存器时会保持Xn寄存器的高32位不变,如果写Wn寄存器时,会将Xn寄存器的高32位设为0。
63 32 31 0
|--------------------|--------------------|
| | |
|--------------------|--------------------|
|---------Wn---------|
|-------------------Xn--------------------|
- 通用寄存器作用如下:
- 通用寄存器中x0-x7:一般用于传递子程序参数和结果,使用时不需要保存,多余参数采用堆栈传递,其中x0/w0用于保存函数返回结果,64位返回结果采用x0表示,128位返回结果采用x1:x0表示。
- 通用寄存器中x8:用于保存子程序返回地址, 尽量不要使用 。
- 通用寄存器中x9~x15:临时寄存器,使用时不需要保存。
- 通用寄存器中x16~x17:子程序内部调用寄存器,使用时不需要保存,尽量不要使用。
- 通用寄存器中x18:平台寄存器,它的使用与平台相关,尽量不要使用。
- 通用寄存器中x19~x28:临时寄存器,使用时必须保存。
- 通用寄存器中x29:一般用作栈基址寄存器,习惯上称为栈帧指针fp (frame pointer),栈顶寄存器为sp(stack pointer )不是通用寄存器,是特殊的寄存器。
- 通用寄存器中x30:x30寄存器是lr (Link Register) ,用于保存跳转指令的下一条指令的内存地址,比如 bl 指令。
读写指令
str & ldr
用于寄存器和内存之间传数据
str x0, [sp] //x0->sp寄存器指向的内存位置 用于将寄存器数据存入内存
ldr x0, [sp] //x0<-sp寄存器指向的内存位置 用于将内存数据加载到寄存器
三种变址寻址方式
ldr x5, [x6, #0x8] // => *x5 = *(x6 + 0x8) 前变址
ldr x5, [x6], #0x8 // => *x5 = *x6, x6 += 0x8 回写 后变址
ldr x5, [x6, #0x8]! // => *x5 = *(x6 + 0x8), x6 += 0x8 回写 前变址
stp & ldp 出入栈指令
ARM64中栈空间以16字节(128bit)作为一个存储单元,而stp和ldp指令可以同时操作两个寄存器,所以出入栈一般用stp和ldp指令实现
stp x29, x30, [sp, #-16]! //入栈(压栈)
ldp x29, x30, [sp], 16 //出栈
mov指令
只能用于在寄存器之间传递数据
mov x1, x0 // x1 <- x0
数学运算
加减法
add x0, x1, x2 // *x0 = *x1 + *x2
sub x0, x1, x2 // *x0 = *x1 - *x2
跳转与返回
带返回的跳转
bl ffff000008dc566c
//下一条指令
先把下一条指令的地址
放在寄存器lr(x30)中,再跳转到ffff000008dc566c
调用ret指令会把lr寄存器的值放在PC寄存器里,从而跳转回下一条指令
ret返回指令
ret
负载将寄存器lr(x30)的值放入PC寄存器
注意:PC寄存器的值不能直接改写,但可以用ret指令间接改写
系统调用 SVC指令(异常处理类指令)
···待补充···
参考资料
https://blog.csdn.net/weixin_43549265/article/details/121993888