arm和thumb指令集

arm和thumb指令集,arm,Arm,如何区分手臂指令和拇指指令?例如: add r1, r2, r3 ;add r2 and r3, then store the result in r1 register 就arm和thumb指令而言,上述指令是如何工作的?我们可以访问infocenter.arm.com,获取有关体系结构的体系结构参考手册,或者只获取ARMv7手册(不是-M而是-A或-R)它将包括从ARMv4到ARMv7的所有指令编码,包括thumb和最成熟的thumb2扩展。(您可能需要多个体系结构参考手册和/或技术参考手

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

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

就arm和thumb指令而言,上述指令是如何工作的?

我们可以访问infocenter.arm.com,获取有关体系结构的体系结构参考手册,或者只获取ARMv7手册(不是-M而是-A或-R)它将包括从ARMv4到ARMv7的所有指令编码,包括thumb和最成熟的thumb2扩展。(您可能需要多个体系结构参考手册和/或技术参考手册,因为arm手册中的指令编码不准确)

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

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

该指令在说明中以ADDS rd、rn、rm的形式列出,S表示从thumb指令派生的父ARM指令中保存的标志,对于ARM指令,您可以选择是否修改标志,thumb指令则可以不修改(thumb2有控制方法,但有限制(用于添加指令)

添加rd、rn、rm

0001100 rm rn路

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

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

在ARM模式下查看ADD指令时,您从一个条件字段开始,当您编写问题时,这是一个ALWAYS或1110模式(ALWAYS execute),当您编写问题时,您还编写了ADD not adds,因此不保存标志,因此编码中的s位为零

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

现在转到手册中描述移位器操作数编码的部分。仅作为寄存器rm的编码位25(I位)为零,11到4为零,3到0为rm,因此添加rd、rn、rm

1110 00 01000 rn rd 0000000 rm

1110 00 0 01000 0001 0010 00000000 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
节的反汇编。文本:
00000000 :
0:e0821003添加r1、r2、r3
4:18d1加上r1、r2、r3
与手动编码匹配


现在,如果您试图反汇编一块不知道它们是什么类型的字节,这是另一回事,这最多可能是非常困难的,理想情况下,您希望通过跟踪执行和模式更改来反汇编整个二进制文件(如果不模拟执行,您可能无法理解)。一个线索是,ARM指令通常使用始终条件,即指令开头的0xE,因此,如果您看到0xExxxxxxx形式的大量32位字,则这些字可能是ARM指令,而不是数据,而不是thumb指令。纯thumb将有一个不太典型的模式,例如0x6xxx和0x7xxx,但同时也是所有字符的混合其他起始值。Thumb2扩展可以在任意一个半字边界上开始,并且对于32位字将具有更独特的起始模式,但由于它们与非Thumb2扩展混合在一起,并且不总是在32位边界上对齐,因此Thumb2扩展(带或不带Thumb2扩展)在视觉上不太容易从数据中分离出来,只有ARM指令离子很容易在视觉上被隔离。

实际上,没有理由把一个库编译成arm,除非你有意让一切变得更加困难。 在arm和thumb模式之间切换需要几纳秒的时间,它有硬件支持,而且比在内核和用户模式之间切换要快得多。
如果你问我为什么谷歌的整个库都是arm,我会告诉你,尽管它们应该保持向后兼容和一致,但绝对没有理由。

你是在问它们有什么不同?或者它们有什么不同?或者它们是如何添加的?你的实际问题我不清楚。:-+1,回答得很好。我在尝试不同的东西。。我使用“gcc-mthumb”编译add.s,但它仍然没有创建thumb二进制文件。你知道为什么吗?注意我代码中的.thumb,它告诉汇编程序后面的代码是thumb。代码32告诉汇编程序代码是arm。还有一些常见的语法和其他你可以自己查找的东西。还要注意,我使用gnu汇编程序而不是gnu C编译器来汇编汇编语言。(as而不是gcc)即使gcc将把它传递给as,也可能会有预处理,而且体验可能不同于直接组装。我刚刚注意到elf文件中的arm/thumb之间的差异还需要做一些其他事情。如果您
readelf-s add.o
,则在.symtab中根据编码得到$a或$t,请参阅