【问题标题】:How are encoded register operands in ARM assembler ?ARM 汇编器中的编码寄存器操作数如何?
【发布时间】:2013-07-24 17:48:11
【问题描述】:

我反编译了一些 ARM ELF 文件并阅读了汇编代码。但是,我看不到一些代码是如何翻译成助记符的。例如我得到这样的代码:

#hex code | #mnemonic             | #binary
0xb480    | push {r7}             | 1011 0100 1000 0000
0xb580    | push {r7, lr}         | 1011 0101 1000 0000
0xb5f0    | push {r4,r5,r6,r7,lr} | 1011 0101 1111 0000

因此,您可以清楚地看到push 的操作码是0xb40xb5,如果推送多个值。但是寄存器列表是如何创建的呢?

第一个例子很清楚,r7是由第8位编码的,也就是设置。但是,为什么第二个操作码也会推送lr?没有位标志吗?

【问题讨论】:

  • 您确定操作码是两个完整字节吗?它可能只有 6 / 7 位。

标签: assembly arm


【解决方案1】:

在 Thumb 模式下,PUSH 指令共有三种编码。第一个是 16 位长,从 ARMv4T(原始 Thumb 实现)开始存在:

15141312|11|109|8|      7..0    |
 1 0 1 1| 0| 10|M| register_list|

由于register_list是8位,它只能将寄存器R0推送到R7(和LR,如果设置了M位)。

在 Thumb-2(ARMv6T2、ARMv7 及更高版本)中,又添加了两种编码。它们都是 32 位长:

1514131211|109|876|5|4|3210||151413|    12 .. 0    |
 1 1 1 0 1| 00|100|1|0|1101|| 0 M 0| register_list |

在这一项中,register_list 是 13 位,所以它可以将R0 推送到R12LR

我不会列出第三种编码,但它可以推送任何单个寄存器。

顺便说一句,POP 编码非常相似。

16 位 POP:

15141312|11|109|8|      7..0    |
 1 0 1 1| 1| 10|P| register_list|

可以将R0 弹出到R7PC(位P)。

32 位 POP 多个:

1514131211|109|876|5|4|3210||151413|    12 .. 0    |
 1 1 1 0 1| 00|010|1|0|1101|| P M 0| register_list |

可以将R0 弹出到R12PC(位P)和LR(位M)。

【讨论】:

    【解决方案2】:

    AFAIR,16 位 Thumb 指令 PUSH 只能压低 8 个寄存器(R0-R7)。 LR在这里是个例外。 0xB480 和 0xB580 之间的不同位是该指令的 push_LR_register 位...

    15 14 13 12 11 10 09 08 07 06 05 04 03 02 01
     1  0  1  1  0  1  0  R  L  L  L  L  L  L  L
    

    这里标记为 L 的位是 register_list 。标记为 R 的位是为 LR 寄存器保留的……

    【讨论】:

    • 在我的指令集 pdf 中,它读取以下内容:“推送多个寄存器将通用寄存器 R0-R12 和 LR 的子集(或可能全部)存储到堆栈中。” web.eecs.umich.edu/~prabal/teaching/eecs373-f10/readings/… 所以是的,也许标有 M 的位是 LR 寄存器?
    • @reox:是的,在编码 T1 中,M 是 LR 寄存器的位。我在较旧的 PDF 上看到过它...
    猜你喜欢
    • 1970-01-01
    • 2014-07-06
    • 1970-01-01
    • 1970-01-01
    • 2013-10-21
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多