Assembly 如何在ARM汇编程序中编码寄存器操作数?

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} |

我反编译了一些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
的操作码是
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 |