CPU内部结构窥探·「2」

从一条汇编加法指令出发,分析cpu内部发生了什么?

本文将详细剖析ARMv8架构中加法指令的执行过程,深入理解其在CPU上的运行机制。

ARMv8汇编基础

在ARMv8汇编语言中,加法指令ADD的基本格式如下:

assembly 复制代码
ADD destination, source1, source2

例如:

assembly 复制代码
ADD X0, X1, X2

这条指令将寄存器X1和X2中的值相加,并将结果存储到寄存器X0中。

加法指令的详细工作原理

ADD X0, X1, X2为例,详细剖析其在ARMv8架构的CPU上的执行过程。

1. 指令获取(Instruction Fetch)

指令获取是整个指令执行过程的第一步,主要涉及程序计数器(Program Counter, PC)和指令缓存(Instruction Cache, I-Cache)。

  • 程序计数器(Program Counter, PC) :保存当前执行指令的内存地址。假设当前PC的值为0x1000,表示正在获取存储在地址0x1000处的指令。
  • 指令缓存(Instruction Cache, I-Cache):高速缓存,从中读取指令以减少访问内存的延迟。

详细流程

  1. PC读取地址 :cpu将当前PC指向的地址0x1000发送到内存系统。
  2. 从I-Cache读取指令 :如果指令缓存中包含该地址的指令,则直接从I-Cache中读取ADD X0, X1, X2指令。否则,从主内存读取指令,并将其加载到I-Cache中。
  3. 加载到指令寄存器(Instruction Register, IR):指令被加载到指令寄存器IR中,准备进行下一步的译码。

2. 指令译码(Instruction Decode)

指令译码阶段,指令寄存器中的指令被送到指令译码单元(Instruction Decode Unit),并解析出操作码和操作数。

详细流程

  1. 解析操作码 :译码单元识别出这是一个ADD指令。
  2. 解析操作数:译码单元识别出涉及的寄存器:目标寄存器X0,源寄存器X1和X2。
  3. 生成控制信号:根据操作码和操作数生成控制信号,用于指导后续的操作数获取和指令执行。

3. 操作数获取(Operand Fetch)

在操作数获取阶段,CPU从寄存器文件中读取操作数,即X1和X2寄存器的值。

详细流程

  1. 寄存器地址:根据指令译码单元的解析结果,确定操作数寄存器的地址X1和X2。
  2. 读取寄存器文件(Register File):寄存器文件根据地址读取X1和X2中的值。例如,假设X1的值为5,X2的值为3。
  3. 传递给ALU:将读取到的操作数(5和3)传递给算术逻辑单元(ALU)。

4. 执行(Execution)

执行阶段,算术逻辑单元(ALU)进行实际的加法运算。

详细流程

  1. 输入操作数:ALU的输入端接收来自寄存器X1和X2的值,分别为5和3。
  2. 二进制加法 :ALU内部的加法器执行二进制加法操作:
    • 位加法 :每个位执行加法操作,并考虑进位。例如,第0位的加法为1 + 1 = 10(二进制),产生一个进位。
    • 进位传播:将进位传递到下一高位进行进一步加法。
  3. 结果生成:加法运算完成后,ALU输出寄存器中存储的结果为8。

5. 结果写回(Write Back)

在结果写回阶段,ALU的计算结果写回寄存器文件。

详细流程

  1. 结果输出:ALU将结果8输出到目标寄存器X0。
  2. 写回寄存器文件:将8写入寄存器文件中的X0寄存器。
  3. 更新寄存器状态:X0寄存器现在包含值8,更新寄存器文件的状态。

6. 更新程序状态寄存器(Update Program Status Register, PSR)

最后,更新程序状态寄存器(Program Status Register, PSR),以反映加法操作的状态。

详细流程

  1. 进位标志(Carry Flag, C):如果加法运算产生了进位,则设置进位标志。
  2. 溢出标志(Overflow Flag, V):如果加法运算产生了符号位错误,则设置溢出标志。
  3. 零标志(Zero Flag, Z):如果加法结果为零,则设置零标志。
  4. 负数标志(Negative Flag, N):如果加法结果为负数,则设置负数标志。

具体示例

为了更清晰地说明,让我们看一个具体的示例代码片段及其执行过程:

assembly 复制代码
MOV X1, #5      ; 将立即数5加载到X1寄存器
MOV X2, #3      ; 将立即数3加载到X2寄存器
ADD X0, X1, X2  ; 将X1和X2中的值相加,并将结果存储到X0中

执行步骤如下:

  1. MOV X1, #5

    • 指令获取 :从内存中获取指令MOV X1, #5
    • 指令译码 :解析出这是一个MOV指令,将立即数5加载到X1寄存器。
    • 操作数获取:立即数5。
    • 执行:将5写入X1寄存器。
    • 结果写回:X1寄存器现在包含5。
  2. MOV X2, #3

    • 类似步骤1,将3加载到X2寄存器。
  3. ADD X0, X1, X2

    • 指令获取 :获取指令ADD X0, X1, X2
    • 指令译码 :解析出这是一个ADD指令,涉及X0、X1和X2寄存器。
    • 操作数获取:读取X1和X2寄存器的值,分别为5和3。
    • 执行:ALU执行加法运算,5 + 3 = 8。
    • 结果写回:将结果8写回X0寄存器。此时,X0寄存器包含8。
    • 更新程序状态寄存器:根据结果8更新程序状态寄存器中的条件标志。

小结

了解汇编指令的执行过程对于深入理解计算机体系结构和优化程序性能具有重要意义。希望这篇博客能帮助你更好地理解ARMv8架构下汇编指令加法操作的运行机制。如果有任何疑问或需要进一步探讨,欢迎在评论区留言!

相关推荐
创龙科技-黄工16 小时前
【深度剖析】自主可控的全国产方案,基于龙芯LS2K1000LA-i!
arm·龙芯·工业核心板·国产处理器
シ風箏2 天前
Neo4j【环境部署 02】图形数据库Neo4j在Linux系统ARM架构下的安装使用
linux·数据库·arm·neo4j
徐某人..5 天前
ARM嵌入式学习--第八天(PWM)
arm开发·学习·arm
徐某人..5 天前
ARM嵌入式学习--第七天(GPT)
学习·arm
Crossoads9 天前
【汇编语言】内中断(二) —— 安装自己的中断处理程序:你也能控制0号中断
android·开发语言·数据库·人工智能·深度学习·机器学习·汇编语言
whik11949 天前
Keil-MDK开发环境编译后axf自动转换bin格式文件
stm32·arm·keil·axi·bin·mdk
编程零零七10 天前
【Python】tensorflow中的argmax()函数
开发语言·python·信息可视化·数据分析·arm·python学习·python数据可视化
嵌入式小能手13 天前
shell编程入门之提取字符并设置rtc时间
linux·单片机·嵌入式硬件·arm
爱喝纯牛奶的柠檬17 天前
基于stm23的智慧宿舍系统 (DAY10)_小程序
stm32·嵌入式硬件·物联网·阿里云·小程序·arm
嵌入式小能手17 天前
自动化点亮LED灯之shell点灯
linux·单片机·嵌入式硬件·arm