We’ve all had to use more space somewhere in a routine. So, we’ve had to branch to more space. Generally, from what I’ve heard from @CT075 is we’d do something like this
Offset - Code
00 (code)
02 ldr r1, constant
04 bx r1
06 nop
08 cons-
0A -tant
Then at the end of our custom code, just
bx lr
But this is inflexible – what if we just needed to replace a subroutine? Do a calculation, then do more stuff. I ended up doing something like this:
(code)
push {r1-r2}
ldr r1, constant
mov r2, pc
add r2, #0x5
mov lr, r2
mov pc, r1 @or bx r1
pop {r1-r2}
b stuff_after
.align
.long constant
stuff_after:
Which gets the job done but is sooo horribly inelegant.
Then I realized the answer was under our noses the entire time – look at the way the game handles dynamic functions.
080386B4 9909 ldr r1,[sp,#0x24]
080386B6 F087FACB bl #0x80BFC50
What is at 0x80BFC50? Why, it’s very simple…
080BFC4C 4700 bx r0
080BFC4E 46C0 nop
080BFC50 4708 bx r1 @this is the line we branched to
080BFC52 46C0 nop
080BFC54 4710 bx r2
080BFC56 46C0 nop
080BFC58 4718 bx r3
080BFC5A 46C0 nop
That’s right, what the game does is it uses bl
to set the link register, then uses bx to go where it needs to. It combines the returnability of bl with the longcalling of bx. It also allows for dynamic calling.
So to implement this in our own code, we might change code that’s like
(code)
(where we want our calcs to take place)
(more code)
into something like
(code)
ldr r1, const
bl goto_r1
b more_code
goto_r1:
bx r1 @This may possibly go after the constant depending on word-alignment
.long constant
more_code:
(more code)
And this is the real way to insert more calculations in the middle of a routine. Even more elegantly, if the routine you’re inserting it ends in a bx r0
or bx r1
, you can set a label there and bl
to that.