【问题标题】:Assembly Hack to Binary Machine Language汇编破解二进制机器语言
【发布时间】:2021-10-02 15:56:50
【问题描述】:

如何将 Assembly Hack 转换为二进制机器语言?

例如,下面的 hack 程序集,我将如何手动将其转换为机器代码(二进制)。我只需要知道一个参考资料或者我可以在哪里学习如何手动翻译它。

计算 R0 = 2 + 3

@2
D=A
@3
D=D+A
@0
M=D

【问题讨论】:

    标签: assembly machine-code machine-language nand2tetris


    【解决方案1】:

    只有少数几种汇编语言行格式,下面是其中的一些:

    1. A型指令
    2. C 类指令
    3. 标签
    4. 注释和空行

    正如您可能想象的那样,标签和 cmets (3&4) 不会生成任何机器代码指令,并且虽然 cmets 被忽略,但标签会通知 A 型指令关于偏移量 - 但是,您的示例两者都没有,所以不用担心他们。

    A 类和 C 类指令均为 16 位宽。

    A类指令很简单,占用16位机器码,其中16位的第一位(最高位,MSB,最高位)为0,表示A类指令,其他15-位是数值(例如在@2 中)或标签位置(例如在@loop 中)。

    所以,@2 编码如下:

     +-- A type indicator, top bit is zero for A-type
     |
     v
     0000000000000010   <-- 16-bit machine code instruction
      |-------------|   range of immediate value field for A-type
    (0000000000111111)  
    (0123456789012345)  bit position (MSB at pos 0, LSB at 15)
    

    A 型的最高位为 0。对于这条指令的其余部分 (@2),低 15 位编码值“2”。

    C 类指令也是 16 位宽,并以 MSB 值 1 开头,这将它们与 A 类指令区分开来(因为那些指令以 0 开头)。 C 类指令具有三个感兴趣的字段:compdestjump

    comp代表要计算什么,是一个6位字段

    dest代表存储计算的位置,是一个3位字段

    jump代表什么条件可以改变机器代码程序的控制流,是一个3位字段

    C 类型指令通常写为X = Y,其中X 就是= 左侧的任何内容,Y 类似地是@ 右侧的任何内容987654335@。 X 对应于destY 对应于comp

    请参阅this 获取 C 类型指令和这些字段的图片,在此处转载:

    C 类指令的编码如下:

    size (in bits):     1    2     7      3      3
                     +-----+----+------+------+------+
    field            | A/C | ZZ | comp | dest | jump |
                     +-----+----+------+------+------+
    

    在某些文本中,7 位 comp 字段进一步细分为 a(1 位)和 c(6 位):

    size (in bits):     1    2    1    6       3      3
                     +-----+----+---+------+------+------+
    field            | A/C | ZZ | a |   c  | dest | jump |
                     +-----+----+---+------+------+------+
                                |   comp   |
                                     7 bits
    

    ZZ 位在 C 类型指令中未使用,因此它们可以是任何值,但常见的文本倾向于使用 1(我不知道为什么,我会使用 0)。 em>

    为了找到这些字段的值,您可以使用表格来查找它们。表格可以在上述链接引用的视频中找到,也可以在https://zhongchuyun.gitbooks.io/nand2tetris/content/chapter_4.html

    例如,如果 C 类型指令旨在使用普通流控制,则使用 000jump 字段编码。

    (正常的控制流是指令一个接一个地按顺序执行,因为它们出现在内存中按顺序递增的内存地址。这是很常见的,因为它经常需要一条接一条地执行多条指令但是,有时我们需要让机器在机器代码程序中向前跳转(执行 if-then/else),而其他时候我们需要让机器在机器代码程序中向后跳转(执行循环)。

    在 C 类型指令 D=A 中,compX = Y 中的 Y)必须简单地计算 A,因此指令字段为表中的 0110000dest (X) 必须以D 为目标,因此dest 表值为010

    因此,我们有一条 C 类型指令 (1),其中 comp0110000,目标为 010jump000。 (请注意,C 类型的指令有两个被忽略的位,如下所示 ZZ。这些 Z 可以是 0 或 1 - 随你喜欢,因为这无关紧要。有些作者似乎选择了 1。)

    一起显示:

    A/C ZZ  comp   dest jump
     1  11 0110000  010  000
    

    -或- 11101100000100002 = EC1016 = 60,43210


    来源:http://dragonwins.com/domains/getteched/csm/CSCI410/references/hack.htm

    【讨论】:

    • 我在 C 类型指令中使用0 而不是1 作为第一位出现错误。我已经修复了这个错误。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2018-07-21
    • 1970-01-01
    • 2017-10-25
    • 2017-04-07
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多