如何区分手臂指令和拇指指令?例如:
add r1, r2, r3 ;add r2 and r3, then store the result in r1 register
上述说明如何在手臂和拇指指导方面起作用?
答案 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模式之间切换需要几纳秒,它的硬件支持,并且比通常在内核和用户模式之间切换要快得多。
如果你问我为什么整套谷歌的图书馆都是武装的,我会告诉你,尽管他们应该保持向后兼容并保持一致,但绝对没有理由。