浅色/深色
指令和程序
虞嘉乐21 计算机 4 班
更多指令
加法的对立面:SUB
SUB 是减法,与 ADD(加法)指令相同,也要用两个寄存器
跳跳跳:JUMP
如果你想改变指令顺序,或者跳过一些指令,那 JUMP 就是你的不二之选。JUMP 的作用是让程序跳转到新的位置。
JUMP 的底层实现方式:用指令后 4 位代表内存地址的值覆盖掉指令地址寄存器中的值(指令地址寄存器可以理解为记录当前内存地址的值的记事本,每完成一次指令,指令地址寄存器都会加一)
JUMP 的好兄弟们
JUMP 的其中一个好兄弟,叫 JUMP_NEGATIVE。它只在 ALU 的负数标志为真时才进行跳转。
除此之外,还有 JUMO IF EQUAL(如果相等)、JUMP IF GREATER(如果更大)
请停下来:HALT
HALT 指令是停止,如果没有它的存在,电脑会崩掉,快说谢谢 HALT 哥。
HALT 很重要,能区分指令和数据,还能避免 CPU 不停运行下去后,去处理 STORE_A13 之后不是操作码的 0 而崩掉
指令的综合运用
无限的循环~ 循环~ 循环~
在运行之前,我们要先把内存中的 3 和 14 两个数字都改成 1。
首先,把 LOAD_A 14 和 LOAD_B 15 中的两个 1 分别存入寄存器 A 和 B 中,然后 ADD B A 把寄存器 B 和 A 相加,结果放在寄存器 A 中。之后,使用 ATORE_A 13 的指令,把结果存在内存地址 13 中。接下来,就是本次主角的隆重登场——JUMP2!这条指令的意思是把指令地址寄存器的值改成 2,那么,我们就在一次的回到了 ADD B A,我们又一次的将 A 和 B 的值相加,然后又一次的遇到了 JUMP2。就这样,不断地循环且无法触发 HALT,这就是无限循环。
如何利用 JUMP 的兄弟逃出循环
这一次,我们进行了微小的更改,比如说将 A 的值改成了 11,B 改成了 5,用 SUB 代替了 ADD,用到了 JUMP_NEGATIVE 指令,具体的更改如下图
现在,让我们跟着 CPU 走一遍。到了 SUB B A,用 A 减 B 等于 6,将结果存在 A 中。因为 6 不符合 JUMP_NEGATIVE 的跳转条件,故进行下一条指令。下一条是 JUMP2,那就再次跳回 SUB,再用 A 减去 B 结果为 1,依旧不符合,继续重复。这一次有了改变,A 减 B 结果是-4,符合了 JUMP_NEG 5 的跳转条件,接下来直接跳转到第五条指令 ADD B A,将 A B 的结果相加并存到寄存器 A 中,再根据下一条的指令,把 A 的值存在内存地址 13 中。最后,碰到了 HALT。现在,我们的程序终于可以休息了。
现代如何使用更多的指令
我们在这里假设的 CPU 都很基础,只有 4 位,只能操作 16 个地址。而现代的 CPU 有两种策略来增加能使用的指令。
最粗暴的方法 —— 更多的位
第一种方法十分简单粗暴,直接用更多的位来代表指令,现代常有的是 32 位和 64 位。
麻烦的技巧型 —— 可变指令长度
举个栗子,比如某个 CPU 用 8 位长度的操作码,如果看到 HALT 指令,HALT 不需要额外数据,那么会马上执行;看到 JUMP,它得知道位置值,这个值在 JUMP 后面,这叫立即值
这样设计,指令可以是任意长度,但会让读取阶段麻烦一些。
当然,这里要说明一下,我们拿来距离的 CPU 和指令集都是假设的,是为了展示核心原理。
最后再来展示一下我们的小美人 —— 4004 处理器
接下来
下一章,我们会讲到 CPU 更多的功能