Appearance
数据寻址方式
2026 大纲 四(三)寻址方式。
一串二进制不会告诉你它是数还是地址
内存里放着 0100H。它是数值 256,还是地址 0100H?这一位信息不在数据里——它在指令的寻址方式字段 M(寻址特征位)里。M 说立即数它就是 256,M 说直接寻址它就是地址。CPU 在译码阶段读出 M,才知道接下来该怎么解释指令里那个地址字段。那两三位看起来不起眼的寻址方式位因此一位都不能省:没有它,地址码根本无法解释。
于是问题变成:为什么值得给 M 留出好几位、支持这么多种解释方式?因为指令里的地址字段同时被三个互相拉扯的要求盯着——
- 地址码要短:它直接决定指令长度,而指令长度决定取指要访存几次;
- 寻址范围要大:操作数可能落在主存任何地方,也可能在寄存器里、在指令里、在栈顶;
- EA 计算要简单:这一步在指令的执行路径上,每多一次加法或访存都要当场付出时间。
三个要求不可能同时满足,所以没有"最好的寻址方式",只有铺开在这个三角里的一整条折中谱系。立即寻址把操作数直接塞进指令——不访存最快,但装不下大数;间接寻址把地址放进主存单元——寻址范围不再受指令长度限制,代价是多访存一次;寄存器间接寻址再把这个存地址的地方从主存搬进 CPU——省掉那次访存,代价是占用一个寄存器。读下面每一种方式时都可以回来问一句:它在这个三角里站在哪、拿什么换了什么。
先约定三个记号:
交互可视化
一、先分两类:指令寻址与数据寻址
"寻址"这个词底下压着两件不同的事:
| 类别 | 要确定的是 | 有哪几种 |
|---|---|---|
| 指令寻址 | 下一条指令的地址从哪来 | 顺序寻址:由 PC 自增自动形成;跳跃寻址:由转移类指令给出目标地址 |
| 数据寻址 | 指令里的形式地址该怎么解释成操作数 | 立即、直接、间接、寄存器、寄存器间接、变址、基址、相对、堆栈、隐含 |
关键的一层关系是:跳跃寻址的目标地址,仍然要靠数据寻址的那几种方式算出来——JMP 7 这种把绝对地址写在指令里的是直接寻址,(PC) + A 这种给出相对位移的是相对寻址,还可以把目标地址存在某个单元里用间接寻址取出。所以两类不是并列的清单:指令寻址决定"走哪条路",数据寻址提供"路标怎么读"。
区分数与地址的判据则全部来自指令格式里的寻址方式字段:
CPU 在译码阶段读出 M 字段,据此决定接下来怎么解释
二、各数据寻址方式
| 方式 | 有效地址 / 操作数 | 收益与代价 |
|---|---|---|
| 立即 | 操作数 | 取操作数无须访存,速度最快;立即数位宽受指令字长限制,装不下大数 |
| 直接 | 不需要计算;地址空间受 | |
| 间接 | @ 标志 | 突破指令中地址字段的位宽限制;代价是多访存一次。可多重间接;经典用途是子程序返回 |
| 寄存器 | 操作数 | 寄存器编号比存储地址短得多 |
| 寄存器间接 | 地址码长度同寄存器寻址,但 EA 来自寄存器而非指令字段,寻址范围不受指令长度限制;执行阶段访存一次 | |
| 变址 | ||
| 基址 | 基准由基址寄存器 | |
| 相对 | 位移量可正可负、用补码;8 位位移量的范围是基准值的 | |
| 堆栈 | 操作数隐含在栈顶,由 SP 访问 | 指令中无须给出地址。PUSH X 调整 SP 后写栈顶,POP X 读栈顶后反向调整。零地址运算指令的基础 |
| 隐含 | 由操作码隐含指出 | 一地址指令的另一操作数隐含为累加器内容、栈操作指令的操作数隐含为栈顶元素 |
若任意通用寄存器都可用作基址/变址寄存器,指令中必须给出寄存器编号并标明用途;若机器设有专门的基址寄存器,则无须在指令中指出。
间接寻址:两级箭头就是它的收益与代价

图 4.1 单级间接寻址
有效地址不再受指令中地址字段位宽的限制(存储单元有多宽,地址就能有多宽),但取一次操作数要多访存一次。子程序返回是它的经典用途:把返回地址预先写进某个固定单元,子程序末尾用一条 JMP @A 就能返回调用点——同一条指令,不同调用场合返回到不同地方。
寄存器间接寻址是同一个思路挪了个位置:存放地址的那个地方从主存搬进了 CPU。两者的差别全在代价上——间接寻址的 EA 来自主存单元,取一次操作数共访存 2 次(取地址 + 取数),地址位宽受存储字长限制;寄存器间接寻址的 EA 来自寄存器,只访存 1 次,位宽受寄存器位数限制,代价是占用一个寄存器。
变址寻址:循环里变的是寄存器

图 4.2 数组元素的变址寻址
图中 for (i = 0; i < N; i++) { x = a[i]; … } 的循环体中
基址寻址:改一个寄存器,整个程序就搬走了

图 4.3 基址寻址过程
三、偏移寻址:三兄弟的统称
变址、基址、相对三种方式形式完全一致——都是"某个寄存器的内容加上一个形式地址",因此教材把它们统称为偏移寻址。区别只在那个寄存器是谁,以及谁固定、谁变化:
| 寄存器是 | 谁不变 | 谁在变 | 谁来改 | 用途 | |
|---|---|---|---|---|---|
| 变址 | 变址寄存器 | 形式地址 | 寄存器 | 程序员 / 编译器 | 数组、表格的顺序访问 |
| 基址 | 基址寄存器 | 寄存器 | 形式地址 | 操作系统(装入时设定) | 程序重定位 |
| 相对 | 程序计数器 PC | 二者都随位置浮动 | 位移量 | 编译器 / 汇编器 | 转移指令、位置无关代码 |
有些指令系统还把基址和变址结合起来,形成基址加变址寻址:
三段各司其职,正好对应二维数组访问的三个成分。展开算例见 有效地址计算。
四、间接与变址的结合
变址寻址还能与间接寻址组合,先后顺序不同结果不同:
| 名称 | 先做什么 | 有效地址 | 对应的 C 语义 | 数据长什么样 |
|---|---|---|---|---|
| 前变址(先变址后间址) | 先算 | 取出指针数组的第 | ||
| 后变址(先间址后变址) | 先从 | 先取出基址指针,再偏移 |
同一组数据在前后变址下差出多远:两条路各走一遍(怀疑自己把先后顺序记反了时展开)
设
- 后变址:先间接取内容,再加变址值 ——
- 前变址:先加变址值,再间接取内容 ——
同一组条件,结果一个在 1004H、一个在 2000H,差得很远。可见这两种方式不是写法差异而是语义差异:区分办法只有一条——看加法发生在间接取内容之前还是之后。
考点速记
- 寻址先分两类:指令寻址(顺序 / 跳跃)与数据寻址(十种);跳跃寻址的目标地址仍由数据寻址方式给出。多种方式并存是在地址码长度、寻址范围、计算与访存代价这个三角里铺开的折中谱系。
- 一串二进制是数还是地址,由指令的寻址方式字段 M 决定,数据本身不携带这个信息。
- 变址、基址、相对统称偏移寻址,形式都是"寄存器内容
形式地址";变址与基址的"谁变谁不变"恰好相反——前者服务数组遍历、后者服务程序重定位;相对寻址的基准是下一条指令的地址,位移量用补码。
这一节在真题里被考过的形式:
- 给出偏移寻址的定义,问哪一种不属于它(2011-16)。判据就一句:能不能写成"某寄存器内容
形式地址"。基址、变址、相对都能,间接寻址不能——它的 EA 直接来自主存单元,全程没有寄存器参与相加。相对寻址是这道题里被误排除得最多的一项,原因是"PC 听起来不像普通寄存器";但定义只看形式,不看那个寄存器叫什么名字。 - 问哪种寻址方式适合按下标顺序访问一维数组(2017-15)。答变址。理由不是"变址听起来像数组",而是数组遍历中首址不变、下标在变,变址寻址恰好把不变的那个放在指令的形式地址里、把变的那个放在寄存器里,于是循环体内的取数指令一个位都不用改。
- 同一个寄存器编号,里面可能是操作数也可能是操作数地址,CPU 凭什么区分(2023-17)。答寻址方式——寄存器寻址取其内容当操作数,寄存器间接寻址取其内容当地址。这问的正是本篇开篇那句话:解释权在指令不在数据,所以答案既不可能是"寄存器编号",也不可能是"寄存器的内容"。
- 给一段真实的 x86 机器代码,判断某条指令用的是哪种寻址方式(2023-44)。
jmp/jge这类短跳转的机器码里跟的是一个字节的位移量而非绝对地址,是相对寻址;mov [ecx+edx*4+00422000h], 0Ah的源操作数0Ah直接写在指令中,是立即寻址。这类题不考定义,考的是从机器码的形态上把它认出来——跟在操作码后面的到底是位移量、绝对地址,还是一个常数。
易错:把相对寻址排除出偏移寻址。PC 也是寄存器,
完全符合"寄存器内容 形式地址"。
易错:把变址和基址的"谁变谁不变"记反。变址是形式地址固定(数组首址)、寄存器在变(下标);基址是寄存器固定(OS 装入时设定)、形式地址在变(每条指令自带偏移)。
易错:以为数据本身能看出是地址还是数值。解释权只在寻址方式字段手上。
易错:把前变址与后变址记反。判据只有一条——加法发生在间接取内容之前(前变址,
)还是之后(后变址, )。
教材出处
- 袁春风《计算机组成与系统结构(第 3 版)》§4.2.3 寻址方式:地址码短与寻址空间大之间的矛盾、立即/直接/间接/寄存器/寄存器间接寻址的定义(印刷页 p94);变址寻址与数组遍历、前变址与后变址、相对寻址的位移量为带符号整数、基址寻址与偏移寻址的统称、隐含寻址(印刷页 p95~96);图 4.1 单级间接寻址(p94)、图 4.2 数组元素的变址寻址(p95)、图 4.3 基址寻址过程(p96)
- 唐朔飞《计算机组成原理(第 3 版)》§7.3.1 指令寻址:指令寻址分顺序寻址与跳跃寻址,顺序寻址通过 PC 加 1 自动形成下一条指令地址、跳跃寻址通过转移类指令实现,跳跃寻址的转移地址形成方式见直接寻址与相对寻址(印刷页 p310)
- 同上 §7.3 寻址方式:间接寻址用于子程序返回、寄存器寻址与寄存器间接寻址的比较(印刷页 p313);变址寻址求
个数平均值的程序对比、自动变址、基址加变址的组合、相对寻址位移量用补码表示且 8 位位移的范围为 (印刷页 p316)
相关知识
有效地址计算|指令格式设计与扩展操作码|指令系统的基本概念|指令执行过程