精简版 · 小杯2026-08 冻结,已停止更新(发布前修订了 4 处已知错误)。后续勘误与新增内容只在正式版。看正式版(中杯)→
Skip to content

数据寻址方式

考情分析

寻址方式在选择题和大题里都有涉及。重点在于 EA 的计算公式和访存次数,尤其是间接寻址、基址/变址寻址的区别。

大纲定位

考纲第四章(三):寻址方式

要求到什么程度:不只是背八种方式的 EA 公式,还要能由具体地址算出有效地址和操作数、判断某方式属不属于偏移寻址、数清一次访问要访存几次。

寻址方式总览

寻址方式有效地址 EA取操作数访存次数特点
立即寻址操作数就是指令中的数本身0最快,操作数在指令中
直接寻址EA = A1简单,A 是内存地址
间接寻址EA = (A)2(一次取地址,一次取数)灵活,支持数组/指针
寄存器寻址操作数在寄存器中0(不访存)最快访问,寄存器有限
寄存器间接寻址EA = (R)1寄存器存地址,灵活
相对寻址EA = (PC) + A1与位置无关,适合跳转
基址寻址EA = (B) + A1B 由操作系统设置,程序重定位
变址寻址EA = (X) + A1X 由程序员修改,适合循环/数组

记号约定(真题也用这一套,务必分清):

  • A:指令中的地址字段(形式地址)
  • (X)取内容X 是寄存器时表示寄存器内容;X 是地址时表示该内存单元的内容
  • 所以 (A) 读作"以 A 为地址的那个内存单元里存的值",((A)) 就是再取一次

选择题常拿 I / (I) / ((I)) 这一层层括号的差别设选项,看清有几层括号是第一位的。

EA 是地址,不是操作数。所有公式算出来的都是 EA,还差最后一步:

操作数=Mem[EA]

停在 EA 就交卷是这类题最常见的失分方式(立即寻址和寄存器寻址除外,它们不产生内存 EA)。

判据来自指令,不是数据

同一个寄存器里的一串二进制,什么时候当数、什么时候当地址?由指令自己说了算。指令格式里有专门的寻址方式字段(也叫寻址特征位):

[ OP  M  A ]

CPU 在译码阶段读 M 字段,据此决定接下来怎么解释 A。数据本身不携带"我是地址还是数值"的信息。

偏移寻址:三兄弟的统称

相对、基址、变址三种方式共享同一个形式:

EA=(某个寄存器)+A

它们合称偏移寻址,区别只在那个寄存器是谁(PC / 基址寄存器 / 变址寄存器)以及谁变谁不变。

判断"哪个不属于偏移寻址"时,看有没有这个加法、有没有寄存器参与:间接寻址是 EA=(A),纯粹的一次取内容,没有加法也没有寄存器,所以不属于。

三种典型方式的操作数落点

图 4.1 单级间接寻址

图 4.1 单级间接寻址

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

图 4.2 数组元素的变址寻址

图 4.2 数组元素的变址寻址

变址寻址:形式地址 A 固定为数组首址,变址器 I 装下标(图中为 3),相加得到 a[3] 的地址。循环里只需递增 I,指令本身一个字节都不用改——这就是"变址适合数组遍历"的由来。

图 4.3 基址寻址过程

图 4.3 基址寻址过程

各寻址方式详解

立即寻址

指令中直接包含操作数,而不是操作数的地址。

指令: ADD R0, #5    ; 将立即数 5 加到 R0

操作数 = 指令中的立即数字段,无需访存取操作数。但立即数的位宽受指令字长限制。

直接寻址

指令中的地址字段 A 就是操作数所在的主存地址。

EA=A

访存 1 次即可取到操作数。地址空间受 A 的位数限制。

间接寻址

指令中的 A 不是操作数地址,而是存放操作数地址的内存单元地址。

EA=(A)

需要访存 2 次:第 1 次从地址 A 取出真正的操作数地址,第 2 次才取操作数。

多重间接寻址:(A) 中存的还是间接地址,继续间接,每多一层多访存 1 次。

寄存器寻址

操作数在某个寄存器中,指令指定寄存器编号。

操作数=Ri

不访存,速度最快。但寄存器数量有限(一般 8~32 个)。

寄存器间接寻址

寄存器中存的是操作数的内存地址。

EA=(Ri)

访存 1 次取操作数——与直接寻址次数相同,但地址来自寄存器而非指令字段,因而地址位数不受指令长度限制,可寻址范围更大。

相对寻址

程序计数器 PC 的当前值为基准,加上偏移量 A

EA=(PC)+A

注意:取该指令后 PC 已自动指向下一条指令,所以基准是下一条指令的地址,不是本条的首地址。

PC=本条首地址+指令长度编址单位

"加几"分三档,别只记住第一档

情形PC 增量
定长指令 + 按编址1单字长指令,一条占一个字
定长指令 + 按字节编址指令字节数2 字节定长指令加 2、32 位定长指令加 4
变长指令(x86)本条指令的字节数5 字节的 call 加 5

编者注(易错):中间那一档最常被漏。"定长"不等于"加 1"——按字节编址时 2 字节的定长指令要加 2。真题的经典错项就是把这一档按第一档算,结果差一个单位。

另外,偏移量位宽小于地址位宽时,要按补码符号扩展到地址位宽再相加(如 8 位偏移 E3H → 16 位 FFE3H),否则负偏移会变成一个大正数。

特点:指令中存储的是相对偏移而非绝对地址,程序可以加载到任意内存位置而不改变相对跳转(位置无关代码)。条件跳转指令广泛使用。

基址寻址

基址寄存器 B(Base Register)的内容为基准,加上指令中给出的偏移量 A

B 由操作系统在程序装入时写入、运行期不再改动;变的是 A——程序里每条指令按自己要访问的位置各写各的偏移。这正是程序重定位的原理:整个程序搬到内存别处,只需改 B 一个寄存器,所有指令里的 A 都不用动。

EA=(B)+A
  • 基址寄存器由操作系统设置,用于程序重定位(多道程序)
  • 偏移量 A 较小,基址寄存器覆盖程序起始地址
  • 程序中的 A 是相对程序起始的偏移,基址 B 是实际起始地址

变址寻址

变址寄存器 X(Index Register)的内容为基准,加上固定偏移量 A

EA=(X)+A
  • 变址寄存器由程序员控制,可以在循环中自动增减
  • A 是数组/表格的起始地址(固定),X 是下标(变化的)
  • 适合遍历数组、查表等顺序访问

基址与变址的区别

特性基址寻址变址寻址
谁不变基址寄存器 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)就是基于堆栈寻址:从栈顶弹出两个操作数运算后结果压回栈顶。

交互可视化

加载可视化中...

访存次数汇总

寻址方式取指令访存取操作数访存总计
立即101
寄存器101
直接112
寄存器间接112
相对112
基址112
变址112
间接123

考点清单

  • 立即寻址:操作数在指令中,访存 0 次取操作数
  • 间接寻址:访存 2 次(取地址 + 取数据),比直接多 1 次
  • 基址寻址:OS 设置基址,用于重定位;变址寻址:程序员设置,用于遍历
  • 相对寻址:EA = PC + 偏移,PC 已指向下一条指令
  • 寄存器间接 EA = (Ri),只访存 1 次(地址已在寄存器中)

教材出处

  • 袁春风《计算机组成与系统结构(第 3 版)》§4.1 指令格式与寻址方式:图 4.1(p94)、图 4.2(p95)、图 4.3(p96)

真题练习