3

I’m working with a disassembled ARMv7 binary. There are several instances where groups of instructions seem sub-optimal, but this one really caught my attention:

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

Since loc_9250 is the beginning of the epilogue, I interpreted this section as:

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

Am I missing something about the ARMv7 architecture that makes all these instructions necessary (besides my disassembler not substituting the pseudo-mov32 for the movw/movt pairs)? It seems like a very inefficient way of going about this sequence of operations. Or perhaps this is just the result of a compiler with optimisation settings cranked right down.

1 Answer 1

3

This is probably because *ledTimer is volatile. Here's a short bit of code that produces a similar result:

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

Now compile with gcc 8.3.1 with -march=armv7 -O1 and we get something that starts to resemble what you've listed:

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

You can try it live.

2
  • This is just the kind of insight I was looking for, thank you! I hope you don’t mind if I wait a day or so to accept your answer, just in case someone else has other ideas.
    – MTCoster
    Dec 17, 2020 at 16:16
  • No, I don't mind at all. Others may very well provide more detailed answers or create code that exactly matches what you've disassembled. Glad I could be of help!
    – Edward
    Dec 17, 2020 at 16:17

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge that you have read and understand our privacy policy and code of conduct.

Not the answer you're looking for? Browse other questions tagged or ask your own question.