现在用 JUMP 让程序更有趣一些。
我们还把内存中 3 和 14 两个数字,改成 1 和 1,现在来从 CPU 的视角走一遍程序。
-
首先 LOAD_A 14,把 1 存入寄存器A(因为地址 14 里的值是 1)。
-
然后 LOAD_B 15,把 1 存入寄存器B\N(因为地址 15 里的值也是 1)。
-
然后 ADD B A 把寄存器 B 和 A 相加, 结果放到寄存器 A 里,现在寄存器 A 的值是 2 (当然是以二进制存的)。
-
然后 STORE_A 13 指令,把寄存器 A 的值存入内存地址 13。
-
现在遇到 JUMP 2 指令,CPU 会把"指令地址寄存器"的值,现在是 4,改成 2。因此下一步不再是 HALT,而是读内存地址 2 里的指令,也就是 ADD B A,我们跳转了。
-
寄存器 A 里是 2,寄存器 B 里是 1,1+2=3,寄存器 A 变成 3,存入内存。
-
又碰到 JUMP 2,又回到 ADD B A,1+3=4,现在寄存器 A 是 4。
发现了吗?,每次循环都+1,不断增多。但没法结束啊,永远不会碰到 HALT。总是会碰到 JUMP,这叫无限循环 - 这个程序会永远跑下去.. 下去.. 下去.. 下去。
条件JUMP
为了停下来,我们需要有条件的 JUMP,只有特定条件满足了,才执行 JUMP。比如 JUMP NEGATIVE 就是条件跳转的一个例子,还有其他类型的条件跳转,比如 JUMP IF EQUAL(如果相等) JUMP IF GREATER(如果更大)。
现在把代码弄花哨一点,再过一遍代码
-
就像之前,程序先把内存值放入寄存器 A 和 B。寄存器 A 是 11,寄存器 B 是 5。
-
SUB B A,用 A 减 B,11-5=6。6 存入寄存器 A。JUMP NEGATIVE 出场,上一次 ALU 运算的结果是 6。是正数,所以 "负数标志" 是假,因此处理器不会执行 JUMP。
-
继续下一条指令,JUMP 2,JUMP 2 没有条件,直接执行!又回到寄存器 A-B,6-5=1,A 变成 1。
-
下一条指令,又是 JUMP NEGATIVE。因为 1 还是正数,因此 JUMP NEGATIVE 不会执行。
-
来到下一条指令,JUMP 2,又来减一次,这次就不一样了,1-5=-4,这次ALU的 "负数标志" 是真。
-
现在下一条指令,JUMP NEGATIVE 5, CPU 的执行跳到内存地址 5
-
跳出了无限循环!
-
现在的指令是 ADD B A,-4+5=1,1 存入寄存器 A。
-
下一条指令 STORE_A 13,把 A 的值存入内存地址 13
-
最后碰到 HALT 指令,停下来。
软件的强大之处
虽然程序只有 7 个指令,但 CPU 执行了 13 个指令,因为在内部循环了 2 次。这些代码其实是算余数的,11除5余1,如果加多几行指令,我们还可以跟踪循环了多少次,11除5,循环2次,余1。
当然,我们可以用任意2个数,7和81,18和54,什么都行,这就是软件的强大之处,软件还让我们做到硬件做不到的事。
明天我们将会讲通过一个实际例子也讲CPU的核心原理。
相关阅读: