Search code examples
assemblyarm

What's the difference between "ldr pc, _boot" and "b _boot"?


I was examining a vector table for the ARM Cortex A9 and stumbled accross two types of instructions:

B _boot

and

LDR PC, _boot

Can someone explain to me the difference in using B or LDR? Both code should do the same but apparently there must be a difference. Has it something to do with the link register?

Thanks for your time!


Solution

  • ldr reg, symbol loads data from memory at that address, into the register. Loading into PC is a memory-indirect jump.
    It will only assemble and link if _boot is near enough for a PC-relative addressing mode to reach it, but that's likely if both are in the .text section.

    b symbol sets PC = the address of the symbol. It's direct relative jump.

    The link register is no involved in either case because you use b not bl or blx.


    ldr pc, _boot

    Another way to do what ldr pc, _boot does:

       ldr  r0, =_boot         @ "global variable" address into register
       ldr  r0, [r0]           @ load 4 bytes from that symbol address
       br   r0                 @ and set PC = that load result
    

    Assuming your _boot: label is in front of some code, rather than a .word another_symbol, this is not what you want. You'd be loading some bytes of machine code and using it as an address. (Setting PC to somewhere probably invalid.)

    But if you do have _boot: .word foobar or something, then it is what you want.


    b _boot

    Or the equivalent of b _boot in terms of ldr would be to load the address from memory into PC. That would mean you'd need a word in memory holding that address, instead of just the immediate relative displacement in the b encoding.

    But ARM assemblers have a pseudo-instruction to do that:
    ldr pc, =_boot will load that label address into PC, using a PC-relative addressing mode to load from a nearby literal pool. Or instead of into PC directly, you could set up for a br.

      ldr  r0, =_boot       @ symbol address into register
      br   r0               @ jump to that symbol
    

    This is not exactly equivalent: it's not position-independent because it's using absolute addresses, not just a relative branch.