将 ARM 指令编码和解码为二进制文件

Encoding and decoding ARM instructions to/ from binary

任务 1:为以下指令编写相应的 ARM 汇编表示形式:

11101001_000111000001000000010000
11100100_110100111000000000011001
10010010_111110100100000011111101
11100001_000000010010000011111010 
00010001_101011101011011111001100

任务 2:为以下指令编写指令代码:

STMFA R13!, {R1, R3, R5-R11} 
LDR R11, [R3, R5, LSL #2]
MOVMI R6, #1536
LDR R1, [R0, #4]!
EORS R3, R5, R10, RRX

我对这方面的经验为零 material 教授让我们这些学生去干。基本上我已经找到了解码这些指令的各种方法,但我仍然有三个主要疑问。

  1. 我不知道如何开始将二进制文件解码为 ARM 指令,这是家庭作业的第一部分。

  2. 我找不到其中一些后缀,例如在 EORS 上,S 是什么?是设置条件位吗?指令前面有S是不是置1?

  3. 我不知道在一个指令行中有多个寄存器有什么用。示例:

     EORS R3,R5,R10,RRx
    

    我不明白这么多寄存器是怎么回事。

非常感谢任何朝着正确方向的推动。我还搜索了 ARM 手册,对于不了解他们正在寻找的内容的人来说,它们并不是很有帮助。他们确实有大部分编码和解码说明,但对我上面提出的问题几乎没有解释。

查看 ARM 体系结构参考手册(其中之一)的不同部分(不是 cortex-m(armv6m armv7m),您想要 ARMv5 或 ARMv7-AR)将查看拇指指令,但 ARM 指令的工作方式相同,并且是前面几章的内容。

它说 thumb 指令集为 section/chapter,然后很快进入 table 显示 thumb 指令集编码,或者您可以直接搜索它。一个如果它们被称为 Add/subtract 寄存器,前面有很多硬编码的 1 和 0 然后第 9 位是 opc,然后是 rm、rn 和 rd 位。

arm 工具链很容易获得 windows mac 和 linux 或者可以很容易地从源代码构建(只需要 binutils)。组装这个

.thumb
add r1,r2,r3
add r1,r2,r4
add r1,r2,r5
add r1,r2,r6
add r1,r2,r7

然后反汇编得到

00000000 <.text>:
   0:   18d1        adds    r1, r2, r3
   2:   1911        adds    r1, r2, r4
   4:   1951        adds    r1, r2, r5
   6:   1991        adds    r1, r2, r6
   8:   19d1        adds    r1, r2, r7

从 ARM 中的图表来看,加法寄存器以硬编码位 000110 开头,上面的指令以 0x18 或 0x19 开头,它们都以 6 位 000110(00011000 或 00011001)开头。在拇指指令的字母顺序列表中,我们查找添加指令。找到三个寄存器 1,在这种情况下,它有 7 位恰好与我们正在解码的位 0001100 匹配,所以我们走在正确的轨道上。最后9位是三组三个

0x1951为0001100101010001或0001100 101 010 001,后九位分别代表r5、r2、r1。查看指令的语法部分,它显示 add rd, rn, rm 但 machine 代码有 rm, rn, rd 所以我们采用 machine 代码并根据语法重新排列并获得 add r1、r2、r5。它匹配得不错,现在不幸的是这里的 s 令人困惑,这个拇指指令没有 s 位没有空间所以这个总是更新标志,所以这个指令和工具链的性质以及我如何使用它需要 add 没有s 在组装端,用 s 拆卸。令人困惑,抱歉。使用 arm 指令时,字母 s 按预期工作。

只需在任一方向对 ARM 指令重复此操作即可。直接值将是其中最具挑战性的部分。与否取决于具体的指令和立即数编码。

如果您有 ARM v7 A+R 体系结构手册 (DDI0406C),A5 章中有很好的基于 table 的 decode/disassembly 描述。您从 table A5.1 开始,并且根据指令字中不同位的值,它指的是越来越具体的 table 导致指令。

例如,考虑以下指令:

0001 0101 1001 1111 0000 0000 0000 1000

根据第一个 table 它是一个无符号的 load/store 指令,因为条件不是 1111 并且 op1 是 010。它的编码在 A5.3 中进一步扩展

从这一部分我们看到 A=0,op1=11001,Rn=1111 (PC),B=0。这意味着该指令是 LDR(文字)。检查描述该指令的页面并记住 cond=0001 我们看到该指令是LDRNE R0, [PC, #4].

要执行相反的过程,请在按字母顺序排列的指令列表中查找指令并遵循该模式。