8086/8088 是 Intel 早期的 16 位处理器,工作在 实模式(Real Mode) 下。其内存布局具有鲜明的时代特征,深刻影响了后续 x86 架构的设计。
一、核心特性
20 位地址线 + 1MB 寻址空间
- 地址总线:20 根(A0--A19)
- 最大物理内存 :2²⁰ = 1,048,576 字节 = 1 MB
- 寻址方式 :段地址:偏移地址 (Segment:Offset)
- 物理地址 = 段地址 × 16 + 偏移地址
- 例如:
0x07C0:0x0000→0x07C00
💡 虽然寄存器是 16 位,但通过分段机制可访问 1MB 空间。
二、标准内存布局(上电后)
| 地址范围(物理地址) | 用途 | 说明 |
|---|---|---|
| 0x00000 -- 0x003FF | 中断向量表(IVT) | 256 个中断向量(每个 4 字节),共 1KB |
| 0x00400 -- 0x004FF | BIOS 数据区(BDA) | 存储设备信息、键盘缓冲区等 |
| 0x00500 -- 0x9FFFF | 常规内存(Conventional Memory) | DOS 程序可用的主内存(≈ 640 KB) |
| 0xA0000 -- 0xBFFFF | Upper Memory Area (UMA) | 视频 RAM、适配器 ROM 等 |
| 0xA0000--0xAFFFF | 图形显存(如 VGA) | 文本/图形模式帧缓冲 |
| 0xB0000--0xB7FFF | 单色显存(MDA) | 旧式单色显示器 |
| 0xB8000--0xBFFFF | 彩色显存(CGA/EGA/VGA) | 文本模式:0xB8000 开始 |
| 0xC0000 -- 0xDFFFF | 扩展 BIOS ROM | 硬盘控制器、网卡等 Option ROM |
| 0xE0000 -- 0xEFFFF | 系统 BIOS ROM | 主板固件(POST、INT 服务例程) |
| 0xF0000 -- 0xFFFFF | 系统 BIOS(复位向量) | CPU 启动时从此处取指令 |
🔑 关键点:
- 640 KB 墙:DOS 程序最多使用 640 KB 内存(0x00000--0x9FFFF)
- UMA(Upper Memory Area):384 KB(0xA0000--0xFFFFF)被硬件占用
三、详细区域解析
(一) 中断向量表(IVT)--- 0x00000 ~ 0x003FF
- 存放 256 个中断处理程序入口地址
- 每个条目:偏移(2B) + 段(2B)
- 重要中断:
- INT 10h:视频服务(显示字符)
INT 13h:磁盘服务INT 16h:键盘输入INT 19h:引导加载
(二)BIOS 数据区(BDA)--- 0x00400 ~ 0x004FF
- 关键字段(偏移从 0x400 开始):
0x410:设备标志(内存大小、软驱数量等)0x417:键盘状态(Shift/Caps Lock 等)0x450:RS-232 串口基地址
(三)常规内存--- 0x00500 ~ 0x9FFFF
- DOS 和应用程序的主要运行空间
- COM 程序 :加载到
0x100(PSP 后) - EXE 程序:由 DOS 加载器分配段
(四)视频内存 --- 0xB8000(彩色文本模式)
- 每字符占 2 字节:ASCII + 属性
- 属性字节:背景色(高 4 位)、前景色(低 4 位)
- 示例:在屏幕左上角显示 'A'(白色):
cpp
mov ax, 0xB800
mov es, ax
mov word [es:0], 0x0741 ; 0x41='A', 0x07=白底黑字
1. 屏幕布局
- 文本模式分辨率 :80 列 × 25 行 = 2000 个字符
- 总内存占用 :2000 × 2 = 4000 字节 (从
0xB8000到0xB8F9F) - 每行偏移:160 字节(80 字符 × 2)
💡 第
row行、第col列的偏移计算:
offset = (row * 80 + col) * 2;
2. 数据格式
每个字符占 2 个字节(16 位)
| 字节偏移 | 位 | 含义 |
|---|---|---|
偶数地址(如 0xB8000, 0xB8002...) |
8 位 | ASCII 字符码(Character Code) |
奇数地址(如 0xB8001, 0xB8003...) |
8 位 | 属性字节(Attribute Byte) |
💡 物理布局(小端序机器上连续存储):
|-----------------------------------------------------------------------------------------|
| [0xB8000] = 'A' → 字符 [0xB8001] = 0x1F → 属性 [0xB8002] = 'B' [0xB8003] = 0x1F ... |
3. 属性格式
属性字节是一个 8 位值,结构如下:
|-----------------------------------------------------------------------------------------------------------------------------------------|
| 7 6 5 4 3 2 1 0 ┌────┬────┬────┬────┬────┬────┬────┬────┐ │ BL │ R │ G │ B │ bl │ r │ g │ b │ └────┴────┴────┴────┴────┴────┴────┴────┘ |
| 位 | 名称 | 作用 |
|---|---|---|
| 0--2 | 前景色(Foreground Color) | bgr(注意顺序是 蓝-绿-红) |
| 3 | 前景高亮(Foreground Intensity) | 0=暗色,1=亮色 |
| 4--6 | 背景色(Background Color) | BGR(蓝-绿-红) |
| 7 | 闪烁/背景高亮 | * 默认:闪烁(Blink) * 若 BIOS 设置为"禁用闪烁",则此位变为 背景高亮(Background Intensity) |
4. 常见颜色编码
| 位组合 (RGB) | 颜色 |
|---|---|
000 |
黑色 |
001 |
蓝色 |
010 |
绿色 |
011 |
青色 |
100 |
红色 |
101 |
洋红(品红) |
110 |
棕色/黄色 |
111 |
白色/浅灰 |
🧪 示例:写一个白色字符 'A' 到屏幕左上角
cpp
; 方法 1:直接写内存
mov ax, 0xB800
mov es, ax
mov word ptr es:[0], 0x0741 ; 0x41='A', 0x07=白底黑字(前景白,背景黑)
; 方法 2:分高低字节
mov byte ptr es:[0], 'A' ; 字符
mov byte ptr es:[1], 0x07 ; 属性
属性 0x07 解析:
- 二进制:
0000 0111 - 前景:
111(白色)+ 高亮=0 → 浅灰色 - 背景:
000(黑色) - 闪烁:0(关闭)
✅ 这是最常见的"黑底白字"样式。
(五)系统 BIOS ROM --- 0xF0000 ~ 0xFFFFF
- CPU 复位后,CS=0xF000, IP=0xFFF0 → 从 0xFFFF0 开始执行
- 包含 POST(加电自检)和 BIOS 中断服务例程
四、重要限制与设计影响
| 限制 | 后果 |
|---|---|
| 1MB 寻址上限 | 早期 PC 无法直接使用 >1MB 内存 |
| 段重叠 | 同一物理地址有多种段:偏移表示(如 0x0000:0x0010 = 0x0001:0x0000) |
| 无内存保护 | 任何程序可读写任意内存(包括 BIOS 和 IVT) |
| 640KB 墙 | 成为 DOS 时代的著名瓶颈 |