cancel
Showing results for 
Search instead for 
Did you mean: 

Jumping execution to an absolute address

smart
Associate II
Posted on March 08, 2008 at 05:12

Jumping execution to an absolute address

6 REPLIES 6
smart
Associate II
Posted on May 17, 2011 at 12:25

I want to write a code to jump at an absolute location.

I used this code I always get hard fault exception

I have already defined some code at 0x8006C00.

typedef void (*appFunc)(void);

void main(void)

{

u32 appFuncAddr;

… some other code

appFuncAddr = (u32)0x8006C00;

((appFunc)appFuncAddr)();

}

troy
Associate
Posted on May 17, 2011 at 12:25

Try This, I haven't tried this but I think it will work

typedef void (*appFunc)(void);

void main(void)

{

appFunc appFuncAddr;

… some other code

appFuncAddr = (appFunc )0x8006C00;

appFuncAddr)();

}

Troy

ericvanolden9
Associate II
Posted on May 17, 2011 at 12:25

If you want to jump at address 0x8006C00, you must write

appFuncAddr = (appFunc )0x8006C01;

Some explanations :

Remember that previous ARM processors have two sets of instructions : ARM and Thumb. To go from one set to other a BX instruction is use with the form of BX Rx. If bit 0 of Rx is 0, next is ARM instructions, if bit 1 of Rx is 1, next is Thumb instructions.

With Cortex-M3, there is no ARM instructions but only Thumb with Thumb2 extensions. But BX instructions is the same. If you try to go to ARM instructions you obtain an Hard Fault Exception.

When you write :

appFuncAddr = (appFunc )0x8006C00;

appFuncAddr)();

compiler generate

LDR Rx,=0x8006C00

BX Rx

So bit 0 is 0 and you try to go to ARM instructions.

If your code is at 0x8006C00, you must have in assembleur :

LDR Rx,=0x8006C01

BX Rx

So processor jump at address 0x8006C00 in Thumb mode (bit 0 is 1)

smart
Associate II
Posted on May 17, 2011 at 12:25

Thanks Eric,

with your suggestions code is working.

Thanks a lot!!

ericvanolden9
Associate II
Posted on May 17, 2011 at 12:25

With IAR assembler, bit 0 is set for label in code section (keyword 'thumb') but is reset in data section (keyword 'data').

When you declare a jump table with directive 'dc8', 'dc16' or 'dc32', you are generally in data section and so label for start of jump table don't have bit 0 set.

gdp123a
Associate II
Posted on May 17, 2011 at 12:25

Thanks Eric, your clear explanation has helped me understand a problem I was having with my assembler routine.

I'm new to ARM processors and this mode swapping scheme (called ''interworking'') took me by surprise. This was causing me trouble when trying to calculate the address into a jump table.

I now understand that with the IAR assembler, all labels in code space have bit0 = 1 (because they are thumb code labels).

So the following will work:

ADR Rx, =Label ;where label is in code space, bit 1 is set

BX Rx

but the following won't work (this is what I was doing wrong):

ADR Rx, =Label

MOV PC, Rx ;FAIL - will try and jump to odd address

The ''MOV PC, Rx'' isn't an interworking instruction (it doesn't consider bit0 as special), so it tries to jump to an odd address - causing an exception.

Some assemblers apparently don't set bit0 on labels, so I will be using the following code to ensure portability:

ADR Rx, Start_of_jump_table

BIC Rx, Rx, #1 ;clear that tricky interworking bit

ADD Rx, Rx, Ry ;add any jump table offset here

MOV PC, Rx ;jump into the table

So the following might work for Troy as well:

LDR Rx,=0x8006C00

MOV PC, Rx

Greg.