汇编基础知识:8086CPU结构 段地址+偏移地址

文章目录

8086物理地址相关内容详解

1. 外部地址总线:20位,寻址能力1MB

8086CPU的外部地址总线有20根 ,每根总线可以传输0或1两种电平,总共能组合出 2 20 2^{20} 220个不同地址:

2 20 = 1048576 Byte = 1 MB 2^{20}=1048576\ \text{Byte}=1\ \text{MB} 220=1048576 Byte=1 MB

这代表它最多能外接、访问1MB容量的内存空间,这是它硬件层面能达到的最大寻址范围。

2. 内部结构:16位,单次只能处理16位地址

8086CPU内部的寄存器、运算通路都是16位设计,单次能直接处理的二进制地址只有16位:

16位地址能表示的地址总数是 2 16 = 65536 Byte = 64 KB 2^{16}=65536\ \text{Byte}=64\ \text{KB} 216=65536 Byte=64 KB,如果只用内部16位直接寻址,最多只能访问64KB空间,远达不到外部1MB的能力。

3. 矛盾的解决:分段寻址(物理地址生成方法)

为了让16位内部结构能用上20位外部寻址能力,8086设计了分段机制

把20位物理地址拆成两个16位部分:段基址偏移地址

物理地址计算公式:

物理地址 = 段基址 × 16 + 偏移地址 \text{物理地址} = \text{段基址} \times 16 + \text{偏移地址} 物理地址=段基址×16+偏移地址

  • 段基址左移4位(×16)得到段的起始20位地址;
  • 再加上段内16位偏移地址,最终拼成完整20位物理地址,就能覆盖1MB的内存空间了。

4. 两句话的核心逻辑

  • 第一句说的是CPU对外硬件能力:20根地址线决定最多能找1MB内存单元;
  • 第二句说的是CPU内部数据宽度限制:内部一次只能处理16位数据,单组寄存器只能覆盖64KB,所以必须用分段拼接的方式,才能突破内部16位限制、发挥外部20位总线的全部寻址能力。

5.举例

段基址2000H(16位),偏移地址1F60H(16位):

段基址左移4位: 2000 H × 16 = 20000 H 2000\mathrm{H} \times 16 = 20000\mathrm{H} 2000H×16=20000H

加上偏移: 20000 H + 1 F 60 H = 21 F 60 H 20000\mathrm{H}+1\mathrm{F}60\mathrm{H}=21\mathrm{F}60\mathrm{H} 20000H+1F60H=21F60H(20位最终物理地址)

段地址与偏移地址

1、核心背景:8086的内存分段机制

8086 CPU的地址总线是20位,能访问1MB( 2 20 2^{20} 220)内存空间,但内部寄存器只有16位,最多只能直接表示 2 16 = 64 K B 2^{16}=64\mathrm{KB} 216=64KB的范围,所以设计了分段地址方案

物理地址(最终真实内存地址)= 段地址 × 16(左移4位) + 偏移地址

第一点:存储单元用段地址+偏移地址描述

8086不直接只用一个数值表示内存地址,而是拆成两部分:

  • 段地址:段的起始位置的高16位(段起始地址一定是16的倍数,所以段地址×16就是段真正的首物理地址)
  • 偏移地址:目标单元距离段首的偏移量(16位)

第二点:物理地址21F60H的两种分段写法验证

用公式计算:段地址2000H,偏移1F60H

物理地址 = 2000 H × 16 + 1 F 60 H = 20000 H + 1 F 60 H = 21 F 60 H \begin{align} \text{物理地址} &= 2000\mathrm{H} \times 16 + 1\mathrm{F}60\mathrm{H} \\ &= 20000\mathrm{H} + 1\mathrm{F}60\mathrm{H} \\ &= 21\mathrm{F}60\mathrm{H} \end{align} 物理地址=2000H×16+1F60H=20000H+1F60H=21F60H

  • 写法(a)2000:1F60:是段地址:偏移地址的标准简写格式;
  • 写法(b):用文字描述,说明这个单元属于以2000H为段地址的段内,距离段首偏移1F60H
    这两种描述指向同一个真实物理内存单元21F60H

第三点:段的定义规则

  • 段内的内存单元地址连续
  • 段的起始物理地址必须是16的倍数(对应段地址×16的要求);
  • 划分很灵活:可以根据程序需求,把满足上面条件的连续内存划为一个段,一个物理地址也可以用多组不同的「段:偏移」来表示(比如21F60H也可以写成2100:F60H21F0:60H等)。

2、整体总结

这页PPT是对8086内存分段寻址的小结:

  1. 8086用段地址+偏移地址的双部件模式描述内存地址;
  2. 同一个真实物理地址,可以用段:偏移格式或文字描述段内偏移两种方式表达;
  3. 段的划分要满足起始地址是16的倍数、内部地址连续,划分方式灵活。

8086CPU找一个地址的数据,需要用到两个16位寄存器吗,一个段寄存器,另一个是什么寄存器

1、结论先说

8086 访问内存时,必须 1 个段寄存器(16位) + 1 个偏移寄存器(16位),两者拼接算出20位物理地址。

  • 段寄存器:CS/DS/ES/SS(专门存段基址)
  • 另一类:通用/指针/变址寄存器,用来存偏移地址,不是固定某一个,分场景对应。

2、段寄存器 与 偏移寄存器 默认配对规则(重点)

8086 有一套默认搭配,不用手动指定段,CPU自动匹配:

  1. 取指令(代码)

    段寄存器:CS(代码段寄存器)

    偏移寄存器:IP(指令指针寄存器)

    用途:CPU下一条要执行的指令地址 = CS×16 + IP

  2. 读写普通数据(变量、数组)

    段寄存器:DS(数据段寄存器)

    偏移来源:BX / SI / DI 或直接数字偏移

    例:[BX][SI+5] 都默认用DS段

  3. 栈操作(PUSH/POP、SP)

    段寄存器:SS(堆栈段寄存器)

    偏移寄存器:SP(堆栈指针)

    栈地址 = SS×16 + SP

  4. 字符串操作指令(MOVSB/CMPSB等)

    • 源字符串:段DS,偏移SI
    • 目标字符串:段ES(附加段),偏移DI

3、举完整例子

  1. 读指令:CS:IP
    CS=2000H,IP=1F60H → 物理地址 21F60H
  2. 访问内存数据 [BX]DS:BX
  3. 栈顶数据:SS:SP
  4. 字符串目标地址:ES:DI

4、补充说明

  1. 偏移不一定非得是寄存器,也可以是纯数字(立即数偏移),比如 DS:[1000H],此时只有段寄存器DS,偏移是常数;
  2. 可以手动改写段前缀,强制换段,比如 CS:[BX],不用默认DS,改用CS段;
  3. 所有段、偏移寄存器全都是16位,二者组合才能生成20位真实物理地址,解决8086内部16位、外部20位地址线的矛盾。