2013-07-24 51 views
2

我反编译了一些ARM ELF文件并读取了汇编代码。但是,我不明白一些代码是如何转换成助记符的。例如,我得到了这样的代码:ARM汇编程序中的编码寄存器操作数是怎样的?

#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 

所以,你可以清楚地看到操作码为push0xb40xb5如果推多个值。但是,那么如何创建寄存器列表呢?

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

+0

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

回答

4

有在Thumb模式PUSH指令的三种编码。第一种是16位长,并且由于与ARMv4T(原始拇指实现)存在:

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

由于register_list为8位,它只能推寄存器R0R7(和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位,所以它可以推到R0R12LR

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

BTW,POP编码非常相似。

16位POP

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

可以弹出R0R7PC(位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 | 

可以弹出R0R12PC(位P)和LR(位M)。

0

AFAIR,16位Thumb指令PUSH只能推下8个寄存器(R0-R7)。 LR在这里是例外。的0xB480和0xB580之间的不同的一点是,指令的比特push_LR_register ...标记为L

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 

这里位是register_list < 0-7>。标记为R,该位被保留用于LR寄存器...

+0

在我的Instruction Set pdf中,它读取了以下内容:“Push Multiple Registers将通用寄存器R0-R12和LR的子集(或可能全部)存储到堆栈中。” http://web.eecs.umich.edu/~prabal/teaching/eecs373-f10/readings/ARMv7-M_ARM。pdf 所以是的,也许是与'LR'寄存器混合在一起的Bit? – reox

+1

@reox:是的,在编码T1中,M是LR寄存器的位。我在一个较旧的PDF上看到了它... – Malkocoglu

相关问题