【问题标题】:Building a Compiler in C, Assembly to Hex用 C 语言构建编译器,汇编为 Hex
【发布时间】:2020-01-17 14:17:59
【问题描述】:

从以下链接 - https://gist.github.com/Romain-P/630f8565cd55b0c52314c47b509b9eb4

查看 ADD 部分 - 为什么他们从 op1[0],op2[1],op3[0] 中减去 48?我理解 or (|) 在左移后组合操作。 另外,为什么 chch 按位与 (&) 与 0x00ff?

                else if (strcmp(token,"add")==0) //----------------- ADD -------------------------------
                {
                    op1 = strtok(NULL,"\n\t\r ");    
                    op2 = strtok(NULL,"\n\t\r ");
                    op3 = strtok(NULL,"\n\t\r ");
                    chch = (op1[0]-48)| ((op2[0]-48)<<3)|((op3[0]-48)<<6);  
                    program[counter]=0x7000+((chch)&0x00ff); 
                    counter++; 
                }

【问题讨论】:

  • 48 == '0'。这会将 ASCII 数字转换为 0 - 9 的范围。
  • 48 是 '0' 的 ascii 代码
  • Anding 与0x00ff 获取变量的低字节。

标签: c assembly hex


【解决方案1】:

会变成一个完整的答案:

48 == '0'。这是将 ASCII 数字转换为 0 - 9 的范围。

下一部分是进行假设。 0 - 9 需要 4 位来完全编码,但它们只使用 3 位来编码。如果任何值大于 7,这将导致混乱。

“和屏蔽”部分正在清除多余的位,但由于这个数学应该只保存 9 位,这也可能很危险,因为掩码只有 8 位的空间。

总而言之,这段代码的想法看起来很可疑。

【讨论】:

  • 所以可以说 op1[0] 的值为 1(寄存器 1)。您将从 1 中减去 48,即 -47。使用十六进制 F 的 &'d 会产生预期的结果吗?抱歉,我是 C 和 ASCII 世界的新手
  • op1[0] 不是一个数字,而是一个字符。因此,如果寄存器 1 为“1”,则其数值为 49。
  • 使用 3 位字段是一个重要线索,这是解析 八进制,而不是十进制。所以 8 或 9 将是非法输入(此片段不会尝试检测;也许它们已被排除)。或者,如果这是一个只有 8 个寄存器的机器的汇编器,那么有效的 asm 将只使用从 0 到 7 的寄存器号。
  • 好的,我现在明白了,并且得到了我需要的工作。感谢您的帮助!
【解决方案2】:

这段代码虽然相当迟钝,但注释很好。当您习惯了新代码时,请从顶部开始,并连同代码一起阅读所有 cmets。

我只是这样做了,发现这条有用的评论:

48 is ASCII value of '0'

因此,从 ASCII '0' - '9' 中减去 48 会将其转换为等效的数字。

与常数的按位与称为“屏蔽”位。掩码中为 1 的位通过 AND 运算符实现,为 0 的位被剥离。

【讨论】:

    猜你喜欢
    • 2015-07-15
    • 1970-01-01
    • 2010-12-24
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-02-19
    相关资源
    最近更新 更多