计算机组成原理笔记:指令系统与寻址方式
一、指令的基本格式
指令是计算机执行操作的基本单位,由操作码(Opcode)和地址码(Address Code)组成,部分指令可能包含其他字段(如标志位、立即数等)。
1. 操作码(Opcode)
- 功能:指明指令的操作类型(如加法、跳转、加载等)。
- 长度:可以是固定长度(如 4 位、8 位)或可变长度(扩展操作码)。
2. 地址码(Address Code)
- 功能:指定操作数的来源或结果的存储位置。
- 常见格式:
- 零地址指令:不需要操作数(如停机指令
HALT
)。 - 一地址指令:隐含操作数(如累加器操作
ADD A
)。 - 二地址指令:两个操作数地址(如
ADD R1, R2
)。 - 三地址指令:两个源操作数地址和一个目标地址(如
ADD R1, R2, R3
)。
- 零地址指令:不需要操作数(如停机指令
3. 其他字段
- 立即数:直接嵌入指令中的常数(如
MOV R1, #5
)。 - 标志位:用于条件判断(如条件跳转指令中的状态位)。
二、扩展操作码的指令格式
当指令长度固定时,通过灵活分配操作码和地址码的位数,扩展支持更多指令。
1. 扩展原理
- 操作码长度可变:通过减少地址码的位数,腾出空间扩展操作码。
- 树状扩展结构:将操作码分为多个层次,每一层对应不同的操作类型。
2. 扩展方法
- 等长扩展:每一层操作码位数相同(如 4-4-4 扩展)。
- 不等长扩展:不同层次操作码位数不同(如 3-6-9 扩展)。
3. 示例
假设指令长度为 16 位,采用扩展操作码设计:
- 第一层:4 位操作码,支持 16 种基本指令(如算术运算)。
- 第二层:若第一层某操作码为“扩展标记”,后续 4 位用于扩展更多指令(如逻辑运算)。
- 第三层:进一步扩展特殊功能指令(如浮点运算)。
三、指令寻址
指令寻址指确定下一条指令的地址,分为顺序寻址和跳跃寻址。
1. 顺序寻址
- 原理:程序计数器(PC)自动递增,指向下一条指令地址。
- 应用:大部分指令按顺序执行(如
ADD
、MOV
)。
2. 跳跃寻址
- 原理:通过跳转指令(如
JMP
、CALL
)修改 PC 的值。 - 类型:
- 无条件跳转:直接修改 PC(如
JMP 0x100
)。 - 条件跳转:根据状态标志跳转(如
JEQ Label
)。
- 无条件跳转:直接修改 PC(如
四、数据寻址方式
数据寻址指确定操作数在内存或寄存器中的位置。以下是十种常见数据寻址方式:
1. 立即寻址(Immediate Addressing)
- 原理:操作数直接包含在指令中。
- 格式:
MOV R1, #5
(将 5 存入 R1)。 - 优点:速度快,无需访问内存。
- 缺点:操作数范围受限(由指令长度决定)。
2. 直接寻址(Direct Addressing)
- 原理:地址码直接给出操作数的内存地址。
- 格式:
MOV R1, [0x100]
(将地址 0x100 的内容存入 R1)。 - 优点:简单直观。
- 缺点:地址范围受限(需硬编码地址)。
3. 间接寻址(Indirect Addressing)
- 原理:地址码指向一个存放实际地址的寄存器或内存单元。
- 格式:
MOV R1, [R2]
(R2 中存储的是实际地址)。 - 优点:支持动态地址计算。
- 缺点:需要多次访存,速度较慢。
4. 寄存器寻址(Register Addressing)
- 原理:操作数直接存放在寄存器中。
- 格式:
ADD R1, R2
(R1 和 R2 均为寄存器)。 - 优点:速度快(无需访存)。
- 缺点:寄存器数量有限。
5. 寄存器间接寻址(Register Indirect Addressing)
- 原理:寄存器中存储操作数的内存地址。
- 格式:
MOV R1, [R2]
(R2 保存地址)。 - 优点:灵活,支持指针操作。
- 缺点:需额外访存。
6. 相对寻址(Relative Addressing)
- 原理:操作数地址 = PC 当前值 + 偏移量。
- 格式:
JMP 0x100
(PC=0x200 时,跳转到 0x300)。 - 应用:跳转指令、位置无关代码。
7. 基址寻址(Base Addressing)
- 原理:基址寄存器 + 偏移量。
- 格式:
MOV R1, [BP + 8]
(访问栈帧中的局部变量)。 - 优点:支持动态内存分配。
- 缺点:需维护基址寄存器。
8. 变址寻址(Indexed Addressing)
- 原理:基地址 + 变址寄存器值 × 缩放因子。
- 格式:
MOV R1, [Array + ECX*4]
(访问数组元素)。 - 优点:适合遍历数组。
- 缺点:需计算地址。
9. 堆栈寻址(Stack Addressing)
- 原理:通过堆栈指针(SP)隐式访问栈顶数据。
- 格式:
PUSH R1
(将 R1 压入栈)或POP R2
(弹出栈顶到 R2)。 - 优点:后进先出(LIFO),适合函数调用。
- 缺点:仅能访问栈顶。
10. 隐含寻址(Implied Addressing)
- 原理:操作数隐含在指令中(如累加器)。
- 格式:
INC A
(累加器 A 自增)。 - 优点:指令简洁。
- 缺点:灵活性低。
五、扩展知识:复合寻址方式
1. 基址变址寻址(Base-Indexed Addressing)
- 原理:基址寄存器 + 变址寄存器 × 缩放因子。
- 格式:
MOV R1, [BX + SI*2]
(适合多维数组访问)。
2. 相对基址变址寻址
- 原理:基址 + 变址 + PC 偏移。
- 应用:动态链接库中的复杂地址计算。
六、总结与对比
寻址方式 | 原理 | 优点 | 缺点 |
---|---|---|---|
立即寻址 | 操作数直接嵌入指令 | 速度快 | 操作数范围受限 |
直接寻址 | 地址码为实际内存地址 | 简单直观 | 地址空间受限 |
间接寻址 | 地址码指向另一个地址 | 支持动态地址 | 多次访存 |
寄存器寻址 | 操作数在寄存器中 | 速度极快 | 寄存器数量有限 |
基址寻址 | 基址寄存器 + 偏移量 | 支持动态内存分配 | 需维护基址寄存器 |
变址寻址 | 基地址 + 变址寄存器 × 缩放因子 | 适合数组遍历 | 需计算地址 |
相对寻址 | PC 当前值 + 偏移量 | 支持位置无关代码 | 仅用于跳转指令 |
堆栈寻址 | 隐式通过堆栈指针访问 | 适合函数调用 | 仅能访问栈顶 |
隐含寻址 | 操作数隐含在指令中(如累加器) | 指令简洁 | 灵活性低 |
七、应用实例
1. 数组遍历(变址寻址)
asm
MOV EBX, Array_Base ; 数组基地址
MOV ECX, 0 ; 索引
Loop:
MOV EAX, [EBX + ECX*4] ; 访问数组元素(每个元素4字节)
ADD ECX, 1
CMP ECX, 10
JL Loop
2. 函数调用(堆栈寻址)
asm
CALL Function ; 将返回地址压栈
Function:
PUSH BP ; 保存基址寄存器
MOV BP, SP ; 设置新栈帧
...
POP BP ; 恢复基址寄存器
RET ; 弹出返回地址