38、P1 W6 U6.1 汇编器 原理

视频:
如果本次课程对应的 Coursera 的视频打不开,可以点击下面链接
P1W6U6.1 - Assembly Languages and Assemblers

课程在
第5周,完成了Hack小电脑
第4周,学会写Hack小电脑的汇编语言

那么Hack小电脑还差一步 把 汇编语言,怎么变成二进制的程序。
第4周,我们相当于人肉翻译的,还利用老师给的模拟器测试了结果
第6周,我们要用一个 叫 assmebler(汇编器)的东西来翻译了。

左边是汇编语言,右边是机器语言。中间的汇编器就是用来翻译的

这节先讲 普遍的大部分的汇编器 是如何 将 汇编语言 翻译成 "01"机器语言。
本周后面课程再具体说Hack电脑的汇编器如何实现。

汇编器

首先它是一个程序,一个把我们写的汇编语言翻译成机器语言的软件。

第4周也隐约提到过,我们也可以直接写“0101”的机器语言,但比较繁琐,就是为了方便写程序,才发明了汇编语言,以及对应翻译用的汇编器。

好在课程里HACK小电脑不是世界上第一台发明的电脑,要不然我们就只能写“0101”的机器语言了。

现在通常情况是在一台电脑(下图左下)里通过Assembler(汇编器)把写好的汇编语言程序(下图左上)翻译成对应的机器语言。然后输入(烧写?)到HACK的ROM(程序存储)中去运行。

汇编器,如果用机器0101语言写出来汇编器,那将相当不容易,所幸这堂课不是在做世界上第一个汇编器,所以可以由高级语言来写HACK的汇编器本身。

现代的开发流程

下图是汇编器的一个基本工作流程

1 读下一行汇编语言指令
2 把这条汇编语言指令拆开成不同小段
3 查表每个小段 转成一个段0101码
4 组合每个0101码 成一行完整的机器语言
5 输出这一行机器语言

PS:汇编器,区别于高级语言的编译器之一,是汇编语言一行指令翻译成机器语言的一行。高级语言一般会编译成多行机器语言。

汇编器 工作流程

工作流程 详解

第一步

通常 汇编器 从 汇编程序文件,读出每一行汇编命令,当然会过滤掉注释行,如下图以“// ”开始的第一行。

然后放入类似一个比如类似字符串,或者如下图的所示。

“Load R1,18”是一个假设的汇编语言,我们的HACK的汇编语言下节课讲

第二步

通过空格、逗号等,将字符串分成三部分。

空格,和逗号 一般用来分割

第三步

通过查找 汇编语言 和 机器语言 的对应表(如图左下)。完成每一段的翻译

通过 对应表 进行翻译

第四步、第五步

将每一段机器码组合,有时候根据汇编语言的细节,也会加入一些额外的码。

最后将它们输出,通常是二进制文件格式,也可以是其它机器能运行的文件格式。

Symbols 符号

另外汇编语言里还有 两个符号 的处理方式值得留意。(关于 Labels 和 Variables ,回顾U4.7)

Labels: 如下图 loop,通常是 (Program)程序存储 里的指令的地址
Variables:如下图 weight,通常是 (Data)数据存储 里的变量的地址

关于 Labels 和 Variables ,回顾U4.7

这就引出一个 Symbol 和 地址 的对应表,如下图。

这里存了 Labels 和 Variables 对应的 存储地址。

符号地址表

先假设汇编器碰到一个 Variable 变量 weight 如图,先查表,如果没有weight,那么汇编器就会分配一个数据寄存器给 weight,然后把这个weight 和 给定的寄存器地址,存在 “符号地址表” 里。下次用的时候就能从地址取出 weight 的值。

Variables 变量 出现在 RAM 里 哈佛架构的 数据存储区

那如果汇编器碰到一个 Label 的声明,如下图“Label loop” 就会把loop 的下一行指令的地址存在表里。

在JMP 调用 这个 Label loop 时,就可以查表得出要 跳转 的 指令地址。

U4.7 回顾 Label 的 声明 和 使用

另外还有一种情况(Forward refernces):Label 的声明 在 调用 的程序后出现。
那么在 程序前面 调用时,就不知道对应 Label 定义的什么。

这种情况下,两种解决办法:如下图,
1 难度大点,先留空,然后再修复。整个程序一个循环处理完成。
2 简单巧妙,把程序处理两次,第一次处理时,调用没找到就跳过,但在后面运行时声明会存入符号地址对应表。第二次处理时,调用就有了。


Forward references

这节课基本讲了 一般的汇编器 是 如何翻译 汇编语言 成 机器语言的。
下面几节课就具体讲讲 HACK的汇编器。

你可能感兴趣的:(38、P1 W6 U6.1 汇编器 原理)