What & How & Why

差别

这里会显示出您选择的修订版和当前版本之间的差别。

到此差别页面的链接

两侧同时换到之前的修订记录前一修订版
后一修订版
前一修订版
cs:comp_n_arch:courses:fnti_i:week_6 [2025/05/19 09:49] – [Variable symbols] codingharecs:comp_n_arch:courses:fnti_i:week_6 [2025/05/19 14:24] (当前版本) – [Developing a Hack Assembler] codinghare
行 113: 行 113:
 ===Variable symbols=== ===Variable symbols===
 变量类型的 symbol 指非提前定义的,且没有使用 driective 在别处进行定义的(比如 ''LOOP'')的 symbol。上面例子中的 ''@i'',''@sum'' 都是变量类型的 symbol。之前提到过,这类 symbol 都会被存储在一个独特地址的内存单元中(地址从 ''16'' 开始)。因此这类 symbol 对应的值,是他们所在内存单元的地址: 变量类型的 symbol 指非提前定义的,且没有使用 driective 在别处进行定义的(比如 ''LOOP'')的 symbol。上面例子中的 ''@i'',''@sum'' 都是变量类型的 symbol。之前提到过,这类 symbol 都会被存储在一个独特地址的内存单元中(地址从 ''16'' 开始)。因此这类 symbol 对应的值,是他们所在内存单元的地址:
-^symbol^value^+^Symbol^value^
 |i|16| |i|16|
 |sum|17| |sum|17|
 +由于变量可能会被多次用到,当第一次用到时,该变量 symbol 和其对应地址会被加入到映射表中;之后再使用时,汇编器会从映射表中查找到该对应关系,并把 symbol 翻译为对应的地址。
 +===Symbol table===
 +可以看到的是,上述的所有翻译都依赖于一种数据结构://Symbol table//,用于建立翻译的映射关系。Hack 计算机的 Symbol table 通过几个阶段进行构造:
 +  * 初始化:这个阶段会建立一张空表,并将 pre-defined symbol 的映射关系写入表中
 +  * 寻找 label 声明:这个阶段(//first pass//)会扫描整个指令序列,将所有的 label 声明找出来
 +    * 当遇到 ''('' 的时候,就识别为 label 的声明
 +    * 同时维护一个计数器,对行数计数。记录的是**已经扫描过的行数**:比如之前的 ''(LOOP)'',其对应的数据是之前已经扫描过的行数 ''4''
 +    * 然后接着扫描,直到遇到下一个 ''('' 开头的 label 声明,重复上面的过程,直到构建出整个 Symbol table 中的 label 声明数据
 +  * 变量处理(//second pass//):这个阶段会再次扫描指令序列,寻找**变量**,再将其与 RAM地址关联,并写入关系到 //Symbol table// 中:
 +    * 新变量会直接加入 symbol table
 +    * 已存在的变量会直接读取 symbol table 中的对应映射关系
 +
 +===Assembly process===
 +<code cpp>
 +// init
 +- construct an empty symbol table
 +- add the pre-defined symbols to the symbol table
 +
 +// first pass
 +// adding label declaration to the symbol table
 +- scan the program
 +- For each instruction of the form(xxx):
 +    - add the pair(xxx, address) to the symbol table, where address is the number of the instruction following (xxx)
 +
 +// second pass
 +// adding variable symbol to the symbol table
 +- scan the program
 +- For each instruction:
 +    - if the insturction is @symbol, look up the symbol in the table
 +        - if (symbol, value) is found, use value to complete the instruction's translation
 +        - if not found
 +            - add(symbol, n) to the symbol table
 +            - use n to complete the instruction translation
 +            - ++n
 +    - if the instruction is a C-instruction, complate the instruction translation
 +- write the translated instruction to the output file
 +</code>
 +