在arm反汇编文件(.dis)中经常在<.text段文字池>或<.bss>段中看到一些奇怪的代码,比如:
1、.text段文字池:
0000003c: 0000804c andeq r8, r0, ip, asr #32
00000040: 00008048 andeq r8, r0, r8, asr #32
2、.bss段:
0000804c: 00000000 andeq r0, r0, r0
其中第一列表示链接地址,第二列为链接地址中的数据,第三列表示数据对应的汇编指令;
这里需要强调的是,这些地址中的数据仅仅只是数据,而不是命令,所以后面对应的汇编语句也不会执行;并不是说这些汇编语句本身不能执行,而是在这种特定情景中它们仅仅代表数据。
下面我们首先来分析,为什么<andeq r0, r0, r0>就代表数据0x00000000呢?
看一下这种and汇编指令对应的二进制格式:
and {<cond>} {S} <Rd>, <Rn>, <shifter_operand>
31~28 | 27~26 | 25 | 24~21 | 20 | 19~16 | 15~12 | 11~0 |
cond | 00 | I | 0000 | S | Rn | Rd | Shifter_operand |
根据具体的指令形式(<Rm>形式),二进制格式可以细化为:
31~28 | 27~25 | 24~21 | 20 | 19~16 | 15~12 | 11~7 | 6~4 | 3~0 |
0000 | 000 | 0000 | 0 | r0(0) | r0(0) | 00000 | 000 | r0(0) |
所以指令<andeq r0, r0, r0>对应的二进制格式为0x00000000,也就说明了,在反汇编代码bss段中有大量的这种代码,也就不足为奇了。
下面再分析一个例子,<andeq r8, r0, ip, asr #32>:
同上面的分析,根据指令形式(<Rm>, asr #<shift_imm>形式),二进制格式直接细化为:
31~28 | 27~25 | 24~21 | 20 | 19~16 | 15~12 | 11~7 | 6~4 | 3~0 |
0000 | 000 | 0000 | 0 | Rn | Rd | Shift_imm | 100 | Rm |
在二进制指令格式中:
r0表示为0000,Rn=0000;
r8表示为1000,Rd=1000;
ip(r12)表示为1100,Rm=12=0xc;
当shift_imm=0时,表示移位32位。
上图用具体数据替换后为:
31~28 | 27~25 | 24~21 | 20 | 19~16 | 15~12 | 11~7 | 6~4 | 3~0 |
0000 | 000 | 0000 | 0 | 0000 | 1000 | 00000 | 100 | 000c |
也就是指指令<andeq r8, r0, ip, asr #32>的二进制形式为0x0000804c。
最后一个指令<andeq r8, r0, r8, asr #32>的二进制形式为0x00008048,在这里就不分析了。