细分两种变址寻址🤔
1. 变址寻址 (Indexed Addressing)
-
一句话说明: 有效地址由“基准地址(在指令中)”加上“偏移量(在变址寄存器中)”得到。
-
生活比喻: 我告诉你我们的基地在“人民路”(基准地址),你要找的人住在从基地出发沿着门牌号走“100号”的位置(偏移量)。你的最终目的地 = 人民路 + 100号。
-
指令示例:
MOV AX, 100[SI]
-
SI
是变址寄存器 (Source Index)。 -
含义: 有效地址
EA = 100 + (SI)
,其中(SI)
表示SI
寄存器中的内容。然后取出主存地址EA
处的数据放入AX
。
-
-
执行分析:
-
CPU取指、译码。
-
CPU将指令中的形式地址
100
和变址寄存器SI
的内容在ALU中相加,得到有效地址EA
。 -
CPU使用
EA
访问主存,取出操作数。 -
将操作数送入
AX
。
-
-
主要用途: 处理数组。指令中的
100
是数组的首地址,变址寄存器SI
中存放元素的下标(乘以元素大小后的偏移)。通过循环改变SI
的值,就可以方便地遍历数组。 -
考点陷阱: 变址寄存器的内容是可变的(通常是循环变量),而指令中的地址是固定的(通常是数组首地址)。
总结对比表
寻址方式 | 有效地址 EA 的计算公式 | 操作数位置 | 访存次数 | 主要用途 |
---|---|---|---|---|
立即 | (无,操作数在指令中) | 指令内部 | 0 | 赋常量 |
直接 | EA = D |
主存 | 1 | 访问静态变量 |
间接 | EA = (D) |
主存 | 2 | 指针、动态内存 |
寄存器 | (无,操作数在寄存器中) | 寄存器 | 0 | 高频数据操作 |
寄存器间接 | EA = (R) |
主存 | 1 | 按地址访问数据结构 |
变址 | EA = D + (IX) |
主存 | 1 | 数组遍历 |
基址 | EA = (BR) + D |
主存 | 1 | 程序重定位 |
相对 | EA = (PC) + D (这是转移地址) |
指令流(下一条指令) | 1 (取指) | 程序分支、循环 |
注: D
=指令中的形式地址, R
=通用寄存器, IX
=变址寄存器, BR
=基址寄存器, PC
=程序计数器, (X)
=X的内容。访存次数指为获取一个操作数而访问主存的次数。
一、 答案
在现代计算机中,变址寄存器通常存放的是原始的数组下标,由CPU硬件在计算有效地址时**自动完成“下标乘以元素大小”**这个操作;但在简化的教学模型或一些早期设计中,也可能是要求程序员(或编译器)事先算好偏移量(即下标 * 元素大小)再放入变址寄存器。
二、两种变址寻址
变址寻址的两种实现模式:基础变址寻址和比例变址寻址 (Scaled Indexed Addressing)。
模式一:基础模型(编译器/程序员负责计算偏移量)
在这种简化的、经典的教学模型中,CPU的地址生成单元只包含一个加法器。
-
变址寄存器的角色: 存放的是字节偏移量 (Byte Offset)。
-
有效地址计算公式:
EA = Base Address + (IX)
- 这里的
(IX)
就是最终的字节偏移。
- 这里的
-
操作过程:
-
程序员/编译器层面: 程序员使用逻辑下标
i
(例如i = 3
)。如果要访问一个4字节的整型数组int arr[]
,编译器需要生成额外的指令,计算出字节偏移量Offset = i * 4 = 12
。 -
指令执行前: 必须有一条指令将计算出的
Offset
(12) 载入变址寄存器IX
。 -
变址寻址指令执行: CPU执行
MOV AX, arr_base[IX]
时,直接将arr_base
和IX
中的12
相加得到有效地址。
-
伪代码示例 (访问 arr[i]
, int类型):
代码段
; 假设 i 存放在 CX 寄存器中
MOV AX, CX ; 将 i 复制到 AX
SHL AX, 2 ; 左移两位,等效于 AX = AX * 4,计算字节偏移量
MOV SI, AX ; 将计算好的字节偏移量放入变址寄存器 SI
MOV BX, arr[SI] ; 执行变址寻址,EA = arr基地址 + (SI)
- 结论: 在这种模式下,变址寄存器里存放的是已经乘好的字节偏移量。乘法操作是在执行变址寻址之前由独立的指令完成的。
模式二:比例变址模型(CPU硬件负责计算偏移量)
在现代CPU(如x86系列)中,为了提高处理数组的效率,地址生成单元硬件本身就包含了移位器或乘法器,可以直接处理比例因子。
-
变址寄存器的角色: 存放的是逻辑下标 (Logical Index)。
-
有效地址计算公式:
EA = Base Address + (IX) * Scale
Scale
是比例因子,大小等于数组元素的大小(1, 2, 4, 8)。这个比例因子通常由操作码或指令的其他部分隐式或显式地指定。
-
操作过程:
-
程序员/编译器层面: 程序员使用逻辑下标
i
。编译器直接将i
的值生成指令载入变址寄存器IX
。 -
指令执行前:
IX
中存放的就是i
本身(例如3
)。 -
变址寻址指令执行: CPU在一条指令的地址计算周期内,自动完成
(IX) * Scale
和加法操作。硬件电路并行地或流水地完成这些计算。
-
x86汇编示例 (访问 arr[i]
, int类型, 即dword):
代码段
; 假设 i 存放在 ECX 寄存器中, arr 基地址在 EBX 中
MOV EAX, [EBX + ECX * 4] ; 一条指令完成所有操作
-
解释: 这条指令明确告诉CPU:
-
基地址在
EBX
中。 -
逻辑下标在
ECX
中。 -
比例因子是
4
(因为是dword
数组)。 -
CPU硬件会计算
(EBX) + (ECX) * 4
来得到最终的有效地址。
-
-
结论: 在这种模式下,变址寄存器里存放的是原始的数组下标。乘法操作是作为地址计算的一部分,由CPU硬件在执行该指令期间自动完成的。