# 4.2 指令的寻址方式

## 4.2.1 指令寻址

通过程序计数器（PC）来给出下一条要执行的指令的地址。

### 1、顺序寻址

$$
(PC)+"1" \to PC
$$

{% hint style="warning" %}
这里的+1并不是直接+1，而是<mark style="color:orange;">**取决于指令字长与存储字长**</mark>。

例如：系统采用定长指令字结构，指令字长=存储字长=2B，主存按照字节（1B）编址，则实际上PC每次是+2

而若采用不定长指令字结构，则每次加的值取决于正在执行的指令的长度。
{% endhint %}

### 2、跳跃寻址

即通过转移指令JMP直接修改PC的值，跳转到相应的指令。

## 4.2.2 数据寻址

明确<mark style="color:orange;">**本条指令**</mark>的地址码指明的<mark style="color:orange;">**真实地址**</mark>。

一般来说，会通过在操作码前增加几位<mark style="color:orange;">**寻址特征**</mark>，用于表明使用的哪种寻址方式。

![](/files/Nz4fqX8uj01Xz4n9EN6V)

### 1、直接寻址

指令字中形式地址就是真实地址，直接访问即可。

* 优点
  * 实现简单
  * 仅需要一次访存，无需专门计算
* 缺点
  * 由于形式地址长度有限，寻址范围存在限制
  * 操作数的地址不易修改

### 2、间接寻址

形式地址指向一个主存单元，在该主存单元中存放着操作数的真实地址。

共需要<mark style="color:purple;">**三次访存**</mark>：取指令，指向主存单元→访问主存单元，得到真实地址→访问真实地址，得到操作数

还可以套娃，进行多次间接寻址。

* 优点
  * 可以扩大寻址范围
  * 便于编程
* 缺点
  * 需要多次访存

### 3、寄存器寻址

地址码部分给出的不再是地址，而是<mark style="color:orange;">**寄存器编号**</mark>。相应的寄存器中存放着真实地址。

* 优点
  * 仅需要一次访存（取指令）
  * 指令执行阶段无需访存，执行速度快
  * 支持向量、矩阵运算
* 缺点
  * 寄存器价格较高，计算机中寄存器的数量有限

### 4、寄存器间接寻址

地址码部分给出寄存器序号。寄存器中存放着主存单元地址，该主存单元中存放着真实地址。

需要两次访存：取指令→执行指令（访问真实地址）

* 优点
  * 相较于间接寻址，速度更快

### 5、隐含寻址

指令中仅给明一个地址，而另一个地址默认位于某个寄存器中（如ACC）

* 优点
  * 有利于缩短指令字长
  * 简化地址结构
* 缺点
  * 需要增加相应的硬件

### 6、立即寻址

指令中存放的不是地址，而是<mark style="color:orange;">**直接存放的操作数**</mark>。

一般寻址特征表现为“#”，相应的操作数又被称为<mark style="color:orange;">**立即数**</mark>，一般用补码表示。

* 优点
  * 仅需要一次访存
  * 执行速度最快
* 缺点
  * 地址码的位数限制了立即数的范围

### 7、基址寻址

将CPU中基址寄存器（BR）的值加上形式地址所表示的偏移量，得到真实地址。

基址寄存器中存放的是<mark style="color:orange;">**当前程序起始的存放地址**</mark>。

{% hint style="warning" %}
操作系统中的“重定位寄存器”其实就是基址寄存器。
{% endhint %}

当计算机中没有基址寄存器时，需要指明使用某个寄存器来充当基址寄存器。

* 优点
  * 便于程序“浮动”（可以存储在主存中的任何地方）
  * 方便多道程序并发运行

{% hint style="warning" %}
在程序运行开始前，CPU会将PCB中的程序起始地址存放进BR中。

用户无法修改BR的内容，只能指定某个寄存器充当BR。
{% endhint %}

* 优点
  * 可以扩大寻址范围
  * 用户不必考虑程序存储在主存的什么位置，便于浮动编程
  * 便于多道程序设计

### 8、变址寻址

与基址寻址类似，将变址寄存器（indexer register，IX）中所存放的值与形式地址中的偏移量相加，得到真实地址。

不同的是，IX是面向用户的，<mark style="color:orange;">**用户可以修改IX中的值**</mark>。

例如，可以将IX的值设为数组的首地址，之后通过不断对IX进行比较运算、加法运算改变IX的值，完成对数组的遍历。

* 优点
  * 适合循环程序的编写
  * 适合处理数组问题

{% hint style="info" %}
可以将变址寻址和基址寻址联合使用，对整段程序采用基址寻址，而对于循环体再次采用变址寻址。
{% endhint %}

### 9、相对寻址

将PC中存放的值与形式地址中的偏移量相加，得到真实地址。

即A是对PC中地址的偏移量，一般采用补码表示。

{% hint style="danger" %}
PC中存放的是<mark style="color:orange;">**下一条指令**</mark>的地址

因此使用相对寻址来用于<mark style="color:purple;">**跳跃寻址**</mark>之中，保证地址的正确
{% endhint %}

* 优点
  * 循环时不用更改跳跃指令的地址码
  * 多道程序设计中，程序可能会在内存中浮动，需要用到

### 10、堆栈寻址

在堆栈数据结构中，存在堆栈指针（SP），当执行出入栈操作时，SP会自动+1（-1），指向新的栈顶元素。

存在用寄存器实现的硬堆栈和存放在主存中的软堆栈。

堆栈可用于函数调用时保存当前函数的相关信息。


---

# Agent Instructions: Querying This Documentation

If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter:

```
GET https://aye10032.gitbook.io/computerorganizationnote/di-si-zhang-zhi-ling-xi-tong/4.2-zhi-ling-de-xun-zhi-fang-shi.md?ask=<question>
```

The question should be specific, self-contained, and written in natural language.
The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
