理解ARMv7看似过于冗长的反汇编

逆向工程 拆卸 手臂
2021-06-15 10:23:42

我正在使用反汇编的 ARMv7 二进制文件。有几种情况下,指令组似乎不是最理想的,但这个确实引起了我的注意:

00009086         movw       r3, #0x4f36
0000908a         movt       r3, #0x1                                            ; ledTimer
0000908e         ldrh       r3, [r3]                                            ; ledTimer
00009090         subs       r3, #0x1
00009092         uxth       r2, r3
00009094         movw       r3, #0x4f36
00009098         movt       r3, #0x1                                            ; ledTimer
0000909c         strh       r2, [r3]                                            ; ledTimer
0000909e         movw       r3, #0x4f36
000090a2         movt       r3, #0x1                                            ; ledTimer
000090a6         ldrh       r3, [r3]                                            ; ledTimer
000090a8         cmp        r3, #0x0
000090aa         bne.w      loc_9250

由于loc_9250是结语的开头,我将此部分解释为:

if (--ledTimer != 0) {
    return;
}

我是否遗漏了使所有这些指令成为必需的 ARMv7 体系结构(除了我的反汇编程序没有用伪mov32代替movw/movt对)?处理这一系列操作似乎是一种非常低效的方式。或者,这可能只是编译器优化设置降低的结果。

1个回答

这可能是因为*ledTimer是 volatile。这是产生类似结果的一小段代码:

int main() {
    volatile unsigned short *ledTimer{(unsigned short *)0x14f36};
    for (--(*ledTimer); *ledTimer; --(*ledTimer));
}

现在使用 gcc 8.3.1 with 进行编译,-march=armv7 -O1我们得到一些开始类似于您列出的内容:

main:
        movw    r2, #20278
        movt    r2, 1
        ldrh    r3, [r2]
        subs    r3, r3, #1
        uxth    r3, r3
        strh    r3, [r2]        @ movhi
        ldrh    r3, [r2]
        uxth    r3, r3
        cbz     r3, .L2
        movw    r2, #20278
        movt    r2, 1
.L3:
        ldrh    r3, [r2]
        subs    r3, r3, #1
        uxth    r3, r3
        strh    r3, [r2]        @ movhi
        ldrh    r3, [r2]
        uxth    r3, r3
        cmp     r3, #0
        bne     .L3
.L2:
        movs    r0, #0
        bx      lr

你可以现场试一试