I am using MBD9F126(ARM Cortex R4) micro-controller. In that I am flashing code into ROM and then I am executing the code from RAM after RAM copy. I am using the Green hills compiler. Before the RAM copy I am executing basic board Initialization code.
LDR r12, ADDRESS_START_PREINIT
BLX r12
ADDRESS_START_PREINIT:DCD Start_PreInit
Start_PreInit is board initialization function. IF I am giving like this after BLX it’ll branch to RAM location. As RAM copy is not done yet so it goes to unknown area.
Instead of this If I am writing
bl Start_PreInit
Its working properly that is going to ROM location of code. I don’t why compiler has such a behavior?
And also
ADDRESS_START_PREINIT:DCD Start_PreInit . Is it done during linking??
The
bl Start_PreInitinstruction works because the branch target is encoded in the instruction opcode as an offset relative to the currentPC(r15). Sincer15is pointing to ROM, the target is another ROM address.The
blx r12instruction branches to the absolute address that was loaded into ther12register.When you load the contents of
ADDRESS_START_PREINITinto a register, what you’re getting is the absolute address that the linker calculated for theStart_PreInitaddress. Apparently the linker has fixed that to the RAM absolute address.You might be able to fix the problem with a linker configuration or by performing some transformation on
r12when it’s loaded with the RAM address (something like(r12 - RAM_START) + ROM_START) before branching. Or use the pc-relative encoding instead of the register-absolute encoding for the branch instruction if the target address is in range.