繁体   English   中英

将非常简单的ARM指令转换为二进制/十六进制

[英]Converting very simple ARM instructions to binary/hex

我一直在尝试使用此页面以及其他各种指南来弄清楚如何将非常简单的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指令转换为汇编它的二进制/十六进制/机器代码。

在此先感谢您的帮助。

以下是数据处理指令的编码方式:

ARM数据处理指令

您的页面中有条件代码表。 寄存器编码为00001111

您的所有示例属于同一类别。 图片是从我的硬盘驱动器上的某些文档中提取的,但我也设法通过谷歌找到它。 编写这些指令是一项繁琐的工作。

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

1110 00 0 0 1101 0000 0000 00000000

我把Rn设为0,因为它实际上不适用于MOV CMP情况下,我相信, S总是1。

首先,您需要在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

arm-none-linux-gnueabi vs arm-none-elf vs arm-elf等对此无关紧要,都做同样的事情

Disassembly of section .text:

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

完整32位臂指令(不是拇指)的前四位是条件代码,请参阅ARM ARM中的条件字段部分。 0xE表示始终执行此指令。 0b0000是eq仅在z标志置位时执行,0b0001 ne仅在z清除时执行,等等。

在ARM ARM中推入arm指令集,然后按字母顺序列出arm指令,然后找到cmp它以cond 00I10101开头snz shifter

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

上面的第19位到第16位是0b001,对于ARM ARM中的移位器操作数是rn = 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

add类似但使用立即数,所以转到alpha指令列表中的add指令。 我们现在从cmp知道这个类指令的24:21是操作码,我们几乎可以直接转向移位器操作数从那里继续

这次我们正在添加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并且在旋转右1 * 2位的rotate_imm字段1101000中的1是11010 = 0x1A = 26。

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

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

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

第二个寄存器是目的地,在这里你只需编码寄存器号,所以在你的情况下它也将是0000,因为你使用r0作为destinal,对于r4它将是0100。

余数是所谓的移位操作数,非常灵活。 它可以是一个简单的寄存器,如你的情况(r0)那么它只是0000 0000 0000,其中最后4位再次编码寄存器。 它还可以编码不同类型的移位,并使用寄存器或立即值进行数据处理。

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

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM