2012-08-02 91 views
21

我一直试图使用this page以及各种其他指南来弄清楚如何以二进制和十六进制表示非常简单的ARM指令。对我来说这似乎应该是一个简单的过程,但我仍然不明白。这里有几个例子。将非常简单的ARM指令转换为二进制/十六进制

基本NOP:为他人

 what goes here?   what goes here? 
      _↓_     _____↓____ 
      | |    |   | 
mov r0, r0 ; ????00?1101????????????????????? 
         |__||__| 
          ↑ ↑ 
       how do I express registers? 

相同的基本问题。

比较两个寄存器:

cmp r1, r0 

添加立即注册值:

add r0, #0x1a 

所有这些教程在线是优秀的,在描述如何使用这样的指令,但没有,我已经能够找到实际的步骤,通过如何将ARM指令转换为二进制/十六进制/机器代码进行汇编。

在此先感谢您的帮助。

+2

很好的问题;不幸的是该链接已经死亡。对于路过的人来说,这里有一个快速的[web档案链接](https://web.archive.org/web/20150426195854/http://www.nyx.net/~troddis/ARM.html) – Asu 2016-11-10 22:26:22

回答

29

下面是数据处理指令是如何编码:

ARM data processing instructions

你在你自己的网页具有条件码表。寄存器编码为00001111

所有的例子都属于同一类别。图片是从我的硬盘上的某个文件中提取的,但我也设法通过google找到它。编写这些指令是一项乏味的工作。

所以,mov r0, r0应该是这样的:

1110 00 0 0 1101 0000 0000 00000000 

我把RN到0,因为它实际上不是适用于MOV。在CMP的情况下,我相信,S总是1.

5

您应该得到一份ARM ARM的副本,它描述了所有指令的编码。

大多数ARM指令使用高4位作为条件码。如果您不希望有条件地运行指令,则只需使用伪条件AL(1110)。

编码中的第一个寄存器(Rn)不用于MOV指令,它应该被设置为0000,如ARM ARM定义的。

第二个寄存器为目标,在这里你只是编码登记号码,所以你的情况,因为你正在使用R0作为destinal,为R4这将是0100

的也将是0000其余部分就是所谓的移位操作数,非常灵活。它可以是一个简单的寄存器(r0),它只是0000 0000 0000,最后4位再次对寄存器进行编码。它还可以对不同类型的班次进行编码,并根据寄存器或立即值进行数据处理。

但它也可能是一个立即的8位在底部位编码和前4位定义右旋转2位步骤。在这种情况下,bit25也将为1,在所有其他情况下为0。

+5

ARM ARM是一个这是一个有趣的缩写词,但要做一个Google搜索很难。该扩展是'ARM体系结构参考手册',它们可在[here](http://infocenter.arm.com/help/topic/com.arm.doc.subset.architecture.reference/index.html#reference )免费注册后。 – 2012-08-02 22:08:48

+0

@Kevin不,扩展实际上是**高级(降低指令集计算)机器体系结构参考手册**。但这不是一个好的谷歌搜索:) – 2014-02-14 23:26:59

9

首先,您需要infocenter.arm.com上的ARM体系结构参考手册(ARM ARM),参考手册,获取最老的一个(armv5管他呢)。该指令集在那里有很好的定义。

二,为什么不只是组装一些指令,看看会发生什么?

;@test.s 
cmp r1, r0 
add r0, #0x1a 

任何交叉汇编你(看到一个脚本生成的gcc目录http://github.com/dwelch67/raspberrypi,只是跑起来直通binutils的那个脚本)

arm-none-linux-gnueabi-as test.s -o test.o 
arm-none-linux-gnueabi-objdump -D test.o 

臂无-Linux的gnueabi VS掰没有精灵VS手臂精灵等不事本,都做同样的

Disassembly of section .text: 

00000000 <.text>: 
    0: e1510000 cmp r1, r0 
    4: e280001a add r0, r0, #26 

前四名的完整的32位ARM指令(不是拇指)是条件码位,见病情场部分在ARM ARM中。 0xE表示始终执行该指令。 0b0000是eq只有当z标志被设置时才执行,0b0001 ne只在z被清除时执行。

在ARM ARM中push进入arm指令集,然后按字母顺序列出arm指令,然后找到cmp它启动与cond 00I10101 rb sbz移位器

从我们的cmp指令上面我们看到1110 000101010001 ...所以我是一个零位15:12是零位27:26是零和24:21是1010所以这是一个cmp指令

上面的第19位到第16位是0b001,这对ARM ARM中的移位器操作数是rn = 1(r1),它告诉您查看寻址模式1数据处理操作数,并在pdf中有一个链接页面

我们知道我们希望第二个操作数只是一个寄存器,即所谓的数据处理操作数寄存器和一个页码,转到该页上的那个页面15:12是11:4是0和3 :0是rm。我们从cmp指令中知道它说15:12应该是零,我想知道它是否在意,cmp不会将结果存储到寄存器,因此不使用rd。 rm被使用,在这种情况下,我们想要r0,所以0b0000进入3:0也注意到它显示位27:25为零,在cmp指令中25是I,我们现在知道我们想在那里有一个零,所以

的CMP页面,这个数据处理之间 - 注册页面,我们有整个画面

1110 condition 
000 
1010 opcode 
1 S (store flags, that is a 1 for a cmp to be useful) 
0001 rn 
0000 rd/dont care/sbz 
00000 
000 
0000 rm 

cmp rn,rm 
cmp r1,r0 

附加类似,但采用了直接的,所以去的指令阿尔法列表中的加法指令。我们现在从cmp得知,这个类的指令是24:21是操作码,我们可以直接转到操作数的操作数上去继续从这里开始

这次我们正在做add rd,rn,#immediate

所以找页面#immediate

和编码是

1110 condition, always 
001 (note the immediate bit is set) 
0100 (opcode for add for this type of instruction) 
0 (S not saving the flags, it would be adds r0,r0,#26 for that) 
0000 (rn = r0) 
0000 (rd = r0) 

现在到了有趣的部分,我们可以编码26种不同的方式。位7:0是立即数,位11:8允许立即旋转,26是0x1A,我们可以简单地将0x1A放在低8位,并将旋转设置为0,这就是gnu汇编器所做的。可能会在低8位中放置一个0x68,并且在rotate_imm字段1101000中向右旋转1 1 * 2位是11010 = 0x1A = 26.

相关问题