ESC
输入关键词搜索文章标题和内容

CPU是怎么执行0和1的?看完这篇你就懂了

本文由 linuxROS 整理发布,首发于 linuxros.cn,转载请注明出处。

CPU是怎么执行0和1的?看完这篇你就懂了

导读:程序烧录进单片机后,CPU如何执行这些0和1?本文详解CPU四步工作流程、程序启动完整过程,用生活化类比+具体指令执行,带你理解最硬核的嵌入式底层。适合嵌入式开发者、STM32学习者、想深入理解计算机底层的工程师。


原理简析

在嵌入式系统中,C/C++程序经过编译、汇编、链接后,生成二进制代码烧录到Flash存储器。CPU上电后,从这些看似无序的0和1中提取指令执行,遵循严格的硬件逻辑。

CPU核心工作就是取指令、译指令、执行指令,周而复始,永不停歇。现代CPU主频已达GHz级别,每秒可执行几十亿次循环。

CPU四步工作流程

CPU执行指令遵循"取指→译码→执行→写回"四步流程。用"仓库管理"类比:

硬件组件 生活比喻 作用说明
Flash 档案室 持久化存储程序代码
RAM 工作台 临时存放变量和数据
CPU 仓库管理员 执行指令的核心
寄存器 管理员的小本子 快速暂存数据
PC寄存器 待办清单 记录下一条指令位置
flowchart TD A[取指<br/>PC→Flash→IR] --> B[译码<br/>IR→译码器] B --> C[执行<br/>ALU运算] C --> D[写回<br/>结果→寄存器/内存] D -->|PC+4| A

取指:CPU从PC寄存器读取指令地址,去Flash读取指令到IR寄存器,PC自动加4。

译码:译码器把二进制机器码翻译成操作码和操作数,生成控制信号。

执行:控制单元指挥各部件工作,ALU负责运算,访存指令访问内存,跳转指令修改PC。

写回:结果写入寄存器或内存,更新状态标志寄存器。

存储系统对比

存储器类型 读取速度 写入速度 容量 成本
寄存器 1周期 1周期 几KB 极高
SRAM 10-100周期 10-100周期 几百KB 高
Flash 100-1000周期 极慢 几MB 低

实操步骤

STM32程序启动完整流程

flowchart LR A[上电复位] --> B[读取中断向量表<br/>0x08000000] B --> C[初始化MSP<br/>栈指针] C --> D[跳转变量服务程序<br/>0x08000004] D --> E[调用__main<br/>初始化.data/.bss段] E --> F[跳转到main<br/>程序开始]

Bootloader地址配置:

来自 linuxros.cn · linuxROS
地址 内容 说明
0x08000000 栈顶指针MSP 临时工作台位置
0x08000004 复位服务程序入口 开业专家位置

启动步骤详解:

  1. 上电复位:按下电源键,CPU被唤醒,准备工作
  2. 读取向量表:CPU自动访问0x08000000,获取栈顶和复位入口
  3. 初始化栈指针:MSP寄存器设置,栈空间就绪
  4. 找到复位服务程序:跳转到0x08000004执行
  5. 调用__main:初始化.data段(从Flash复制初值到RAM)和.bss段(清零未初始化变量)
  6. 跳转到main:用户程序开始运行

代码实现

启动文件分析(startup_stm32f10x_md.s)

; 版本:ST官方启动文件 v1.8.5
; 依赖:ARMCC编译器

    AREA    RESET, DATA, READONLY
    EXPORT  __Vectors
__Vectors
    DCD     __initial_sp               ; 栈顶指针
    DCD     Reset_Handler              ; 复位服务程序
    DCD     NMI_Handler                ; NMI中断
    DCD     HardFault_Handler          ; 硬fault中断

    AREA    |.text|, CODE, READONLY

Reset_Handler    PROC
    EXPORT  Reset_Handler             [WEAK]
    IMPORT  __main
    IMPORT  SystemInit

    LDR     R0, =SystemInit
    BLX     R0                          ; 调用SystemInit初始化系统时钟
    LDR     R0, =__main
    BX      R0                          ; 跳转到__main
    ENDP

    END

主程序代码(main.c)

// 版本:v1.0
// 依赖:STM32F10x Standard Peripheral Library v3.6.0

#include "stm32f10x.h"

// 全局变量(将被放在.data段)
uint32_t g_counter = 0;

// 未初始化全局变量(将被放在.bss段)
uint32_t g_uninitialized_var;

void LED_Init(void)
{
    GPIO_InitTypeDef GPIO_InitStructure;

    // 使能GPIOC时钟
    RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOC, ENABLE);

    // 配置PC13为推挽输出
    GPIO_InitStructure.GPIO_Pin = GPIO_Pin_13;
    GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;
    GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
    GPIO_Init(GPIOC, &GPIO_InitStructure);
}

int main(void)
{
    LED_Init();

    while(1)
    {
        // LED翻转
        GPIO_WriteBit(GPIOC, GPIO_Pin_13, (BitAction)(1 - GPIO_ReadOutputDataBit(GPIOC, GPIO_Pin_13)));

        // 延时
        for(volatile uint32_t i = 0; i < 0xFFFFF; i++);

        // 计数器递增
        g_counter++;
    }
}

汇编指令执行示例

; 示例:add eax, ebx 指令的机器码
; 机器码:00000001 11011000
; 执行前:eax = 5, ebx = 3, PC = 0x08000100

四步执行过程:

步骤 操作内容 寄存器变化
取指 从PC=0x08000100读取指令到IR IR=0x01D8, PC=0x08000104
译码 译码器解析出add指令 控制单元生成控制信号
执行 ALU计算5+3=8 ALU输出=8
写回 将8写入eax eax=8, 状态寄存器更新
sequenceDiagram participant PC as PC寄存器 participant Flash as Flash存储器 participant IR as IR寄存器 participant Decoder as 译码器 participant ALU as ALU运算器 participant Reg as 通用寄存器 PC->>Flash: 发送地址0x08000100 Flash->>IR: 返回指令0x01D8 IR->>Decoder: 传入机器码 Decoder->>ALU: 发出add指令 Reg->>ALU: 读取eax=5, ebx=3 ALU->>ALU: 计算5+3=8 ALU->>Reg: 写回eax=8

常见问题解决

Q1:为什么程序要先从Flash复制到RAM?不能直接在Flash运行?
A:可以直接在Flash运行(XIP原地执行),但Flash读取速度比RAM慢很多,而且Flash只读,变量需要在RAM中修改。

Q2:什么是"栈"?它有什么用?
A:栈是LIFO内存区域,采用"后进先出"方式,存储函数调用返回地址、局部变量和临时数据,保证程序嵌套调用正确返回。

Q3:为什么CPU能看懂0和1?
A:CPU看不懂0和1!它看到的是电平信号——高电平(3.3V)代表1,低电平(0V)代表0。CPU内部是无数逻辑门,通过组合实现各种运算和控制。


技术参数参考

CPU核心参数

参数名称 典型数值范围 说明 来源
时钟频率 8MHz - 1GHz 决定CPU执行速度 ARM Cortex-M系列手册
指令周期 1 - 若干时钟周期 执行一条指令所需时间 芯片数据手册
寄存器位宽 8/16/32/64位 一次能处理的数据位数 CPU架构规范
流水线级数 3 - 20级 并行执行多条指令的能力 ARM架构参考手册

CISC vs RISC架构对比

特性 CISC(复杂指令集) RISC(精简指令集)
指令数量 多(几百条) 少(几十条)
指令长度 可变 固定
执行周期 多周期 单周期为主
代表架构 x86 ARM、RISC-V
应用领域 PC、服务器 嵌入式、移动设备

XIP vs 非XIP执行对比

特性 XIP(原地执行) 非XIP
执行位置 Flash RAM
启动速度 快 慢(需复制)
执行速度 慢 快
RAM占用 少 多

总结

今天完成了从二进制烧录到CPU执行的完整之旅。核心要点:二进制烧录是将程序从电脑"搬"到单片机Flash,程序运行是CPU按"取指→译码→执行→写回"流程逐条执行0和1。

理解这个核心流程后,建议后续学习:中断机制、时钟系统、GPIO控制,这些是嵌入式开发的基础。关注我,带你用最通俗易懂的方式,理解最硬核的嵌入式技术!

搞笑图片
(程序员看CPU执行0和1的表情包:我也想这么高效地工作)


字数:约3200字 | 完成日期:2026-04-21

版权声明

作者linuxROS
协议本作品采用 CC BY-NC-SA 4.0 许可协议:署名-非商业性使用-相同方式共享
关注欢迎关注微信公众号 linuxROS,获取更多机器人 / 嵌入式 / Linux 干货
返回首页