手臂和拇指指令集

时间:2012-12-05 14:52:47

标签: arm

如何区分手臂指令和拇指指令?例如:

add r1, r2, r3 ;add r2 and r3, then store the result in r1 register

上述说明如何在手臂和拇指指导方面起作用?

2 个答案:

答案 0 :(得分:2)

请访问infocenter.arm.com并获取相关架构的架构参考手册,或者只获取ARMv7手册(不是-M而是-A或-R),其中包括迄今为止的所有指令编码从ARMv4到ARMv7,包括拇指和最成熟的thumb2扩展。 (您可能需要多本架构参考手册和/或技术参考手册,因为手册中的指令编码是命中或遗漏)

在拇指指令下查看基于寄存器的ADD指令,有一个编码带有三个寄存器编码T1,列为所有拇指变体(ARMv4T到现在(ARMv4T,ARMv5,ARMv6,ARMv7和可能的ARMv8))

位15到9是0b0001100三位rm,三位rn和三位rd(通常拇指指令限于r0-r7需要三位编码,thumb2扩展和一些特殊的拇指指令允许更高编号寄存器(四位编码))。

该指令在描述中列为ADDS rd,rn,rm,S表示来自导出thumb指令的父ARM指令的保存标志,对于ARM指令,您可以选择是否修改标志,拇指指令你没有(thumb2有办法控制它,但它有限制(对于添加指令))。

ADDS rd,rn,rm

0001100 rm rn rd

所以ADDS r1,r2,r3就是这个比特块

0001100 011 010 001 = 0001100011010001 = 0001 1000 1101 0001 = 0x18D1

在ARM模式下查看ADD指令,你从条件字段开始,因为你已经写了你的问题,这是一个总是或1110模式(总是执行),因为你已经写了你写的问题,你写的是添加不添加所以不是保存标志,因此编码

中的s位为零

所以添加rd,rn,shifter操作数我们从位模式0b111000I01000开始然后四 对于移位器操作数,rm为4,对于移位器操作数为11。是的,这是我有点位置25而不是一个。 I是移位器操作数编码的一部分

现在转到描述移位器操作数编码的手册部分。只是寄存器rm的编码是第25位(I位)为零,11到4为零,3到0为rm所以加上rd,rn,rm

1110 00 0 01000 rn 00000 000 rm

1110 00 0 01000 0001 0010 00000 000 0011 = 1110 0000 1000 0001 0010 0000 0000 0011 = 0xE0812003

现在我们可以测试一下,拿这个程序

add r1,r2,r3
.thumb
add r1,r2,r3

称之为add.s assemble then disassemble

arm-none-eabi-as add.s -o add.o
arm-none-eabi-objdump -D add.o 

并获取

Disassembly of section .text:

00000000 <.text>:
   0:   e0821003    add r1, r2, r3
   4:   18d1        adds    r1, r2, r3

匹配手编码。

现在,如果你试图反汇编你不知道它们是什么类型的一大块字节,这是一个不同的故事,这可能是非常困难的,理想情况下你想通过执行和执行来反汇编整个二进制文件。模式更改(如果不模拟执行,您可能无法理解)。一个线索是ARM指令通常使用ALways条件,该条件在指令开始时为0xE,因此如果您看到0xExxxxxxx形式的大量32位字,那么这些可能是指令而不是数据而不是拇指指令。纯拇指将有一个不那么典型的模式,如0x6xxx和0x7xxx,但也是所有其他起始值的混合。 Thumb2扩展可以从任一半字边界开始,并且对于32位字具有更独特的起始模式,但是因为它们与非thumb2扩展混合并且不总是在32位边界上对齐有或没有thumb2扩展的拇指在视觉上不那么容易仅从数据中隔离ARM指令很容易在视觉上隔离。

答案 1 :(得分:0)

在实践中,除非你故意选择让一切变得更加困难,否则没有理由将库编译为arm。

在arm和thumb模式之间切换需要几纳秒,它的硬件支持,并且比通常在内核和用户模式之间切换要快得多。

如果你问我为什么整套谷歌的图书馆都是武装的,我会告诉你,尽管他们应该保持向后兼容并保持一致,但绝对没有理由。