【问题标题】:how to tell the difference between lc3 opcodes and lc3 processor directives如何区分 lc3 操作码和 lc3 处理器指令
【发布时间】:2018-11-21 18:20:00
【问题描述】:

我一直在学习lc3,我正在写disassembler。我有一个问题,关于如何在读取组装的 lc3 代码时区分操作码和处理器指令(例如 .FILL 指令)。

现在,LC3 指令为 16 位宽。这是一个例子:

0000100000000111

此示例是 BR(分支)指令。左边的前 4 个数字 (0000) 表示这是一个 BR 操作码,后面的 3 个数字 (100) 是测试条件(负、零和正,按此顺序。所以 100 表示仅测试负, 110 表示测试是否为负数或零等)。如果这三位都没有设置,那么这实际上不是 BR 指令,而是处理器指令。所以如下:

0000000001001001

左边数的前 4 个是 0000,所以通常这将是一条 BR 指令,但因为没有设置 Neg、Zero、Pos 位,所以它是一个 .FILL 处理器指令,这意味着所有 16比特被计算为一个十六进制数,在本例中为 0x0049。

现在这只是 16 个操作码之一。我也碰巧知道 TRAP 指令的操作码 (1111) 有一个类似的特殊情况,即如果设置了相同的三位中的任何一个(再加上右边的一位),那么它就不是 TRAP 指令。现在,由于操作码 0000 和操作码 1111 有这些特殊情况,所以它们之间的操作码也应该有这样的特殊情况是有道理的。但是我浏览了所有我能找到的文档,似乎没有提到这些案例(虽然,我知道我阅读了 lc3 汇编器生成的 .lst 文件是对的)。有谁知道任何提到这一点的文件?或者有人知道更多这些“特殊情况”吗?谢谢

编辑: 感谢您的回复,但我仍然不确定如何区分指令和数据。以下是我刚刚从 .lst 文件中复制的几行代码:

(305A) 0059  0000000001011001 (  45)                 .FILL x0059
(305B) 0000  0000000000000000 (  45)                 .FILL x0000
(305C) FFD0  1111111111010000 (  46) RESET           .FILL xFFD0
(305D) 0045  0000000001000101 (  47) LINE1           .FILL x0045

请注意,如果不是因为没有设置任何 NZP 位,前两行和最后一行很容易被读取为 BR 指令。第三行和 TRAP 指令也是如此。那么,这个呢:

0101001001100000   ;; or 0x5260

这是 AND 指令还是 .FILL 指令?怎么分辨?

【问题讨论】:

  • 强大的反汇编程序(如 IDA Pro)会分析哪些位置永远不会在执行流中,然后将这些位置视为数据值,而不是尝试将它们解释为操作码。
  • A .FILL 伪操作可以去任何地方,所以我不知道如何测试它。我做了一个可以工作的反汇编程序,链接有问题,但我担心某些特殊情况会导致它输出不正确的信息

标签: assembly directive disassembly lc3


【解决方案1】:

.FILL 可以将任意字节发送到输出文件中。

手动编码指令并使用.fill 发出指令与让汇编程序从助记符 + 操作数对其进行编码之间在机器代码上几乎没有区别。示例见How to avoid executing variables in lc3 assembly

当 CPU 解码/执行机器代码时,它并不关心字节是如何到达那里的,它只是将它们视为指令。您的反汇编程序也应该这样做。

如果遇到不是有效 LC-3 指令的指令字,您可以简单地将其反汇编为 .fill 0x1234 或其他内容,然后继续下一个字。这就是现有反汇编程序为 ARM 和 x86 等 ISA 所做的事情。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2014-11-10
    • 2014-11-10
    • 1970-01-01
    • 2014-11-10
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多