如何区分arm指令和thumb指令?例如:
add r1, r2, r3 ;add r2 and r3, then store the result in r1 register就arm和thumb指令而言,上述指令是如何工作的?
发布于 2012-12-05 23:30:17
我们可以访问infocenter.arm.com,获取相关体系结构的体系结构参考手册,或者直接获取ARMv7手册(不是-M,而是-A或-R),其中将包括从ARMv4到ARMv7的所有指令代码,包括thumb和最成熟的thumb2扩展。(您可能需要多个架构参考手册和/或技术参考手册,因为指令的编码在arm手册中有失偏颇)
在thumb指令下查看基于寄存器的加法指令,有一种编码具有三个寄存器编码T1,它被列为所有thumb变体(ARMv4T到现在(ARMv4T,ARMv5,ARMv6,ARMv7和可能的ARMv8))
位15到9是rm的三位、rn的三位和rd的三位(典型地,thumb指令限于需要三位编码的r0-r7,thumb2扩展和少数特殊thumb指令允许更高编号的寄存器(四位编码))。
该指令在说明中被列为ADDS rd、rn、rm,S表示保存标志,它来自thumb指令派生自的父ARM指令,对于ARM指令,您可以选择是否修改标志,thumb指令您不可以(thumb2有办法控制这一点,但它有限制(对于add指令))。
添加rd、rn、rm
0001100 rm rn rd
因此添加r1,r2,r3将是这块位
0001100 011010001= 0001100011010001 = 0001 1000 1101 0001 = 0x18D1
查看ARM模式下的ADD指令,您从一个条件字段开始,因为您已经编写了问题这是一个ALWAYS或1110模式(always execute)也是因为您已经编写了您的问题您编写了add not add所以不保存标志,因此s位在编码中为零
因此,添加rd,rn,移位器操作数我们从位模式0b111000I01000开始,然后rn为四位,rm为四位,移位器操作数为11。是的,这是一个位25,不是1。I是移位器操作数编码的一部分
现在转到手册中描述移位器操作数编码的部分。仅仅是寄存器rm的编码是位25 (i位)是零,并且11到4是零,其中3到0是rm,所以添加rd,rn,rm
1110 00 0 01000 rn rd 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先组装,然后拆卸
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位字,这些可能是arm指令,而不是数据,也不是thumb指令。纯thumb将有一个不那么典型的模式,比如0x6xxx和0x7xxx,但也有其他所有起始值的混合。thumb扩展可以在任何一个半字边界上开始,并且对于32位字将具有更独特的开始模式,但由于它们与非Thumb2扩展混合在一起,并且并不总是在32位边界上对齐,因此使用或不使用thumb扩展都不那么容易从视觉上与数据隔离,只有ARM指令很容易在视觉上隔离。
发布于 2017-05-22 01:27:02
在实践中,没有理由将库编译为arm,除非您故意选择使一切变得更加困难。
在手臂和拇指模式之间切换需要几纳秒,它是由硬件支持的,而且比你通常所经历的在内核和用户模式之间切换要快得多。
如果你问我为什么谷歌的所有库都是arm的,我会告诉你,尽管他们应该保持向后兼容和一致,但绝对没有理由。
https://stackoverflow.com/questions/13725878
复制相似问题