一、寄存器种类
通用寄存器:x0-x30 或 w0-w30 (共31个)
特殊寄存器:程序寄存器(pc)
堆栈寄存器(sp)
链接寄存器(LR)
零寄存器(WZR/XZR)
二、寄存器详解
通用寄存器
arm64v8-A是64位的架构,每一个寄存器都是64位的,但允许使用寄存器中的低32位进行处理,目的应该是为了在处理低精度数据的时候不操作高32位而降低能耗和时间。
所以通用寄存器在使用64位的时候,其组织形式是x0-x30,而使用32位的时候,组织形式是w0-w30。程序在进行编译的时候,会根据程序中需要处理的数据类型,自动的使用更优的寄存器位数,比如在处理int类型的时候,会自动使用w类型寄存器,一般不会使用x类型寄存器。
特殊寄存器
上述所说的31个通用寄存器中有部分寄存器是有特殊功能的。
pc寄存器:用来保存当前程序指令的地址,保证程序能够按照我们设计的程序逻辑和顺序执行。
sp寄存器:sp是栈寄存器,该寄存器用来存储当前栈空间的栈顶指针,并且sp寄存器可以通过减操作进行栈的开辟,通过加操作进行栈的释放(因为栈空间是从高地址到低地址延伸的,所以减是开辟栈空间,加是释放栈空间)。另外,sp寄存器其实也是x31寄存器,在编译出来的汇编程序当中,不会被表示为x31,而是sp。
LR寄存器:链接寄存器,也就是x30寄存器。用来保存函数调用者的当前的运行指令,当调用函数执行完毕后,通过LR寄存器技能够成功跳转回来继续向下执行。
零寄存器:WZR表示低32位的零寄存器,XZR表示64位的零寄存器。零寄存器最大的功能应该是对其他寄存器进行传值。零寄存器存储的值默认是0,当对零寄存器进行读操作时,读取到的数据是0,当对零寄存器进行写操作时,会忽略写操作,所以零寄存器可以当做是一个只读的寄存器,并且只读的数据是0;
NEON寄存器
neon寄存器总共有32个(v0-v31),每一个寄存器有128位,能够以向量的形式并行处理多个数据。
————————————————————————
补充说一下在之前学习中没有理解透彻的一点东西
在每一个函数开始的时候,都会有一条指令是用来将x29和x30寄存器压入栈的。那么这两个寄存器当中存储的是什么呢?
其实x29寄存器的作用是用来调用管理函数局部变量的一个寄存器。x29寄存器也叫做栈帧寄存器。在main函数中调用func函数时的流程是:main函数中先stp x29,x30 [sp,-16],将main函数调用者的局部变量和返回地址压入栈,然后add x29 sp,0语句将新的栈顶赋给x29,从这里开始才是对main函数中的局部变量的管理。类似的,在面函数调用func函数时,func函数首先是stp x29,x30 [sp,-16]将main函数的最后的局部变量信息和返回地址压入栈,然后add x29 sp,0后才开始维护func函数的局部变量。
在每一个函数调用返回前,会先释放掉栈空间,然后返回调用者的x29,x30,最后根据x30的返回地址返回。