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

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 和如何写一个汇编语言的汇编器。

相关推荐
Estar.Lee2 小时前
查手机号归属地免费API接口教程
android·网络·后端·网络协议·tcp/ip·oneapi
2401_857610033 小时前
SpringBoot社团管理:安全与维护
spring boot·后端·安全
凌冰_4 小时前
IDEA2023 SpringBoot整合MyBatis(三)
spring boot·后端·mybatis
码农飞飞4 小时前
深入理解Rust的模式匹配
开发语言·后端·rust·模式匹配·解构·结构体和枚举
一个小坑货4 小时前
Rust 的简介
开发语言·后端·rust
monkey_meng5 小时前
【遵守孤儿规则的External trait pattern】
开发语言·后端·rust
Estar.Lee5 小时前
时间操作[计算时间差]免费API接口教程
android·网络·后端·网络协议·tcp/ip
新知图书6 小时前
Rust编程与项目实战-模块std::thread(之一)
开发语言·后端·rust
盛夏绽放6 小时前
Node.js 和 Socket.IO 实现实时通信
前端·后端·websocket·node.js
Ares-Wang6 小时前
Asp.net Core Hosted Service(托管服务) Timer (定时任务)
后端·asp.net