0

I know bx is used for switching to thumb, and from this answer I came to know that:

BX won't switch to Thumb mode if the least significant bit of the target address is 0. In other words, it can be used as a regular branch as well.

I've noticed that the bx lr is also generated if compiling with -marm, so it should never do the switch, and always behave like a normal branch.

So my question is, why does the compiler generate this bx lr, as opposed to mov pc, lr or push {lr} [...] pop {pc}?

mell_o_tron
  • 143
  • 7

1 Answers1

0

This is heavily opinion based, and you would have to dig up the authors of each compiler and ask them directly.

Why not? before thumb the compilers like gnu used mov pc,lr because that was a return. But once thumb came along and got integrated into the compilers then that changed to bx lr. It does not make sense to if-then-else this since bx lr works for all cases, no need to add code for a mov pc,lr.

As far as pop {pc} it will use it for architectures it can. Now this is more of a fair question. So for example armv4t cannot switch to thumb mode with a pop so you will see the return constructed as a pop into lr then a bx lr (or pop into a lower register if in thumb mode). Where if there is no interwork at all needed and in arm mode then a pop pc could have worked. -marm I would assume does not disable thumb-interwork. Just means you want it to generate the arm instructions. If you specify the architecture I think even armv5 it does not generate the extra bx lr and will generate a pop {pc}.

So you can try without interwork and armv4t and see if it uses a pop {pc}.

But in general you would need to contact the individual compiler developers directly for these kinds of "why" questions.

old_timer
  • 69,149
  • 8
  • 89
  • 168