极客的计算机入门课程:公开课从与非门到俄罗斯方块[Nand to Tetris]

博客中的文章均为meelo原创,请务必以链接形式注明本文地址

Build a Modern Computer from First Principles: Nand to Tetris Part II (project-centered course)
by: Noam Nisan & Shimon Schocken
from: Hebrew University of Jerusalem
课程链接:https://www.coursera.org/learn/nand2tetris2/home
课程第一部分的介绍:http://www.cnblogs.com/meelo/p/5559453.html
伴随这门公开课,还有一本书《计算机系统要素》

在文章《从零开始设计一台计算机?记公开课从与非门到俄罗斯方块》中,我介绍了这门课的基本理念——从零开始设计一台计算机。在课程的第一部分,课程用与非门建造了算数逻辑单元,用触发器建造了内存,进而用算数逻辑单元和内存构建了一台能够运行机器指令的硬件。课程的第一部分主要涉及计算机的硬件,而第二部分将主要涉及计算机的软件。不像第一部分,课程不需要任何先修知识,这门课需要你具有高级编程语言的基础,编程作业需要用Java或者Python完成。在编程作业中,你需要设计一个编译器将Jack高级语言编译成为汇编语言。

课程全貌

上面这张图就展示了课程的全貌,课程第二部分主要针对于图片上侧的软件部分。下面将简要介绍课程每一周所学习的内容,并非一个完整的学习笔记。你可以根据所涉及的知识点,来决定是否需要来学习这一门课。

第一周

课程需要设计的编程语言类似于Java,引入了一个虚拟机层,高级语言需要经过双层编译成为汇编语言。这一周介绍了虚拟机的结构及虚拟机指令,以及如何将虚拟机指令转换成汇编指令。虚拟机是一种堆栈结构机器,由8个抽象的堆栈组成。虚拟机的指令有4种,分别是算数逻辑运算指令、内存分区指令、分支指令和函数指令。这一周和下一周的编程任务就是实现一个VMTranslator,将虚拟机指令转换成汇编指令,这一周需要实现算数逻辑运算指令和内存分区指令,下一周需要实现分支指令和函数指令。课程的视频中详细介绍了每一个虚拟机指令的功能,和大致的实现流程,但并没有给出具体的实现,这就是项目中最难的一部分,有的虚拟机指令可需要绞尽脑汁才能想出实现方案。

四类虚拟机指令
算数逻辑运算指令 add sub neg and or not eq gt lt
内存分区指令 push pop
分支指令 label goto if-goto
函数指令 function call return

第二周

这一周的项目需要实现上一周所剩余的分支指令和函数指令。分支指令很简单,函数指令就难很多了。函数作为高级语言很重要的一种抽象,在函数调用和返回的时候需要借助堆栈数据结构,同时需要进行很多额外的步骤来处理调用函数的参数、函数内状态的保存和函数内的局部变量。需要深入理解函数调用和返回的流程才能够用汇编指令实现出函数指令。函数调用和返回的过程非常精妙,在函数调用之前需要把函数的参数入栈到堆栈中,同时把函数的当前状态保存到堆栈,函数内的局部变量也需要事先在堆栈内开辟空间;函数返回时需要恢复调用函数的状态,保存返回值到堆栈中,最后跳转到调用函数中。


函数的调用栈

第三周

这一周会介绍针对这门课所设计的高级语言Jack。Jack是一种类似于Java的语言,拥有对象,对象有静态变量和实例变量,区分函数和方法,可以动态初始化生成实例;Jack像一般的高级语言一样拥有if语句和while语句,但是没有for语句;Jack有int、char和boolean三种基本数据类型,但是没有浮点类型;Jack包含运算符加减乘除、小于、大于、等于以及取非,但没有小于等于和大于等于。Jack语言很简陋,相比现代的商业化语言很不人性化,所有的Jack语言要求所有的的变量声明都需要以var起始,所有的赋值语句需要以let开始,所有的函数调用需要以do起始。虽说Jack各种不方便,写程序时无数次忘掉do和let,有时需要用到小于等于时,非得用非大于来实现,用着这种怪异的写法简直想骂街。但是麻雀虽小五脏俱全,所有没有的语法其实都可以用已有的语法实现,比如for语句可以用while语句实现。这一周的项目就是用Jack设计一个程序,程序的功能自由发挥。在网络上,你可以找到很多Jack语言实现的游戏,比如俄罗斯方块、2048。我也挑战了一下自己,实现了一个游戏了一个贪吃蛇,第一次做游戏,看看怎么样。

用Jack语言编写的贪吃蛇游戏

第四周

接下来的两周的任务是实现一个编译器。编译器由三个部分组成,分别是分词器(tokenizer)、语法解析器(parser)和代码生成器(code generator)。编译器的工作经过分解,变成三个步骤后就变得简单了许多。这周的项目需要实现分词器和语法解析器,代码生成器的实现是下周的任务。高级语言里符号可以以空格、缩进符为符号的分隔符,如果可以判断为两个符号也可以不需要分隔符,分词器就是根据符号间复杂的分隔关系将源程序分割中一个个符号。编程语言的语法可以用形式化的方法来表示,下图就展示了Jack语言的一部分语法。语法解析器的功能就是根据语法的形式化描述把属于同一程序结构的token流汇聚在一起,不同的程序结构相互嵌套构成了一颗树。


Jack语言的部分语法

第五周

这一周的任务是实现编译器最后的一部分,代码生成器。在代码生成器的实现中,基本上每一条语法规则由一个函数实现。语法规则的嵌套关系可以由函数的嵌套调用所体现。课程提供了代码生成器的代码框架,所以你只需要填充每一个函数的功能就行了,这大大降低了问题的难度。一些语法规则的实现很简单,而另一些语法规则的实现会很难,最为复杂的一个语法是term,不光代码的行数最多,在实现过程中还犯了几个错误。一些语法规则的实现具有相当的启发意义,比如if语句、while语句、字符串的实现、以及实例方法的调用,这只有你亲自实现才能体会到。课程还提供了测试的方法,每一组测试用例均提供了Jack源程序和虚拟机程序,通过对比给出的虚拟机代码和用程序生成的虚拟机代码就能查找程序哪个地方写错了。


编译器的工作流程示意图

第六周

介绍了操作系统。这个操作系统可谓简陋,其实它只是个库函数,包含8个类,分别是Math、String、Array、Output、Screen、Keyboard、Memory、Sys。这一周的内容很杂,走马观花式地介绍了很多内容。Math实现了基本的数学运算,由于课程中所设计的CPU并不支持乘除法,Math类里需要实现乘除操作,课程里介绍了一个复杂度为log(n)的乘除法实现;String类实现了字符串的操作;Array类实现了数组;Output类实现了将字符显示在屏幕上的功能,为此课程还设计了一个专门的字体,同时在这还介绍了中断中cursor的抽象。Screen类处理图形的绘制,包括直线矩形和圆,没有思考过不知道,其实在屏幕上画直线其实挺难的。Keyboard类实现了键盘的相关操作,包括如何读入字符、整数;Memory类处理类初始化时的动态内存分配,一个难点是如何管理内存。


操作系统的8个库函数

从零开始设计一个计算机,这是一个相当有挑战的课程,它涉及了数字逻辑设计、汇编语言、编译器、高级语言等诸多的理论知识。如果你完成了全部的两门课程,我保证你肯定会有相当大的收获。课程的标题里写着以项目为导向,其实名不虚传,所有视频授课的内容都直接与项目相关,没有一点废话。这种课程的组织方式对于学习者来说十分有益,通过编程来实践课程里所涉及的知识能够检验出你是否真正理解了。可以说公开课从与非门到俄罗斯方块是一门非常不错的计算机入门课程,五星推荐给对计算机的组成或者是计算机工作原理感兴趣的人。

彩蛋
课程的第二部分还没有结束,老师在课程的结尾透露还会有第三部分,内容会是用FPGA将计算机真正搭建在硬件上,期待下一次美妙的学习之旅!

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 203,362评论 5 477
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 85,330评论 2 381
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 150,247评论 0 337
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 54,560评论 1 273
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 63,580评论 5 365
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,569评论 1 281
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 37,929评论 3 395
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,587评论 0 258
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 40,840评论 1 297
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,596评论 2 321
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,678评论 1 329
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,366评论 4 318
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 38,945评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,929评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,165评论 1 259
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 43,271评论 2 349
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,403评论 2 342

推荐阅读更多精彩内容

  • 计算机组成原理课程在计算机系统中的位置 图1描述了计算机系统抽象层的转换。从图1可以看出,计算机系统由不同的抽象层...
    开点工作室阅读 3,342评论 16 55
  • Android 自定义View的各种姿势1 Activity的显示之ViewRootImpl详解 Activity...
    passiontim阅读 171,392评论 25 707
  • 那天我们说起来曾经,你说我们还来得及吗? 从最初的借你手机玩游戏,侃侃瞎聊上课睡着,一起像菜鸟一样学业务 忽然一个...
    北极熊看见了刚果拉阅读 235评论 0 0
  • 文.孙亮 你问我世态炎凉我回你岁月沧桑我的它你流走何方清晨骄阳落霞里却渗透着迷茫漆黑的夜里栅栏旁目光无助的打量一阵...
    朦胧诗人孙亮阅读 399评论 0 5
  • 初夏的风是焖湿的,徐来阵阵栀子花香,周末难得早起,沿着古城坑坑洼洼的青石板路,散着步,也散着心。晨早...
    天行健君马甲阅读 225评论 0 4