CPU和内存基础

1. CPU寄存器

CPU内部有一些高速存储单元,叫做寄存器。操作系统开发中需要了解的主要寄存器:

1.1 通用寄存器

64位32位16位用途
RAXEAXAX累加器,常用于运算和返回值
RBXEBXBX基址寄存器
RCXECXCX计数器,循环计数
RDXEDXDX数据寄存器,I/O操作
RSIESISI源地址(字符串操作)
RDIEDIDI目的地址(字符串操作)
RBPEBPBP栈基址指针
RSPESPSP栈顶指针

📝 64位寄存器以 R 开头,32位以 E 开头,16位直接是两字母。 在实模式(16位)中使用 AX、BX 等,保护模式(32位)使用 EAX、EBX 等。

1.2 段寄存器

寄存器名称用途
CS代码段指向当前执行的代码所在的段
DS数据段指向数据存储的段
SS栈段指向栈所在的段
ES附加段额外的数据段
FS附加段通常用于线程本地存储
GS附加段通常用于系统数据

1.3 特殊寄存器

寄存器用途
RIP/EIP/IP指令指针 - 指向下一条要执行的指令
RFLAGS/EFLAGS标志寄存器 - 存储运算结果的状态
CR0控制寄存器0 - 包含保护模式开关
CR3控制寄存器3 - 页目录基地址

1.4 标志寄存器中的关键位

EFLAGS:
  CF (Carry Flag)     - 进位标志,无符号运算溢出
  ZF (Zero Flag)      - 零标志,结果为零时置1
  SF (Sign Flag)      - 符号标志,结果为负时置1
  IF (Interrupt Flag) - 中断标志,1=允许中断
  DF (Direction Flag) - 方向标志,字符串操作方向

2. 指令执行周期

CPU执行每条指令的过程:

取指(Fetch) → 解码(Decode) → 执行(Execute) → 写回(Write-back)
    ↑                                              |
    └──────────────────────────────────────────────┘
  1. 取指: 从内存中读取 RIP 指向的指令
  2. 解码: 分析指令的操作码和操作数
  3. 执行: 执行运算或内存访问
  4. 写回: 将结果写入寄存器或内存

3. CPU模式

x86 CPU有三种主要工作模式:

模式位数可寻址空间特点
实模式 (Real Mode)16位1MB开机默认模式,无内存保护
保护模式 (Protected Mode)32位4GB有内存保护和特权级
长模式 (Long Mode)64位16EB现代操作系统使用

启动过程的模式切换:

开机 → 实模式(16位) → 保护模式(32位) → 长模式(64位)

我们的教程将从实模式开始,逐步切换到高级模式。

4. 内存基础

4.1 物理地址 vs 逻辑地址

  • 物理地址: 内存芯片上的真实位置
  • 逻辑地址: 程序看到的地址(可能经过段或页的转换)

实模式寻址(段:偏移):

物理地址 = 段基址 × 16 + 偏移量

例: CS=0x07C0, IP=0x0000
物理地址 = 0x07C0 × 16 + 0x0000 = 0x7C00

4.2 重要的内存地址

OS开发中你会反复遇到这些地址:

地址范围                    用途
─────────────────────────────────────────────
0x00000000 - 0x000003FF    中断向量表(实模式,1KB)
0x00000400 - 0x000004FF    BIOS数据区
0x00000500 - 0x00007BFF    可用内存
0x00007C00 - 0x00007DFF    引导扇区(BIOS加载到这里)  ← 我们代码的起点
0x00007E00 - 0x0009FFFF    可用内存
0x000A0000 - 0x000BFFFF    VGA显存                    ← 屏幕输出写这里
0x000C0000 - 0x000FFFFF    BIOS ROM
0x00100000 - ...           扩展内存(1MB以上)         ← 内核加载到这里

4.3 栈

栈是一种后进先出(LIFO)的数据结构,在内存中向下增长:

高地址
┌──────────┐
│          │ ← 栈底 (EBP)
├──────────┤
│ 局部变量 │
├──────────┤
│ 返回地址 │
├──────────┤
│ 参数     │
├──────────┤
│          │ ← 栈顶 (ESP),向下增长
└──────────┘
低地址

关键操作:

  • push eax — 将 EAX 压入栈顶(ESP 减小)
  • pop eax — 从栈顶弹出到 EAX(ESP 增大)
  • call func — 压入返回地址,跳转到 func
  • ret — 弹出返回地址,跳转回去