天天看点

指令和程序jump指令jump negativeALU 除法32位 64位真实cpu

jump指令

首先指令地址寄存器从0开始,LOAD A14,把1存入寄存器A(因为地址14里的值是1)

指令和程序jump指令jump negativeALU 除法32位 64位真实cpu

然后指令地址寄存器跳到1,把1存入寄存器B

指令和程序jump指令jump negativeALU 除法32位 64位真实cpu
指令和程序jump指令jump negativeALU 除法32位 64位真实cpu

现在寄存器A的值是2(当然是二进制存的)

指令和程序jump指令jump negativeALU 除法32位 64位真实cpu

现在遇到jump2,cpu会把指令地址寄存器的值,现在是4改成2

指令和程序jump指令jump negativeALU 除法32位 64位真实cpu

因此下一步不是HALT,而是读取地址2里的指令,也就是ADD B A

指令和程序jump指令jump negativeALU 除法32位 64位真实cpu

跳转后,寄存器A里是2寄存器B里是, 1+2=3,寄存器A变成3,存入内存 ,这样永远碰不到HALT,这叫无限循环,程序会永远跑下去。

为了停下来,我们需要有条件的JUMP,只有条件满足,才执行jump,比如jump negative就是条件跳转的一个例子,还有其他类型如 jump if equal(如果相等),jump if greater(如果更大)

jump negative

指令和程序jump指令jump negativeALU 除法32位 64位真实cpu
指令和程序jump指令jump negativeALU 除法32位 64位真实cpu
指令和程序jump指令jump negativeALU 除法32位 64位真实cpu

6存入a

指令和程序jump指令jump negativeALU 除法32位 64位真实cpu

因为6是正数,所以负数标志是假的,因此不会执行jump,继续执行至jump2

指令和程序jump指令jump negativeALU 除法32位 64位真实cpu

a变成1 ,下一次1-5=-4位负数,这次alu负数标志是真

指令和程序jump指令jump negativeALU 除法32位 64位真实cpu
指令和程序jump指令jump negativeALU 除法32位 64位真实cpu

跳出无限循环,现在指令ADD BA -4+5=1,存入寄存器A

指令和程序jump指令jump negativeALU 除法32位 64位真实cpu

最后碰到HALT 停了下来,虽然程序只有7个指令,但cpu执行了13个指令,因为内部两次循环,这些代码其实是算余数的11除5余1

ALU 除法

alu不具备除法功能,是程序给了我们这个功能。别的程序也可以用我们的除法程序,来做其他的事情。

32位 64位

如果用上图的方法来使用,由于操作指令由4位表示,则只能由16个操作指令,且内存地址也只有16个,这样都无法使用jump 17,因为4位二进制无法表示数字17。

因此现代由两种方法来处理这个为题

最直接方法用更多位来代表指令,比如32位 64位,这叫指令长度。

第二种方法“可变指令长度”,举个例子,比如某个cpu用8位长度的操作码,如果看到HALT指令,HALT不需要额外数据。会马上执行,如果看到JUMP,它得知道位置值,这叫“立即值”,这样设计指令可以是任意长度,但让读取阶段复杂了一点点

真实cpu

指令和程序jump指令jump negativeALU 除法32位 64位真实cpu
指令和程序jump指令jump negativeALU 除法32位 64位真实cpu
指令和程序jump指令jump negativeALU 除法32位 64位真实cpu
指令和程序jump指令jump negativeALU 除法32位 64位真实cpu

例如光ADD指令就有很多变种