我正在使用反汇编的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易失。这是一小段产生类似结果的代码:
int main() {
    volatile unsigned short *ledTimer{(unsigned short *)0x14f36};
    for (--(*ledTimer); *ledTimer; --(*ledTimer));
}

现在使用带有-march=armv7 -O1的gcc 8.3.1进行编译,我们得到的内容开始类似于您列出的内容:
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

您可以尝试一下。

评论


这只是我一直在寻找的见解,谢谢!希望您不要介意我等一天左右才能接受您的回答,以防万一其他人有其他想法。

– MTCoster
20/12/17在16:16

不,我一点也不介意。其他人可能会提供更详细的答案或创建与您反汇编的内容完全匹配的代码。很高兴我可以提供帮助!

–爱德华
20/12/17在16:17