翻译自:http://www.suppertime.co.uk/blogmywiki/2020/06/improved-microbit-cpu/
在第一版的micro:bit CPU中(用MakeCode编程),只有非常精简的4条指令,但它在许多方面都像第一代家用计算机中使用的微处理器,如Altair 8800、Commodore Kim-1和剑桥科学的MK14:
没有使用诸如MakeCode,Scratch,Python或BASIC之类的高级语言进行编程,而是使用二进制代码指令。
每个二进制代码代表一条指令,一条附加了数据的指令,或者仅仅是数据。
程序运行时,CPU 依次从内存中提取每个指令。
然后解析指令
CPU 执行该指令
使用程序步数计数器跟踪其在程序中的位置,并在每次需要获取新指令时在程序计数器中加1。
不断从内存中按顺序提取,解码和执行指令,直到到达暂停指令为止。
实际上,我们的简易CPU所能做的就是将两个数字加在一起,并使用LED以二进制形式显示答案。它只不过是一个计算器而已,但不是一个好的计算器,因为它不能减、乘或除。
因为设计指令的方式,它仅限于4条指令:
指令限制为5位二进制数,而不是早期计算机系统中通常使用的8位二进制,因为我希望能够在micro:bit的LED显示屏的一行上显示指令的内容,发光的LED代表1,不发光的LED代表0。
操作数(数据,在这种情况下为地址)存储在指令的最后3位中,所以仅剩下前两位对实际指令进行了编码。
这显然不是一个好主意,但是如果我仍然想保留5位指令以适合显示,就需要从操作码中将操作数拆分出来,这就是micro:bit CPU项目的版本2所做的。
新的CPU指令
在新的设计中,当CPU获取并解码需要操作数的指令(某些数据或可以在其中找到数据的地址)时,它将内存中的下一个地址解释为数据,而不是指令。它通过读取其内容并将程序步数计数器增加2而不是增加1来实现。
现在我们有5个完整的位来对指令编码,这样有31个指令而不再是4个。严格来说,可以有32个指令,但是我决定使00000成为无操作的操作码,也就是空指令。
31个指令听起来很多,但即使是早期8位处理器(如早期家用计算机中使用的6502)也有100多个指令。为了使这个项目保持简单,并仍然实现一些有用的功能,我决定使用最少数量的指令来实现一个简单的乘法算法:
该算法通过将6(保存在变量x中)乘以7(保存在变量y中)变为将6累加7次,每次累加时从y中减去1,当y达到零时循环停止,并在LED显示输出上显示答案。
为了使该算法在micro:bit CPU上能使用,需要具有将变量减1的功能。将变量减1称为递减。正如我们将看到的,在执行重复性任务时,递增和递减数字非常有用。
不过,我们原来的算法缺少了两个功能:
循环功能。
条件判断功能 —— 在y为零时,跳出循环。
第二点是根据计算结果改变改执行代码的功能,这是使计算机成为计算机而不仅仅是加法器的根本原因。这种分支能力(通过指令集采用不同的路径)也是查尔斯·巴贝奇(Charles Babbage)的分析引擎与更简单的差分引擎区分开来的原因,并使分析引擎(虽然从未建造)理论上成为一台通用计算机。
为了简单起见,我决定将循环和从循环中跳出的功能放在一条指令中:“如果不是零则跳转”。
当任何递减指令结果是0时,设立一个标志位。微处理器用内存来存储几个标志:这些是单个位,用来记录达到零(零标志)、变成负数(负数标志)或太大而超出一个字能存储的数字(进位标志)。
我们的新CPU程序使用变量zeroFlag作为零标志。这是一个布尔变量,这意味着像它只能有两个值,true或false,1或0。
这是新的指令集:
我本可以添加一些寄存器或堆栈来存储数据,可能会在将来的版本中这样做,但是为了简单起见,我只做了一个A累加器。您可以在其中存储数字或向其中添加数字,还可以增加或减少内存位置的内容,因此实际上您可以使用任意数量的内存位置作为变量或寄存器。
当开发这个程序时,可能会添加从累加器中减去数字的功能,以及将累加器存储在内存位置以及直接存储和相加数字的功能。
我们没有在乘法程序中使用上面的所有指令。下面是将5累加6次实现5乘6的程序:
它将数字5放到累加器中。它通过在内存的下一位中指定的存储位置中查找数字5:告诉CPU从存储位置8中获取数字。
接下来,它会将位置9的内容减1。这样可以跟踪我们添加了多少个5。
如果零标志未设立,则存储器位置4中的指令告诉它跳回到位置0 。它将继续执行此操作,直到在存储位置9达到零时设置零标志为止。
接下来,它使用显示屏底部一行的LED将结果(即累加器中的数字)输出为二进制数。然后,它到达HALT指令,停止解码和执行任何其他指令或数据,
时钟速度是多少?
我的micro:bit CPU没有用时钟来获取指令,而是依靠您按下按钮B来逐步执行程序。按下按钮A,将CPU置于执行模式,这样它不仅会在第一行LED上显示内存内容,还将执行任何指令。
可以在MakeCode的模拟器中模拟运行。按下按钮A进入程序执行模式,启动后您会听到高音。继续按下按钮B,您会看到它在相同的位置循环 -- 每次它都会向累加器加5,并将存储位置9减少1。累加5六次,就是5 x 6 = 30。当存储位置9达到0时,它在显示屏的下一行以及到达暂停指令时以二进制形式显示5×6的结果并发出低音。
你可以继续按下按钮B,但程序不会执行 —— 程序运行指示灯熄灭,它不会再解码或执行任何指令。
下面是它的代码 – 相当复杂的程序,但是我尝试在可能的地方使用函数,使它更易于理解。
识别二维码或者访问下面的链接,可以在线运行程序。
https://makecode.microbit.org/#pub:_97wd4uWiJfDD
本文分享自微信公众号 - MicroPython中文社区(MicroPython_cn)。
如有侵权,请联系 support@oschina.cn 删除。
本文参与“OSC源创计划”,欢迎正在阅读的你也加入,一起分享。
来源:oschina
链接:https://my.oschina.net/shaoziyang/blog/4653608