计算机基础系列 —— 汇编语言

Same hardware can run many different programs(Software)

文中提到的所有实现都可以参考:nand2tetris_sol,但是最好还是自己学习课程实现一遍,理解更深刻。

我们在之前的文章里,构建了 Register、RAM 和 ALU,使得我们有了存储和计算的能力,我们接着借助之前的组合逻辑单元和时序逻辑单元把 Register、RAM 和 ALU 就可以构建一个电脑架构(Hack),如下图:

这篇文章我们先介绍运行在这个架构上的汇编语言,用来编写在这个电脑架构上可以运行的程序,后面的文章会介绍这个电脑架构如何实现。我们了解汇编语言之后,也会实现自己的汇编器,把汇编语言编译成机器语言,如下图。

所以我们可以通过汇编语言的指令集来操作 Program、data 和 CPU 里的寄存器(具体是 A 和 D 两种寄存器),参考下图。

接下来我们来看看 Hack 的汇编语言里的指令集 A 指令和 C 指令,以及控制流、变量和标签。

A 指令

A 指令很简单,当我们写 @19 的时候就代表 Address register 被设置成 19(CPU 会帮我们干这件事,后面我们会实现这颗 CPU),而且 RAM[A] 和 ROM[A] 会被自动选中,Hack 汇编语言用 M 表示 RAM[A]。

C 指令

C 指令要复杂一些,有如下这些指令:

我们看一些例子,学习 C 指令的使用。

给 Data Register 赋值

给 RAM 赋值

控制流

这里用 A 指令选择存储在 ROM 里需要执行的指令,每条指令存储在 ROM 里的一个 Register 里。

变量

把 A 指令里的 const 替换成 symbol(变量名)即可,这里把变量名绑定到对应的 const 的工作是我们后面文章介绍的汇编器做的,这些 symbol 实际在 ROM 里不存在,汇编器帮我们实现了 symbol 和 地址的映射关系,我们来看一些例子:

汇编器还帮我们预定义了一些 Register,方便我们使用:

标签

sym 帮我们定义了数据的相对地址,这样我们不用记住数据(RAM)对应的绝对地址,就可以访问数据。同理,我们需要新的 sym 帮我们定义控制流的相对地址,我们用 (sym) 表示,这样我们不用记住程序段的绝对地址,就可以通过标签访问对应的程序段(ROM)。

我们需要 infinite loop 确保程序不会执行想要运行程序外的程序(用来表示程序结束):

有了控制流和标签,我们就相当于可以实现 for 循环:

指针

这里是这门课我最喜欢的部分之一,学习这门课之后你可以清清楚楚的知道指针是什么,而不是捧着《c++ primer》看大段的指针是什么的描述。

结合用 C++ 指针的写法写一下上面的汇编语言:*R0 = -1。我们对指针的理解更深刻了。来看一下更复杂点的例子:

数组

实际上就是通过指针访问的一连串数字,理解了指针,就可以理解数组了,我们看下例子:

我们可以看到程序定义了长度为 5,arr[1] = 100 的数组,并计算了数组所有元素相加的和。

A 指令和 C 指令总结

接下来我们来看二进制版本的指令集,我们编程还是用汇编语言,但是汇编器会把汇编程序翻译成下面的二进制版本加载到 ROM 里运行。

二进制版本指令集

I/O(输入和输出)

  • 输入

可以看出 RAM 里的一个寄存器用来连接键盘,一个 Register 是 16-bit,足够表示键盘上的按键。例子:

  • 输出

输出设备是一个 256(row) * 512(col) 像素的黑白屏幕。

我们可以看到 1 代表黑色,0 代表白色,每 32 个寄存器代表屏幕里的一行像素。

课程里有两个小项目帮助理解内容,一个是计算两个寄存器的乘积,一个是通过按键控制屏幕全黑或者全白,感兴趣的可以看文章开头的 github 实现,也可以自己学习课程实现。

接下来的文章会介绍如何构建 CPU 和如何写一个汇编语言的汇编器。

相关推荐
追逐时光者4 小时前
推荐 12 款开源美观、简单易用的 WPF UI 控件库,让 WPF 应用界面焕然一新!
后端·.net
Jagger_4 小时前
敏捷开发流程-精简版
前端·后端
苏打水com5 小时前
数据库进阶实战:从性能优化到分布式架构的核心突破
数据库·后端
间彧6 小时前
Spring Cloud Gateway与Kong或Nginx等API网关相比有哪些优劣势?
后端
间彧6 小时前
如何基于Spring Cloud Gateway实现灰度发布的具体配置示例?
后端
间彧6 小时前
在实际项目中如何设计一个高可用的Spring Cloud Gateway集群?
后端
间彧6 小时前
如何为Spring Cloud Gateway配置具体的负载均衡策略?
后端
间彧6 小时前
Spring Cloud Gateway详解与应用实战
后端
EnCi Zheng7 小时前
SpringBoot 配置文件完全指南-从入门到精通
java·spring boot·后端
烙印6017 小时前
Spring容器的心脏:深度解析refresh()方法(上)
java·后端·spring