Appearance
有效地址计算
2026 大纲 四(三)寻址方式——有效地址的计算与访存代价一侧。
算完公式还没算完,你手上拿的还是个地址
寻址计算题的错法高度集中,而且不是算错,是提前停手。变址寻址
只有两个方式没有中间那一段:立即寻址(操作数就是
这一篇处理的正是"从
交互可视化
一、访存次数:一次一次数出来
访存次数不需要记表,按"这条指令一共碰了几次存储器"逐段数即可。一条指令的完整执行最多经过三个访存场合:
| 场合 | 什么时候发生 | 次数 |
|---|---|---|
| 取指令 | 每条指令都有 | 恒为 1 |
| 求有效地址 | 只有间接寻址需要(多重间接则多次) | 0 或 |
| 取操作数 | 操作数在存储器里时才需要 | 0 或 1 |
按这个框架逐种展开:
| 寻址方式 | 取指令 | 求 EA | 取操作数 | 合计 |
|---|---|---|---|---|
| 立即 | 1 | 0 | 0(操作数在指令里) | 1 |
| 寄存器 | 1 | 0 | 0(操作数在寄存器) | 1 |
| 直接 | 1 | 0 | 1 | 2 |
| 寄存器间接 | 1 | 0(EA 已在寄存器里) | 1 | 2 |
| 相对 / 基址 / 变址 | 1 | 0(EA 靠加法算出,不访存) | 1 | 2 |
| 一重间接 | 1 | 1 | 1 | 3 |
| 1 | 1 |
编者注(辨析):偏移寻址三种方式看起来"多了一步计算",却和直接寻址一样只访存 2 次——因为那一步是在 CPU 内部做加法,加法器不碰存储器。真正让访存次数上涨的只有"到内存里再去取一次地址"这一件事。
二、相对寻址:基准与位移量
式中的
分母那一项常被跳过,而它决定了增量到底是多少:
| 情形 | PC 增量 | 例 |
|---|---|---|
| 定长指令 | 1 | 单字长指令恰好占一个存储单元 |
| 定长指令 | 指令占的字节数 | 2 字节定长指令加 2;32 位定长指令加 4 |
| 变长指令 | 本条指令的字节数 | 5 字节的调用指令加 5 |
中间那一档最容易被漏掉:"定长"不等于"加 1"。同样是 2 字节的定长指令,按字编址加 1、按字节编址加 2,两者差一个单位,目标地址随之整体偏移。
位移量可正可负,用补码表示。当它的位宽小于地址位宽时,参与加法前必须按补码符号扩展到地址位宽。位移量的位宽直接决定转移范围:
反过来用,公式移项即可:
至于地址字段该按无符号读还是按补码读,判据是它扮演什么角色,不是它长什么样:绝对地址(直接寻址、间接寻址里的形式地址)按无符号读,因为地址不存在负数;位移量与偏移量(相对、基址、变址)按补码读,因为它们必须能往回指。同一个 E3H,当绝对地址是 227,当 8 位位移量是 E3H 扩到 16 位是 FFE3H 而不是 00E3H,用零扩展会把一个小的负位移变成一个很大的正数,目标地址直接跑飞。
还有一层单位问题容易被跳过:位移量的单位未必是字节。有的指令系统把目标地址定义成
三、复合寻址
部分机器把基址与变址组合起来,并给变址部分配一个比例因子:
比例因子
三段的分工是固定的:
| 段 | 装什么 | 为什么装它 |
|---|---|---|
| 位移量 | 数组首地址 | 首地址是编译期常量,正好放进指令的立即数字段 |
| 基址寄存器 | 行偏移 | 内层循环期间不变,外层每轮更新一次 |
| 变址寄存器 | 列偏移 | 内层循环每轮变化,正好由比例因子完成 |
对应的地址公式:
编译器不会在内层循环里反复做
把第一节那三条判据套上去,复合寻址的访存次数不用另记:
三段完整走查:同一条指令在各寻址方式下的 EA、由目标地址反求位移量、二维数组元素地址(想核对自己每一步的基准值、进制换算与三段分配取得对不对时展开)
(一)同一条指令在各寻址方式下的 EA。 设某机按字节编址、指令定长 4 字节;本条指令首地址 2000H,故取指后
| 寻址方式 | EA 的算法 | EA | 操作数 | 总访存 |
|---|---|---|---|---|
| 立即 | 不产生 EA | — | 1 | |
| 寄存器( | 不产生 EA | — | 1 | |
| 直接 | 0100H | 2 | ||
| 间接 | 6000H | 3 | ||
| 寄存器间接( | 5000H | 2 | ||
| 相对 | 2104H | 2 | ||
| 基址( | 5100H | 2 | ||
| 变址( | 0130H | 2 |
三处值得回看:相对寻址那一行用的是 2004H 而不是 2000H(按字节编址、4 字节定长指令,PC 增量是 4);间接寻址是唯一访存 3 次的,多出来的那次花在"到 0100H 去把真正的地址读回来";立即与寄存器两行的 EA 栏是空的,因为它们不产生存储器地址。
(二)由目标地址反求位移量。 某转移指令位于 3000H,本条指令占 2 字节,要跳到 2FC0H:
写成 8 位补码即 BEH。回代验算:3002H 为基准、8 位补码位移,可达 2F82H ~ 3081H,目标 2FC0H 落在其中,位移量装得下。
(三)二维数组元素的地址。 int a[50][30],每个元素 4 字节,按行优先存放,数组首地址 00500000H,求 a[7][12] 的地址与三段分配。
行宽(一整行占多少字节)
| 段 | 值 | 来源 |
|---|---|---|
| 位移量 | 00500000H | 数组首地址,编译期常量 |
| 基址寄存器 | 行偏移,外层循环每轮 | |
| 变址 | 列偏移, |
反过来读也成立:看到比例因子是 4,就知道元素占 4 字节;再由数组的列数算出行宽,基址寄存器里装的必然是
考点速记
- 所有公式算出来的都是 EA(一个地址),取操作数还差
;访存次数按取指恒 1 求 EA(只有间接才需要) 取操作数(在存储器里才需要)三个场合逐一数——数的是碰了几次存储器,不是算了几次加法。 - 相对寻址的基准是
而非本条首址,增量分按字编址加 1 / 按字节编址加指令字节数 / 变长加本条字节数三档;位移量按补码读,位宽不足时须符号扩展,且单位未必是字节。 - 复合寻址
三段固定分工(位移量装首地址、基址装行偏移、变址乘比例因子装列偏移),比例因子 元素字节数;段数多少不影响访存次数,仍是 2 次,叠一层间接才变 3 次。
这一节在真题里被考过的形式:
- 算完 EA 就停手(2013-17)。给出变址寄存器内容 1000H、形式地址 2000H,再给一串存储单元的内容,问"变址寻址下访问到的操作数"。
只是半程,答案是 。四个选项恰好把这条链上的每一站都摆了出来——寄存器内容、形式地址、EA、操作数,停在哪一站就选中哪一个错项。 - 相对寻址的基准取错(2009-16)。转移指令在 2000H、占 2 字节、按字节编址、每取一个字节 PC 加 1、位移量 06H。基准不是 2000H 而是取完整条指令之后的 PC
,目标地址 。选项里 2006H(用本条首址)、2007H(只加了一次)、2009H(多加了一次)把三种取错基准的方式全列齐了。判断增量时先问两句:指令占几个字节、按什么编址。 - 位移量的单位不是字节(2013-44)。题面给的公式是"转移目标地址
、顺序执行下条地址 "。由后一句可知 16 位指令占 2 个地址单元,故按字节编址;由前一句里的 可知 OFFSET 数的是指令条数,所以 8 位补码的 OFFSET 向后最多跳 128 条指令(不是 128 字节,也不是 127 条)。这道题两问都是从给定公式反推口径,一个字都不能默认。 - 复合形式的偏移地址反求下标(2018-18)。
double数组首址 2000H、变址寄存器存下标、偏移地址变址值 sizeof(double),某次取到的元素地址是 2100H。。关键在先把十六进制差值换成十进制再除,以及 sizeof(double)是 8 不是 4。 - 基址寻址叠上补码与大小端(2019-15)。形式地址 FF12H 用补码表示、要符号扩展成 32 位 FFFFFF12H,与基址 F0000000H 相加得 EFFFFF12H——这里正是"零扩展会跑飞"的实例:若扩成 0000FF12H,结果是 F000FF12H,恰好就是错项 A。算出的 EA 是操作数首字节的地址,而题问的是 LSB(最低有效字节)的地址:大端方式下最低有效字节排在最后,4 字节操作数的 LSB 在 EFFFFF12H
EFFFFF15H。三步——符号扩展、地址相加、按端序定位——错一步就落进一个错项。 - 由指令格式反推转移目标地址的范围(2010-43)。16 位机、按字编址、单字长指令,所以 PC 增量是 1 而不是 2;相对寻址的位移量取自一个 16 位寄存器、按补码,于是目标地址范围是
。"定长不等于加 1"这条在这里正好反过来用:它确实加 1,但理由是按字编址,不是因为定长。
易错:把 EA 当操作数交卷。除立即与寄存器两种方式外,公式右边一律是地址,还差一次
。
易错:相对寻址用本条指令首地址当基准。PC 在取指周期就已自增,用到它时装的是下一条指令的地址。
易错:见到"定长指令"就认为 PC 加 1。加 1 的条件是按字编址;按字节编址要加指令占的字节数。
易错:把位移量按无符号读,或位宽不足时做零扩展。位移量是补码,必须符号扩展。
易错:把偏移寻址"多做了一次加法"算进访存次数。那次加法在 CPU 内部,加法器不碰存储器。
教材出处
- 袁春风《计算机组成与系统结构(第 3 版)》§4.2.3 寻址方式:有效地址在无虚拟存储时即物理地址、变址寻址中元素占 4 字节时变址寄存器每次加 4、前变址与后变址的有效地址表达式(印刷页 p94~96)
- 唐朔飞《计算机组成原理(第 3 版)》§7.3 寻址方式:间接寻址在执行阶段需访存两次或多次、寄存器寻址在执行阶段无须访存、相对寻址的位移量用补码表示且 8 位位移的范围为
、基址与变址结合时 (印刷页 p313、p316)