一文搞懂 ARM 64 系列: 寄存器

ARM 64中包含多种寄存器,下面介绍一些常见的寄存器。

1 通用寄存器

ARM 64包含3164bit寄存器,记为X0~X30

每一个通用寄存器,它的低32bit都可以被访问,记为W0~W30

在这31个通用寄存器中,有2个寄存器比较特殊。

X29寄存器被作为栈帧寄存器,也被称为FP(Frame Pointer Register)

X30寄存器被作为函数返回地址寄存器,也被称为LR(Link Register)

下面从一个例子来看X29寄存器与X30寄存器的作用。

c 复制代码
// ARMAssemble`-[ViewController viewDidLoad]:
0x104e94000 <+0>:  sub    sp, sp, #0x30
0x104e94004 <+4>:  stp    x29, x30, [sp, #0x20]
0x104e94008 <+8>:  add    x29, sp, #0x20
...

上面代码是一个VC viewDidLoad汇编方法的开头部分。

代码第1行将栈寄存器SP的值减少0x30,也就是开辟了0x30的栈空间。

代码第2行将寄存器X29与寄存器X30存入(sp + 0x20)指向的地址。

代码第3行将(SP + 0x20)这个地址值写入寄存器X29,形成新的栈帧FP

从上图可以看到新FP存储在寄存器X29,而上一个栈帧FP的值被存入到地址(SP + 0x20)。这样,随着函数一层一层调用,栈帧也被串联起来。

对于寄存器X30,可以使用image lookup -a命令查看其存储的地址0x1c43df260代表的含义:

c 复制代码
(lldb) p/x $x30
(unsigned long) 0x00000001c43df260
(lldb) image lookup -a $x30
      Address: UIKitCore[0x0000000189353260] (UIKitCore.__TEXT.__text + 3665488)
      Summary: UIKitCore`-[UIViewController _sendViewDidLoadWithAppearanceProxyObjectTaggingEnabled] + 84

从输出看到,这个地址位于函数-[UIViewController _sendViewDidLoadWithAppearanceProxyObjectTaggingEnabled]中,正是这个函数调用了-[UIViewController viewDidLoad]。寄存器X30存储的地址0x1c43df260正是viewDidLoad函数返回后,要执行的指令地址:

c 复制代码
// UIKitCore`-[UIViewController _sendViewDidLoadWithAppearanceProxyObjectTaggingEnabled]:
...
0x1c43df25c <+80>:  bl     0x18a7b7e80 ; objc_msgSend$viewDidLoad
// X30 的地址指向这行代码
0x1c43df260 <+84>:  mov    x0, x19

上面代码第1行调用函数-[UIViewController viewDidLoad]

代码第2行就是函数-[UIViewController viewDidLoad]返回后要执行的指令,其地址正好是0x1c43df260

2 SP

SP是栈顶指针寄存器,类似Intel 64中的RSP寄存器。

3 PC

PC寄存器存储当前要执行的指令地址,类似Intel 64中的RIP寄存器。

c 复制代码
// ARMAssemble`-[ViewController viewDidLoad]:
->  0x104e94000 <+0>:  sub    sp, sp, #0x30
    0x104e94004 <+4>:  stp    x29, x30, [sp, #0x20]
    ...

上面代码第1行,正要执行0x104e94000地址处指令,打印寄存器PC的值,也正好是0x104e94000:

c 复制代码
(lldb) p/x $PC
(unsigned long) 0x0000000104e94000

4 SIMD&FP 寄存器

SIMD是单指令多数据的缩写(Signle Instruction,Multiple Data),FP代表浮点数(Float Point)。

SIMD&FP寄存器有32个,记为V0~V31,每一个寄存器都是128bit

当访问SIMD&FP寄存器的全部128bit时,它们也可以被记为Q0~Q31

当访问SIMD&FP寄存器的低64bit时,它们被记为D0~D31,此时也是被当成浮点数寄存器使用。

当访问SIMD&FP寄存器的低32bit时,它们被记为S0~S31

当访问SIMD&FP寄存器的低16bit时,它们被记为H0~H31

当访问SIMD&FP寄存器的低8bit时,它们被记为B0~B31

如果一条指令包含寄存器Vn,寄存器Vn同时存储比如432bit数据,这样一条指令就包含了4个数据,也就是所谓的单指令多数据SIMD应用场景。

在矩阵运算中,常常能看到SIMD的应用。

5 Z 寄存器

Z寄存器也就是标量向量寄存器(Scalable Vector Register)。

ARM 64中有32Z寄存器,Z寄存器最低可以有128bit,最高有2048bit。具体长度有处理器实现决定。

如果Z寄存器的长度是128bit,那么它其实就是一个SIMD&FP寄存器。

相关推荐
一枝小雨4 天前
ARM异常处理流程与中断机制总结,与常见丢中断情况
arm开发·嵌入式硬件·架构·系统架构·arm
亿道电子Emdoor7 天前
【ARM】MDK-解决中文注释的乱码问题
arm开发·stm32·单片机·arm·mdk
亿道电子Emdoor8 天前
【ARM】MDK-解决单机版LIC获取报错
arm开发·stm32·单片机·arm
Invinciblenuonuo11 天前
STM32八股【1】-----启动流程和startup文件理解
stm32·arm
单车少年ing13 天前
stressapptest交叉编译(ARM64)
linux·arm64
亿道电子Emdoor1 个月前
【ARM】DS如何查看工程的堆栈使用情况
arm开发·stm32·单片机·arm
toradexsh1 个月前
ARM 处理器平台 eMMC Flash 存储磨损测试示例
linux·arm·nxp·toradex·emmc
CYRUS STUDIO1 个月前
使用 AndroidNativeEmu 调用 JNI 函数
android·汇编·arm开发·arm·逆向·jni
小虾米的Daddy2 个月前
ARM64 Trust Firmware [一]
linux·arm·安全架构
世事如云有卷舒2 个月前
《ARM64体系结构编程与实践》学习笔记(三)
笔记·学习·arm