乐于分享
好东西不私藏

【学寄存器2】: 用《编码》+《CSAPP》双书视角,彻底读懂 CPSR/Status 标志位与中断位

【学寄存器2】: 用《编码》+《CSAPP》双书视角,彻底读懂 CPSR/Status 标志位与中断位

Hello,大家好,我是程序媛MM。

本文约1800字,今天按照前面帖子《零基础学ARM/MIPS寄存器:BSP底层必学路线》的计划,继续学习寄存器,ARM和MIPS前15个寄存器的用途直接去背就可以了。本文接着整理CPSR/Status寄存器 、标志位与中断屏蔽位相关知识。

我建了一个BSP学习交流群,想学BSP或者已经是BSP开发者可私信我,加入群,一起交流学习,共同进步。

关注公众号, 即可获得与Linux相关的电子书籍(含编码:隐匿在计算机软硬件背后的语言》)以及常用开发工具,文末有文档清单。


【书名注解】:

[1].《编码》,全称《编码:隐匿在计算机软硬件背后的语言》

[2].《CSAPP》(Computer Systems: A Programmer’s Perspective),中文译名《深入理解计算机系统》。

本文结合《编码》和《CSAPP》这两本书中对CPSR/Status 寄存器、标志位(

N/Z/C/V)、中断屏蔽位(I/F) 寄存器的描述来理解。不讲CPSR/Status 寄存器、标志位(N/Z/C/V)、中断屏蔽位(I/F)的抽象定义,只讲它是什么、为什么存在、怎么工作、在 BSP 里到底干嘛。

一 寄存器的具象理解


在《编码》里,作者告诉我们:

[1].计算机 = 一堆用电线连起来的开关

[2].寄存器 = 一组能记住 0/1 的开关组

那么 CPSR / Status 寄存器 是什么?

它是 CPU 面板上的 “状态指示灯面板”。

这块面板上有 8~32 个小灯泡,每个灯对应一个状态:

刚才的计算结果是正还是负?结果是 0 吗?刚才加法有没有进位?中断现在是开还是关?CPU 当前在什么模式(用户 / 内核 / 中断)?

CPSR 就是这块实时亮灯面板。

灯亮 = 1,灯灭 = 0。

总之,所有指令执行、异常触发、中断响应、模式切换,本质都是在操作这面板上的灯。

二 结合《CSAPP 》定位寄存器


CSAPP 第 3 章(程序的机器级表示)明确说:

CPU 除了通用寄存器,还拥有一组 “条件码”,用来记录最近一次运算的结果特征。

CPSR 就是 ARM 中条件码标志位N/Z/C/V)、控制位(中断使能、CPU 模式、大小端等)的统一存放处。

换句话说:

CPSR = 条件码 + 控制位 + 模式状态 的集合体。

三 CPSR 到底长什么样?(最清晰图示)


31 30 29 28 27  26  25  24  23  22  ...  8 7 6 5 4 3 2 1 0N  Z  C  V  Q  保留  J  保留   ...      I F T M[4:0]

我们只学 BSP 必须懂的 8 位,其他不用管。

四 标志位 N/Z/C/V


这 4 个灯每次运算后自动亮 / 灭,硬件自动更新,不需要写代码。

[1].N (Negative) 负标志

灯亮 = 结果最高位为 1 → 表示负数(有符号数)

像计算器上的 “负号指示灯”。

运算完自动亮/灭。

[2].Z (Zero) 零标志

灯亮 = 结果是 0

最常用:if (x == 0) 就是看 Z 位。

相当于 “结果 = 0” 指示灯。

[3].C (Carry) 进位 / 借位标志

加法有进位 → 亮灯

减法有借位 → 亮灯

相当于计算器的 “进位指示灯”。

在移位指令中,它保存被移出去的那一位。

[4].V (Overflow) 溢出标志

有符号数运算超出范围 → 灯亮

例如 0x7FFFFFFF + 1 = 负数

硬件自动亮灯报警。

五 最重要的两个控制位:I/F(中断开关)


这是启动、异常、驱动、锁中断 的命门。

I 位 (IRQ 中断屏蔽位)

I = 1 → 关中断(灯亮 = 屏蔽)I = 0 → 开中断(灯灭 = 允许)

具象理解:

I 位 = 家里大门的 “门铃屏蔽开关”。

按下(I=1)= 门铃不响

松开(I=0)= 门铃正常响

>>启动过程必须关中断

>>原子操作、临界区必须关中断

>>中断服务程序里自动被硬件设为 1

>>F 位 (FIQ 快速中断屏蔽位)

F = 1 → 关快速中断F = 0 → 开快速中断

FIQ 比普通中断优先级更高,硬件处理更快。

大多数 BSP 只需要关心 I 位。

六 M [4:0] —— CPU 模式


M 位就是 CPU 当前穿什么 “工作服”。

10000 = User 模式10001 = FIQ10010 = IRQ (中断模式)10111 = Abort11011 = Undefined11111 = SVC 模式(内核 / 特权级)

板子启动后默认进入 SVC(11111)

这就是为什么 U-Boot、内核一开始能操作所有硬件。

七 CPSR 在 BSP 中的 4 个核心作用(面试必问)


[1]. 条件跳转依靠 N/Z/C/V

BEQ → Z=1 跳BNE → Z=0 跳BGT → N=0,Z=0 跳

所有 if/else/while 底层都靠这 4 个灯。

[2]. 中断开关靠 I 位

CPSIE I ; 开中断CPSID I ; 关中断

驱动、调度、自旋锁、上下文切换都靠它。

[3]. 异常处理自动保存 CPSR

当中断 / 异常发生时,硬件自动:

把当前 CPSR 保存到 SPSR

设置 I=1 关中断

改变 M 位进入 IRQ 模式

跳去异常向量

这就是 BSP 异常处理的底层真相。

[4]. 判断运算结果是否正确

C/V 标志用来校验:

加法是否溢出

减法是否借位

移位是否移出有效位

八 一句话总结 CPSR


CPSR 就是 CPU 胸前的仪表盘:

4 个灯显示计算结果,

2 个开关控制门铃(中断),

5 位表示当前穿什么工作服。

程序的每一步行为,都由这几个灯和开关决定。

CPSR 包含了 CPU 的条件码控制状态是指令执行、分支预测、异常响应、权限管理、中断控制的核心。

所有高级语言的控制流与异常机制,最终都落脚在这个寄存器上。

九 只需要记住这 8 位


N = 结果负Z = 结果0C = 进位/借位V = 有符号溢出I = IRQ 中断屏蔽F = FIQ 中断屏蔽T = Thumb 状态M[4:0] = CPU 模式

以上为全文内容。

往期文章(欢迎订阅技术分享栏目全部文章):

【从零开始撸内核驱动源码】:以ttyserial(串口驱动)为例,串联字符设备驱动基础知识点的学习计划
Linux内核源码顶层 Makefile分析并单独编译调试内核自带的驱动
【从零开始撸内核驱动源码】:ttynull驱动
Linux内核驱动安装失败问题调试及解决方法
Linux内核驱动源码走读之编译内核及外部驱动实操指南

谢谢你看到这里

这里是女程序员的笔记本

 15年+嵌入式软件工程师兼二胎宝妈

分享读书心得、工作经验,自我成长和生活方式。

希望我的文字能对你有所帮助