浅析ARMv8体系结构:程序运行寄存器
2026/7/6 21:34:13 网站建设 项目流程

文章目录

    • 概述
    • 通用寄存器
    • 程序状态寄存器
      • NZCV标记位
    • 特殊寄存器
      • PC寄存器
      • SP寄存器
      • SPSR寄存器
      • 异常链接寄存器(ELR)
      • CurrentEL寄存器
      • SPSel寄存器
      • DAIF寄存器
      • NZCV寄存器
      • PAN寄存器
      • UAO寄存器
      • 零寄存器
    • 系统寄存器
    • 相关参考

概述

ARM体系架构下,程序运行依赖一系列的寄存器,用于记录运行状态、过程数据以及系统配置等,这些寄存器大体可分为以下几个类别:

  • 通用寄存器
  • 程序状态寄存器
  • 特殊寄存器
  • 系统寄存器。

通用寄存器

AArch64运行状态支持31个64位的通用寄存器,分别是X0~X30寄存器,而AArch32状态支持16个32位的通用寄存器。通用寄存器除了用于数据运算和存储之外,还可以在函数调用过程中起到特殊作用,ARM64架构的函数调用标准和规范对此有所约定。

在AArch64状态下,使用X来表示64位通用寄存器,如X0、X30等。另外,还可以使用W来表示低32位的数据,如W0表示X0寄存器的低32位数据,W1表示X1寄存器的低32位数据

通用寄存器中有2个相对特殊的寄存器X29和x30,主要用于函数调用过程,其中:

  • X29:栈帧寄存器,可以通过别名FP进行引用,用于记录函数调用栈帧的基地址;
  • X30:链接寄存器,可以通过别名LR进行引用,用于保存函数调用的返回地址。

程序状态寄存器

在AArch64里使用PSTATE寄存器来表示,准确来说PSTATE并不是单一的寄存器,而是一系列系统状态的组合。

PSTATE状态通常是通过其它特殊的系统寄存器进行访问,包括CurrentEL、DAIF、SPSel、PAN、UAO以及NZCV寄存器,这些寄存器可以通过指令MRS/MSR进行访问和操作。

NZCV标记位

标志全称含义触发条件
ZZero结果全0运算输出所有bit=0,Z=1;否则0
NNegative结果最高位运算结果最高bit(bit63/X, bit31/W)=1 → N=1;视作有符号负数
CCarry进位/借位(无符号溢出)ADD:最高位产生进位;SUB:最高位产生借位
VOverflow有符号补码溢出两个同符号数相加,结果符号反转;两异号数相减等价同号相加溢出
  1. C 只管无符号溢出(纯二进制进位,和正负无关)
  2. V 只管补码有符号溢出(符号位出错)
  3. N/Z 只是结果属性,和溢出无关

特殊寄存器

ARMv8架构除了支持31个通用寄存器之外,还提供多个特殊的寄存器:

PC寄存器

PC寄存器通常用来指向当前运行指令的下一条指令的地址,用于控制程序中指令的运行顺序,ARM不支持通过指令来直接访问它,但使用分支跳转和返回指令可以间接改变。

SP寄存器

ARMv8架构支持4个异常等级,每一个异常等级都有一个专门的SP寄存器SP_ELn,存放当前异常等级下程序运行使用的栈地址,如处理器运行在EL1时选择SP_EL1寄存器作为SP寄存器。

  • SP_EL0:EL0下的SP寄存器。
  • SP_EL1:EL1下的SP寄存器。
  • SP_EL2:EL2下的SP寄存器。
  • SP_EL3:EL3下的SP寄存器。

当处理器运行在比EL0高的异常等级时,处理器可以访问如下寄存器。当前异常等级对应的SP寄存器SP_ELn。
EL0对应的SP寄存器SP_EL0可以当作一个临时寄存器,如Linux内核里使用该寄存器存放进程的task_struct数据结构的指针。
当处理器运行在EL0时,它只能访问SP_EL0,而不能访问其他高级的SP寄存器。

SPSR寄存器

当CPU进入异常处理时,硬件会自动把当前CPU的程序状态保存到SPSR(Saved Process Status Register)寄存器中。SPSR寄存器内容定义如下:

当异常将要发生时,CPU会把PSTATE的值暂时保存到SPSR里;当异常处理完成并返回时,CPU再把SPSR的值恢复到PSTATE。

异常链接寄存器(ELR)

ELR寄存器用于存放异常返回地址。当处理器发生异常时,会将异常返回地址保存在异常级别对应的ELR寄存器中。AArch64位每个异常级别都提供了ELR寄存器。

CurrentEL寄存器

CurrentEL寄存器用于访问PSTATE寄存器中的EL字段,EL保存了当前任务运行的异常等级,使用MRS指令可以读取当前异常等级:

MRS X0, CurrentEL

其中:

  • 0:表示EL0;
  • 1:表示EL1;
  • 2:表示EL2;
  • 3:表示EL3。

SPSel寄存器

SPSel寄存器用于访问PSTATE寄存器中的SP字段,用于ELx异常等级(不包括EL0)选择SP寄存器,可以是SP_EL0或SP_ELx。

当PSTATE.SPSel = 0时,CPU使用SP_EL0作为当前任务的堆栈寄存器;反之则使用与异常等级对应的SP寄存器。

DAIF寄存器

DAIF寄存器用于访问PSTATE寄存器中的{D, A, I, F}字段,用于异常、中断以及调试开关控制。

NZCV寄存器

NZCV寄存器用于访问PSTATE寄存器中的{N, Z, C, V}字段。

PAN寄存器

PAN寄存器用于访问PSTATE寄存器中的PAN(Privileged Access Never,特权禁止访问)字段。

UAO寄存器

UAO寄存器用于访问PSTATE寄存器中的UAO(User Access Override,用户访问覆盖)字段。

零寄存器

ARMv8架构提供两个零寄存器(zero register),这些寄存器的内容全是0,可以用作源寄存器,也可以用作目标寄存器。WZR寄存器是32位的零寄存器,XZR是64位的零寄存器。

系统寄存器

除了上面介绍的通用寄存器和特殊寄存器之外,ARMv8架构还定义了很多的系统寄存器,通过访问和设置这些系统寄存器来完成对处理器不同的功能配置。在ARMv7架构里,我们需要通过访问CP15协处理器来间接访问这些系统寄存器,而在ARMv8架构中没有协处理器,可直接访问系统寄存器。ARMv8架构支持如下7类系统寄存器:

  • 通用系统控制寄存器
  • 调试寄存器
  • 性能监控寄存器
  • 活动监控寄存器
  • 统计扩展寄存器
  • RAS寄存器
  • 通用定时器寄存器

系统寄存器支持不同的异常等级的访问,通常系统寄存器会使用Reg_ELn的方式来表示:

  • Reg_EL1:处理器处于EL1、EL2以及EL3时可以访问该寄存器。
  • Reg_EL2:处理器处于EL2和EL3时可以访问该寄存器。

大部分系统寄存器不支持处理器处于EL0时访问,但也有一些例外,如CTR_EL0寄存器。

相关参考

  • 《奔跑吧,Linux内核》
  • 《ARM64体系结构编程与实践》
  • PSTATE.SPSel, SP_EL0的实际使用

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询