ADR instruction

cancel
Showing results for 
Show  only  | Search instead for 
Did you mean: 

ADR instruction

3,754 Views
ianbenton
Senior Contributor I

I have just upgraded to MCUXpresso 11.1 and all the addresses calculated by the ADR instruction are now messed up.

See screenshots. . . (the software is for an LPC15xx)

Previously, the name of the label required "+1" after it to make sure that it set bit 0 in the destination address for Thumb mode. 

Now it seems fairly random whether it does or doesn't. I thought it was something to do with the presence or absence of ".thumb_func", but that doesn't seem to make much difference either.

A simple workaround would be to use "|1" (OR 1) to set bit zero, but that gives an error every time saying that the parameters are wrong for the instruction.

Using the LDR instruction instead appears to work, but changing it throughout the code isn't so simple as the "=" has to be added before the name of the label.

Has anyone else noted this?

A further point, 11.1 seems to get out of sync with the program very easily and refuse to get itself realigned.

Even clicking "debug" doesn't seem always to rewrite the flash, and it appears to do the "attach" procedure instead

Labels (2)
0 Kudos
5 Replies

3,653 Views
xiangjun_rong
NXP TechSupport
NXP TechSupport

Hi, Ian,

Regarding your question, of course, you are right that the PC value must be an odd value for the thumb instruction for Cotem-M3 core.

If you use the Label to branch with B label1, or branch to a function for example BL func1, the func1 and label1 are label, in this way, the assembly compiler of MCUXpresso tools is smart enough to add 1.

I suppose if you use BLX Rm instruction, because user is responsible for computing the target address in Rm, adding 1 using ADR is required by user.

Hope it can help you

BR

XiangJun Rong

0 Kudos

3,653 Views
ianbenton
Senior Contributor I

Having examined all of the disassembly, I find the following:

I always use ADR Rx,<label>+1

If the address of the label is GREATER than the current pc address, the compiler produces ADD.W PC,#offset, and offset is always ODD, so it works correctly.

If the address of the label is LESS than the current pc address, the compiler produces SUB.W PC,#offset and the offset is always EVEN, so it fails.

If I refer back to software that has not been complied since I upgraded to McuXpresso 11 I find that the offset is ALWAYS odd regardless of whether the instruction is ADDW or SUBW.

Your explanation please?

Why does ADR Rx,<label>|1 always produce an error?

0 Kudos

3,653 Views
ianbenton
Senior Contributor I

That's mighty interesting reading

However, If my code says: ADR R0,startbreak+1 

it assembles as:      a84: f2af 20bc subw r0, pc, #700 ; 0x2bc

and if it says:   ADR R0,startbreak

it assembles as:      a84: f2af 20bd subw r0, pc, #701 ; 0x2bd

it has used "sub.w" both times! It has added an extra 1 twice, making the destination address 1 HIGHER than it should be.

If I specify "ADR.w" then it makes no difference.

But in older versions of MCU Xpresso it got it right. It's only when I was re-developing an old bit of software that I found the problem.

0 Kudos

3,653 Views
converse
Senior Contributor V

Maybe there was a bug introduced in GCC (or maybe it was a bug fix?). Did you try v11.1.1?

However, the official ARM manual says that the "LDR Rn,=value" pseudo-instruction will be automatically replaced by the fastest and least memory consuming instruction(s) that will load the value into Rn. So, you probably want to replace you ADR's with LDR Rn, [PC, #208] (or whatever is appropriate in your code).

0 Kudos