本 Wiki 开启了 HTTPS。但由于同 IP 的 Blog 也开启了 HTTPS,因此本站必须要支持 SNI 的浏览器才能浏览。为了兼容一部分浏览器,本站保留了 HTTP 作为兼容。如果您的浏览器支持 SNI,请尽量通过 HTTPS 访问本站,谢谢!
这是本文档旧的修订版!
Week 6 notes
汇编器重复以下的功能:
以下面的汇编代码为例:
// Start processing the table
Load R1, 18
Load
, R1
, 18
汇编语言中存在着 symbols,以便提高程序的可读性,比如:
JMP loop
Load R1, weight
而在汇编器翻译的过程中,这些 symbols 都会被替代为其对应的地址,比如 loop
对应的是跳转后的指令地址,weight
对应的是在 RAM 里面的寄存器所属地址。这种翻译也是依赖对应的 map 来实现的:
第一次进入 symbol table 的变量需要汇编器为其安排 table 中的位置。通常,汇编器会在 RAM 中找到第一个可用的内存单元(Unallocated memory cell)来存放该变量。
Label 需要处理额外的两件事:
需要汇编器处理的元素有:
对于 ROM 所有的指令:
A 指令的结构表现为: @ + value
,因此将 A 指令转化为二进制取决于:
@21
),那么直接转成对应的 15
位的二进制常量
首先回顾一下,C 指令的机器语言组成如下图所示:
因此,如果希望翻译 C 指令,那么首先需要做的就是将汇编语言按照机器语言的组成来进行划分。通常这部分会由 Parser(解析器)来完成。以下面的汇编语句为例:
// 将 D + 1 的值存储到 M 和 D 寄存器中
MD = D + 1
接下来按如下的顺序进行翻译:
15-13
这三位永远都是 111
,可以将其先填入comp
这部分 12..6
(a
和 comp
)进行翻译。这部分通过对照 C 指令的 table 来获取二进制代码。比如例子中的计算部分 D+1
,对应的 a
是 0
,对应的六位 comp
是 011111
,那么这一部分对应的代码就是 0011111
dest
这部分 5..3
进行翻译。这部分的翻译也是通过查表:比如例子中的 MD
,对应的是 011
jump
这部分 2..0
进行翻译,同样也是通过查表:本例中没有跳转部分(null),对应的 bits 是 000
111 0011111 011 000
之前介绍过,根据 symbol 的内容,可以将 symbol 划分为三种类型:
goto
跳转的指令位置由于这些 symbol 只会在 A 指令中出现,因此只需要根据对照表,将 symbol 转化为对应的地址值即可:比如
// R1 corresponds address 1
@R1->@1
label 类型的 symbol 主要用于:
@loop
。这类 symbol 会被直接替换成其值(与 pre-defined symbol 类似),比如下面例子中的 LOOP
会被替换为 16
(loop)
:这类 label 通常不会进行翻译,但汇编器遇到这类 label 时,会将其对应的 symbol 与其起始行关联起来。比如:
@i // line 0
M=1
@sum
M=0
(LOOP) // not a instruction line
@i // line 4
...
@LOOP //line 16
这里的 (LOOP)
标签,对应的 block 起始行为 4
;这个关系将会使用一张表来维护:
Symbol | value |
---|---|
LOOP | 4 |
变量类型的 symbol 指非提前定义的,且没有使用 driective 在别处进行定义的(比如 LOOP
)的 symbol。上面例子中的 @i
,@sum
都是变量类型的 symbol。之前提到过,这类 symbol 都会被存储在一个独特地址的内存单元中(地址从 16
开始)。因此这类 symbol 对应的值,是他们所在内存单元的地址:
symbol | value |
---|---|
i | 16 |
sum | 17 |