# 1.8 指令和程序（Instructions & Programs）

1.8 指令和程序（Instructions & Programs）

2022-10-02

Table of Contents

## 1.8.1 指令集

指令由「操作码」和「地址码」组成，前者用于说明操作指令，后者则表示操作数据的地址（寄存器或内存地址）。记录指令名称、用法、操作码以及所需 RAM 地址/寄存器位址的表格，称为「指令集」。

![常见指令集\]](https://275040345-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FycDQGvckh16RY095vh62%2Fuploads%2FbGp03tFMIaf7ChXyfa6g%2F0.png?alt=media)

指令集使得身为硬件的 CPU 是「可编程」（programmable），其可以被软件控制做到硬件本身无法完成的事前，比如下图就是用仅能做加减的 ALU 实现计算余数（e.g. 11 / 5 -> 1）的例子（下图的实现需要多个时钟周期，很低效）。

![除法指令串](https://275040345-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FycDQGvckh16RY095vh62%2Fuploads%2F2zv4UeMr2yVxS9vo212F%2F1.png?alt=media)

## 1.8.2 指令执行

### JUMP

用于改变指令的顺序，或是跳过一些指令。JUMP 的底层实现方式是将指令后四位代表的内存地址的值覆盖掉「指令地址寄存器」里的值。

![JUMP](https://275040345-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FycDQGvckh16RY095vh62%2Fuploads%2FiQVfiI3WsgpNE3YO0FlX%2F2.png?alt=media)

为了避免无限循环（infinite loop）, JUMP 可以设置为有条件的，比如 JUMP NEGATIVE（在 ALU 的负标志位为真 true 时进行 JUMP）、JUMP IF EQUAL（如果相等）、JUMP IF GREATER（如果更大）。

### HALT

用于停止执行指令程序，同时也是区分指令和数据的标志（指令和数据在同一内存中均以二进制进行存储）。

## 1.8.3 指令长度

本例中的 CPU 指令为 8 位，前 4 位为操作码，后 4 位为地址码，至多支持 个操作，远远无法满足需求。现代 CPU 通常使用两种方法来拓展指令长度（the instruction length）：

（1）使用更多位数表示指令，如 32 位或 64 位。

（2）采用「可变指令长度」（variable-length instructions），指令长度任意，但指令读取稍显复杂。以 8-bit 操作码的 CPU 为例，其遇到 HALT 这类无序额外数据的指令会立即执行，遇到 JUMP 这类需要位置值信息的指令（又名「立即值」（Immediate Value））会明白所需位置值在 JUMP 后面。

![Intel 4004 指令集](https://275040345-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FycDQGvckh16RY095vh62%2Fuploads%2FiKkLWYWR4eeFq74bkix5%2F3.png?alt=media)

1971 年 Intel 4004 CPU 发布，这是第一个单芯片 CPU，支持 46 个指令。为了表示更多的内存地址，其使用 8-bit 立即值来执行 JUMP。经多年发展，如今的 Intel i7 已有上千指令和指令变种，指令长度在 1\~15 个字节中变化。
