Assembly 如何在ARM汇编程序中编码寄存器操作数?
我反编译了一些ARM ELF文件并阅读了汇编代码。但是,我不知道有些代码是如何翻译成助记符的。例如,我得到如下代码:Assembly 如何在ARM汇编程序中编码寄存器操作数?,assembly,arm,Assembly,Arm,我反编译了一些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} |
#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
的操作码是0xb4
或0xb5
(如果按下多个值)。那么,如何创建寄存器列表呢
第一个示例非常清楚,
r7
由设置的第8位编码。但是,为什么第二个操作码也会推送lr
?没有位标志吗?AFAIR,16位Thumb指令推送只能推送较低的8个寄存器(R0-R7)。LR在这里是个例外。0xB480和0xB580之间的不同位是该指令的push_LR_寄存器位
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的位是寄存器列表。标记为R的位是为LR寄存器保留的…在Thumb模式下,PUSH指令有三种编码。第一个是16位长的,自ARMv4T(原始Thumb实现)以来就存在: 由于
register\u list
为8位,因此它只能将寄存器R0
推送到R7
(如果设置了M
位,则推送到LR
)
在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\u list
为13位,因此它可以将R0
推送到R12
和LR
我不会列出第三种编码,但它可以推送任何单个寄存器
顺便说一句,POP
编码非常相似
16位POP
:
15141312|11|109|8| 7..0 |
1 0 1 1| 1| 10|P| register_list|
可以将R0
弹出到R7
和PC
(位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
弹出到R12
、PC
(位p
)和LR
(位M
)。在我的指令集pdf中,它读到以下内容:“将多个寄存器存储通用寄存器R0-R12和LR的子集(或可能全部)。”,可能标有M的位是LR
寄存器吗?@reox:是的,在编码T1中,M是LR寄存器的位。我在旧的PDF上看到过…你确定操作码是两个完整字节吗?它可能只有6/7位。
1514131211|109|876|5|4|3210||151413| 12 .. 0 |
1 1 1 0 1| 00|010|1|0|1101|| P M 0| register_list |