Skip to content

Comment on Raspberry Pi Pico: What is this code doing in its boot ROM, line 442?

Comments

ARM thumb disassembly:

    00:  11 38          subs r0, #0x11
    02:  C0 7A          ldrb r0, [r0, #0xb]
    04:  00 BD          pop  {pc}
    06:  00 B5          push {lr}
    08:  42 40          eors r2, r0
    0a:  00 2A          cmp  r2, #0
    0c:  00 F0 02 F8    bl   #0x14
    10:  F6 D2          bhs  #0
    12:  8E 46          mov  lr, r1
    14:  70 46          mov  r0, lr
    16:  00 47          bx   r0
Edit: I agree with the other commenters that this doesn't really look like a valid disassembly, it is perhaps data rather than code.

Edit2: I take that back - it's just very "creatively" written.

This reads a bit like a spurious decompilation. It's sorta valid but doing very weird things. Random bytes will often decompile to valid Thumb that looks sort of right like this all the time.

04 pop {pc} -> this is an odd way to return from a function on ARM, and likely means that these first bytes would be a very odd function.

06 push {lr} -> OK, maybe a valid prologue, but this function ignores the result of the cmp and calls 0x14.

pop {..., pc} is THE standard way to return from a function that calls other functions itself, on Armv5 and above. Non tail functions usually do this: push {..., lr} ... pop {..., pc}

Only if there's a corresponding push { ..., lr }, but in this case there isn't. I'd expect bx lr here.

As other people are saying, code seems to be jumped at at #6.

I'd expect bx lr here

LR is being clobbered by the bl (EDIT: bl, not blx)

As other people are saying, code seems to be jumped at at #6.

Well yeah, that's what I said above.

LR is being clobbered by the blx

There's no blx in the first section. These first six bytes would only make sense if this small stub ended in bx lr, therefore I don't think it's a valid function.

Normally you'd save more than just PC as AAPCS (https://github.com/ARM-software/abi-aa/blob/main/aapcs32/aap...) mandates stack to be aligned to 8 bytes for "public interface" functions. But this is is not a "public" function so it's fine to only save lr here.

"bx lr" is only used on it's own when the function doesn't call another function (altering lr), and doesn't need to save any registers.

If you see pop {lr}; bx lr then that's code that's being compiled to explicitly support Armv4 (e.g. Arm7TDMI)

EDIT: https://gcc.godbolt.org/z/TadnqescT

    // r0 = arg1, r1 = arg2, r2 = arg3

    if (arg3 ^ arg1 >= 0u)
        return 42; // edited //*(u8 *)(r0 - 17 + 11);
    else // dead code (edited)
        return arg2();

[deleted]

https://www.keil.com/support/man/docs/armasm/armasm_dom13612...

The `BL` instruction does not change the flags.

Doesn't seem like much of an assumption to me :P

This makes a bit of sense when the actual entry point is at

    06:  00 B5          push {lr}
However, even then, the code appears unnecessarily convoluted. Easter egg? Back door ;-)?
AboutSource Built by g1lg1l

Hackerly is an independent reader for Hacker News, built on the public HN API. Not affiliated with Y Combinator.