Appearance
数据寻址方式
考情分析
寻址方式在选择题和大题里都有涉及。重点在于 EA 的计算公式和访存次数,尤其是间接寻址、基址/变址寻址的区别。
大纲定位
考纲第四章(三):寻址方式。
要求到什么程度:不只是背八种方式的 EA 公式,还要能由具体地址算出有效地址和操作数、判断某方式属不属于偏移寻址、数清一次访问要访存几次。
寻址方式总览
| 寻址方式 | 有效地址 EA | 取操作数访存次数 | 特点 |
|---|---|---|---|
| 立即寻址 | 操作数就是指令中的数本身 | 0 | 最快,操作数在指令中 |
| 直接寻址 | EA = A | 1 | 简单,A 是内存地址 |
| 间接寻址 | EA = (A) | 2(一次取地址,一次取数) | 灵活,支持数组/指针 |
| 寄存器寻址 | 操作数在寄存器中 | 0(不访存) | 最快访问,寄存器有限 |
| 寄存器间接寻址 | EA = (R) | 1 | 寄存器存地址,灵活 |
| 相对寻址 | EA = (PC) + A | 1 | 与位置无关,适合跳转 |
| 基址寻址 | EA = (B) + A | 1 | B 由操作系统设置,程序重定位 |
| 变址寻址 | EA = (X) + A | 1 | X 由程序员修改,适合循环/数组 |
记号约定(真题也用这一套,务必分清):
:指令中的地址字段(形式地址) :取内容。 是寄存器时表示寄存器内容; 是地址时表示该内存单元的内容 - 所以
读作"以 为地址的那个内存单元里存的值", 就是再取一次
选择题常拿
EA 是地址,不是操作数。所有公式算出来的都是 EA,还差最后一步:
停在 EA 就交卷是这类题最常见的失分方式(立即寻址和寄存器寻址除外,它们不产生内存 EA)。
判据来自指令,不是数据
同一个寄存器里的一串二进制,什么时候当数、什么时候当地址?由指令自己说了算。指令格式里有专门的寻址方式字段(也叫寻址特征位):
CPU 在译码阶段读 M 字段,据此决定接下来怎么解释 A。数据本身不携带"我是地址还是数值"的信息。
偏移寻址:三兄弟的统称
相对、基址、变址三种方式共享同一个形式:
它们合称偏移寻址,区别只在那个寄存器是谁(PC / 基址寄存器 / 变址寄存器)以及谁变谁不变。
判断"哪个不属于偏移寻址"时,看有没有这个加法、有没有寄存器参与:间接寻址是
三种典型方式的操作数落点

图 4.1 单级间接寻址
间接寻址:指令里的 @间接地址 指向的不是操作数,而是存放有效地址的那个单元;要再访存一次才拿到操作数。图里两级箭头正是访存 2 次的来源。

图 4.2 数组元素的变址寻址
变址寻址:形式地址 a[3] 的地址。循环里只需递增

图 4.3 基址寻址过程
各寻址方式详解
立即寻址
指令中直接包含操作数,而不是操作数的地址。
指令: ADD R0, #5 ; 将立即数 5 加到 R0操作数 = 指令中的立即数字段,无需访存取操作数。但立即数的位宽受指令字长限制。
直接寻址
指令中的地址字段
访存 1 次即可取到操作数。地址空间受
间接寻址
指令中的
需要访存 2 次:第 1 次从地址
多重间接寻址:
寄存器寻址
操作数在某个寄存器中,指令指定寄存器编号。
不访存,速度最快。但寄存器数量有限(一般 8~32 个)。
寄存器间接寻址
寄存器中存的是操作数的内存地址。
访存 1 次取操作数——与直接寻址次数相同,但地址来自寄存器而非指令字段,因而地址位数不受指令长度限制,可寻址范围更大。
相对寻址
以程序计数器 PC 的当前值为基准,加上偏移量
注意:取该指令后 PC 已自动指向下一条指令,所以基准是下一条指令的地址,不是本条的首地址。
"加几"分三档,别只记住第一档:
| 情形 | PC 增量 | 例 |
|---|---|---|
| 定长指令 + 按字编址 | 1 | 单字长指令,一条占一个字 |
| 定长指令 + 按字节编址 | 指令字节数 | 2 字节定长指令加 2、32 位定长指令加 4 |
| 变长指令(x86) | 本条指令的字节数 | 5 字节的 call 加 5 |
编者注(易错):中间那一档最常被漏。"定长"不等于"加 1"——按字节编址时 2 字节的定长指令要加 2。真题的经典错项就是把这一档按第一档算,结果差一个单位。
另外,偏移量位宽小于地址位宽时,要按补码符号扩展到地址位宽再相加(如 8 位偏移 E3H → 16 位 FFE3H),否则负偏移会变成一个大正数。
特点:指令中存储的是相对偏移而非绝对地址,程序可以加载到任意内存位置而不改变相对跳转(位置无关代码)。条件跳转指令广泛使用。
基址寻址
以基址寄存器 B(Base Register)的内容为基准,加上指令中给出的偏移量
- 基址寄存器由操作系统设置,用于程序重定位(多道程序)
- 偏移量
较小,基址寄存器覆盖程序起始地址 - 程序中的
是相对程序起始的偏移,基址 是实际起始地址
变址寻址
以变址寄存器 X(Index Register)的内容为基准,加上固定偏移量
- 变址寄存器由程序员控制,可以在循环中自动增减
是数组/表格的起始地址(固定), 是下标(变化的) - 适合遍历数组、查表等顺序访问
基址与变址的区别
| 特性 | 基址寻址 | 变址寻址 |
|---|---|---|
| 谁不变 | 基址寄存器 B——程序装入时定死,整个程序运行期不变 | 形式地址 A——固定为数组首址 |
| 谁在变 | 形式地址 A——每条指令各写各的偏移 | 变址寄存器 X——随循环递增 |
| 用途 | 程序重定位 | 数组遍历、循环 |
| 修改者 | 操作系统(装入时设定 B) | 程序员/编译器(循环里改 X) |
编者注(易错):两者的公式都是"寄存器
形式地址",唯一区别就在谁是常量、谁是变量,而且正好相反。一句话记:基址是"基准固定、偏移在变",变址是"基准固定在指令里、下标在变"。选择题的做法就是把这两栏对调。
堆栈寻址
操作数隐含在栈顶,通过栈指针 SP 访问。
- PUSH X:SP-1 → SP,然后将 X 写入 M[SP](先移指针再压栈,或反之取决于架构)
- POP X:将 M[SP] 读出送 X,然后 SP+1 → SP
堆栈操作的操作数地址由 SP 隐含给出,无需在指令中显式指定。零地址指令(如 ADD)就是基于堆栈寻址:从栈顶弹出两个操作数运算后结果压回栈顶。
交互可视化
访存次数汇总
| 寻址方式 | 取指令访存 | 取操作数访存 | 总计 |
|---|---|---|---|
| 立即 | 1 | 0 | 1 |
| 寄存器 | 1 | 0 | 1 |
| 直接 | 1 | 1 | 2 |
| 寄存器间接 | 1 | 1 | 2 |
| 相对 | 1 | 1 | 2 |
| 基址 | 1 | 1 | 2 |
| 变址 | 1 | 1 | 2 |
| 间接 | 1 | 2 | 3 |
考点清单
- 立即寻址:操作数在指令中,访存 0 次取操作数
- 间接寻址:访存 2 次(取地址 + 取数据),比直接多 1 次
- 基址寻址:OS 设置基址,用于重定位;变址寻址:程序员设置,用于遍历
- 相对寻址:EA = PC + 偏移,PC 已指向下一条指令
- 寄存器间接 EA = (Ri),只访存 1 次(地址已在寄存器中)
教材出处
- 袁春风《计算机组成与系统结构(第 3 版)》§4.1 指令格式与寻址方式:图 4.1(p94)、图 4.2(p95)、图 4.3(p96)