ARM汇编(第三部分)ARM指令集

ARM & Thumb

 ARM处理器有两种主要状态可以运行(ARM和Thumb)(在这里不包括Jazelle)。这些状态与特权级别无关。例如,以SVC模式运行的代码可以是ARM或Thumb。这两种状态之间的主要区别是指令集,其中ARM状态下的指令始终为32位Thumb状态下的指令为16位(但可以为32位)。知道何时以及如何使用Thumb对于我们的ARM利用开发目的尤其重要。在编写ARM shellcode时,我们需要摆脱NULL字节,而使用16位Thumb指令而不是32位ARM指令会减少使用它们的机会。

 ARM版本的调用约定不仅令人困惑,而且并非所有ARM版本都支持相同的Thumb指令集。在某个时候,ARM引入了增强的Thumb指令集(伪名:Thumbv2),该指令集允许32位Thumb指令甚至条件执行,而在此之前的版本中是不可能的。为了在Thumb状态下使用条件执行,引入了“ it”指令。但是,此指令在以后的版本中被删除,并交换了一些本应使事情变得不那么复杂的东西,但是却达到了相反的目的。我不知道在所有不同的ARM版本中ARM / Thumb指令集的所有不同变体,老实说我不在乎。你也不应该 您唯一需要知道的是目标设备的ARM版本及其特定的Thumb支持,以便您可以调整代码。ARM信息中心应帮助您确定ARM版本的详细信息(http://infocenter.arm.com/help/index.jsp)。

 如前所述,有不同的Thumb版本。不同的命名只是为了使它们彼此区分(处理器本身始终将其称为Thumb)。

  • Thumb-1(16位指令):在ARMv6和更早的体系结构中使用。
  • Thumb-2(16位和32位指令):通过添加更多指令并使它们的宽度为16位或32位(ARMv6T2,ARMv7)来扩展Thumb-1。
  • ThumbEE:包括一些针对动态生成的代码(在执行之前或执行期间在设备上编译的代码)的更改和添加。

ARM和Thumb之间的区别:

  • 条件执行:ARM状态下的所有指令均支持条件执行。某些ARM处理器版本允许使用IT指令在Thumb中有条件执行。有条件的执行导致更高的代码密度,因为它减少了要执行的指令数量并减少了昂贵的分支指令数量。
  • 32位ARM和Thumb指令:32位Thumb指令带有.w后缀。
  • 桶形移位器是ARM​​模式的另一个独特功能。它可以用于将多个指令缩小为一个。例如,您可以使用左移1-> Mov R1,R0,LSL,而不是使用两条指令进行乘法运算(将寄存器乘以2并使用MOV将结果存储到另一个寄存器中),而不是在MOV指令中包含乘法#1; R1 = R0 * 2

要切换处理器执行的状态,必须满足以下两个条件之一:

  • 我们可以使用分支指令BX(分支和交换)或BLX(分支,链接和交换)并将目标寄存器的最低有效位设置为1。这可以通过在偏移量上加1来实现,例如0x5530 + 1。可能会认为这将导致对齐问题,因为指令是2字节或4字节对齐的。这不是问题,因为处理器将忽略最低有效位。有关更多详细信息,请参见 第6部分:条件执行和分支。
  • 我们知道,如果当前程序状态寄存器中的T位置1,则我们处于Thumb模式。

ARM指令简介

 这部分的目的是简要介绍ARM的指令集及其一般用法。对于我们而言,至关重要的是要了解最小的汇编语言是如何工作的,它们如何相互连接以及将它们组合起来可以实现什么。

 如前所述,汇编语言由指令组成,而指令是主要的构建块。ARM指令通常后跟一个或两个操作数,并且通常使用以下模板:

MNEMONIC {S} {condition} {Rd},Operand1,Operand2

 由于ARM指令集的灵活性,并非所有指令都使用模板中提供的所有字段。但是,模板中字段的用途描述如下:

MNEMONIC     -指令的简称(助记符)
{S}          -可选的后缀。如果指定了S,则根据操作结果更新条件标志
{condition}  -执行指令需要满足的条件
{Rd}         -用于存储指令结果的寄存器(目标)
Operand1     -第一个操作数。寄存器或立即值
Operand2     -第二个(灵活的)操作数。可以是立即数(数字)或带可选移位的寄存器

 虽然MNEMONIC,S,Rd和Operand1字段很简单,但condition和Operand2字段需要更多说明。条件字段与CPSR寄存器的值紧密相关,或者确切地说,与寄存器内特定位的值紧密相关。Operand2之所以称为灵活操作数,是因为我们可以以各种形式使用它-作为立即值(具有有限的一组值),寄存器或带移位的寄存器。例如,我们可以将这些表达式用作Operand2:

123      -立即值(一组有限的值)。 
Rx         -寄存器x(如R1,R2,R3 ...)
Rx,ASR n  -寄存器x算术右移n位(1 = n = 32)
Rx,LSL n  -逻辑x左移n位的寄存器x(0 = n = 31)
Rx,LSR n  -寄存器x的逻辑右移n位(1 = n = 32)
Rx,ROR n  -向右旋转n位的寄存器x(1 = n = 31)
Rx,RRX    -寄存器x向右旋转一位,扩展

 作为一个简短的示例,说明了不同种类的指令的外观,让我们看一下以下列表。

ADD   R0, R1, R2       -将R1(Operand1)和R2(Operand2以寄存器形式)的内容相加并将结果存储到R0(Rd)中
ADD   R0, R1, #2       -将R1(Operand1)和值2(Operand2以立即值形式)的内容相加并将结果存储到R0(Rd)中
MOVLE R0, #5           -仅在满足条件LE(小于或等于)的情况下,将数字5(Operand2,因为编译器将其视为MOVLE R0,R0,#5)移动到R0(Rd)。
MOV   R0, R1, LSL #1   -将R1的内容(逻辑左移的寄存器形式的操作数2)左移一位至R0(Rd)。因此,如果R1的值为2,则将其左移一位并变为4。然后将4移至R0。

 作为一个简短的摘要,让我们看一下将在以后的示例中使用的最常见的说明。

操作说明描述操作说明描述
MOV移动数据EOR按位异或
MVN移动并取反LDR加载
ADD加法STR储存
SUB减法LDM加载多个
MUL乘法STM储存多个
LSL逻辑左移PUSH推入堆栈
LSR逻辑右移POP弹出堆栈
ASR算术右移B分支
ROR右旋BL分支使用链接
CMP比较BX分支与交换
AND按位与BLX分支使用链接和交换
ORR按位或SWI / SVC系统调用
相关推荐
©️2020 CSDN 皮肤主题: 技术黑板 设计师:CSDN官方博客 返回首页