本 Wiki 开启了 HTTPS。但由于同 IP 的 Blog 也开启了 HTTPS,因此本站必须要支持 SNI 的浏览器才能浏览。为了兼容一部分浏览器,本站保留了 HTTP 作为兼容。如果您的浏览器支持 SNI,请尽量通过 HTTPS 访问本站,谢谢!
这里会显示出您选择的修订版和当前版本之间的差别。
两侧同时换到之前的修订记录前一修订版后一修订版 | 前一修订版 | ||
cs:comp_n_arch:courses:fnti_i:week_6 [2025/05/19 08:44] – [外部总逻辑] codinghare | cs:comp_n_arch:courses:fnti_i:week_6 [2025/05/19 14:24] (当前版本) – [Developing a Hack Assembler] codinghare | ||
---|---|---|---|
行 81: | 行 81: | ||
- 对 '' | - 对 '' | ||
- 最后得到的翻译结果是 '' | - 最后得到的翻译结果是 '' | ||
+ | |||
+ | ====Symbols Handling==== | ||
+ | 之前介绍过,根据 symbol 的内容,可以将 symbol 划分为三种类型: | ||
+ | * //varible symbol// | ||
+ | * //label symbol// | ||
+ | * // | ||
+ | ===pre-defined symbols=== | ||
+ | 由于这些 symbol 只会在 A 指令中出现,因此只需要根据对照表,将 symbol 转化为对应的地址值即可:比如 | ||
+ | <code nand2tetris-hdl> | ||
+ | // R1 corresponds address 1 | ||
+ | @R1->@1 | ||
+ | </ | ||
+ | ===Label symbols=== | ||
+ | label 类型的 symbol 主要用于: | ||
+ | * 标记 goto 命令的终点,比如 '' | ||
+ | * 对应的伪代码声明,比如 '' | ||
+ | <code nand2tetris-hdl> | ||
+ | @i // line 0 | ||
+ | M=1 | ||
+ | @sum | ||
+ | M=0 | ||
+ | |||
+ | (LOOP) // not a instruction line | ||
+ | @i // line 4 | ||
+ | ... | ||
+ | @LOOP //line 16 | ||
+ | </ | ||
+ | 这里的 '' | ||
+ | ^Symbol^value^ | ||
+ | |LOOP|4| | ||
+ | ===Variable symbols=== | ||
+ | 变量类型的 symbol 指非提前定义的,且没有使用 driective 在别处进行定义的(比如 '' | ||
+ | ^Symbol^value^ | ||
+ | |i|16| | ||
+ | |sum|17| | ||
+ | 由于变量可能会被多次用到,当第一次用到时,该变量 symbol 和其对应地址会被加入到映射表中;之后再使用时,汇编器会从映射表中查找到该对应关系,并把 symbol 翻译为对应的地址。 | ||
+ | ===Symbol table=== | ||
+ | 可以看到的是,上述的所有翻译都依赖于一种数据结构:// | ||
+ | * 初始化:这个阶段会建立一张空表,并将 pre-defined symbol 的映射关系写入表中 | ||
+ | * 寻找 label 声明:这个阶段(// | ||
+ | * 当遇到 '' | ||
+ | * 同时维护一个计数器,对行数计数。记录的是**已经扫描过的行数**:比如之前的 '' | ||
+ | * 然后接着扫描,直到遇到下一个 '' | ||
+ | * 变量处理(// | ||
+ | * 新变量会直接加入 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' | ||
+ | - 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, | ||
+ | - write the translated instruction to the output file | ||
+ | </ | ||
+ |