This discussion has been locked.
You can no longer post new replies to this discussion. If you have a question you can start a new discussion

function pointer assignment

Note: This was originally posted on 22nd December 2008 at http://forums.arm.com

Hi,

I've a scenario here.

say, i have 2 functions. func1 and func2.

func1is at adddress 0x28 and func2 at some other location.
now, i have to pass func1 through func2 (where func1 is a callback function)

func2(func1);
while executing the above,  i observed in the assembly instruction that,

ldr r3,0xdb1f0 is called where

At 0xdb1f0:  dcd 0x29 is found.
so that r0 =0x29  (address of func1+1)

Now my question is:
1. why the func1 address 0x29 (func1+1) is loaded instead of 0x28 (func1). what is the logic behind this behaviour.

Please some one answer my question. Though it is not obstructing my work, just curious to know the reason for this behaviour.

Thanks
  • Note: This was originally posted on 23rd December 2008 at http://forums.arm.com

    Indeed. I inserted the values directly in order to simplify the code sample, but bhav's comment is correct and the code example I gave will not work as it is. As bhav suggested, the pointer will be in a register if it is passed as a callback, so either of the B(L)X instructions will accept it.

    Refer to the [url="http://infocenter.arm.com/help/topic/com.arm.doc.qrc0001l/QRC0001_UAL.pdf"]instruction set reference card[/url] for descriptions of the various options available for branch instructions.
  • Note: This was originally posted on 22nd December 2008 at http://forums.arm.com

    The reason for this is simple, though not obvious at first.

    Most ARM processors provide two instruction sets: ARM and Thumb. Some newer processors also provide Thumb2, and indeed the Cortex-M3 only provides Thumb2.

    ARM instructions are all 4 bytes long and are all aligned on 4-byte boundaries. Thumb instructions are all 2 bytes long and are all aligned on 2-byte boundaries. (Thumb2 instructions are either 2 or 4 bytes long, but are also always aligned in 2-byte boundaries.)

    You'll probably have noticed that the bottom bit of the address pointer is therefore never used to locate an address. The bottom bit of the address pointer is used to indicate the processor mode that the code should execute in. It seems that your code executes in Thumb mode.

    Of course, the mode switch won't happen automatically with a standard B instruction, so you have to use BX.

    BX 0x100 // Branches to address 0x100 and switches to ARM mode.
    BX 0x201 // Branches to address 0x200 and switches to Thumb mode.
    B  0x301 // No mode switch occurs, so the result is undefined as you can't branch to a misaligned address.


    Does that make sense? If you recompile your code for ARM instructions, your function pointer will be "0x28".

    Jacob
  • Note: This was originally posted on 22nd December 2008 at http://forums.arm.com

    Of course, the mode switch won't happen automatically with a standard B instruction, so you have to use BX.

    BX 0x100 // Branches to address 0x100 and switches to ARM mode.
    BX 0x201 // Branches to address 0x200 and switches to Thumb mode.
    B  0x301 // No mode switch occurs, so the result is undefined as you can't branch to a misaligned address.


    Just a quick note...  The rest of the reply is correct, but there is no "BX label" instruction, so this isn't quite right.  You are thinking of the BL and BLX instructions.  e.g.  "BL xxx" branches to xxx without changing state, "BLX xxx" branches to xxx and changes to the opposite state.

    Aside, for a function pointer I assume the address is in a register, so using this register with a BX or BLX instruction would detect the state by looking at the low bit.