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

Is it mistake to force PC to specific address?

I want to make mechanism to force my processor (LPC2378) to do one program if some flag is set and to do another if that flag isn't set.
But that two programs may have functions with same name and I want to insure that right one will be executed.

  • Hi Bojana,

    I'm still not entirely sure I understand what you are trying to do here. You could link the programs to different addresses (say prog1 at 0x8000, prog2 at 0x9000). Then have a third assembly level program that tests a flag (at say 0x1000), and then based on that, jump to appropriate address. Note the thumb code address should be "odd" in the below as least significant bit highlights to the core that you are going to Thumb state (even though Cortex-M3 only supports Thumb state...).

         AREA test, CODE

         ENTRY

    flag     EQU 0x1000

    prog1    EQU 0x8000 +1

    prog2    EQU 0x9000 +1


    testflag

         LDR r0, =flag

         LDR r1, [r0]


         CMP r1, #0

         LDREQ pc, =prog1

         LDRNE pc, =prog2


         END


  • I see there is much discussion on the other thread on bootloaders and functionality therein. I think that thread addresses this topic fully.

  • Ok, but what if i want to do this from C code.
    I tried that with inline _asm function but I got error message?

                                  #pragma thumb

                                         __asm void GOTO_ADD // __thumb //compile this in Thumb instruction set

                                              {

                                                   LDR pc,0x6000; //move entry address into PC

                                              }

                                     #pragma arm

    Glavni.c(34): error:  #130: expected a "{"

                             __asm void GOTO_ADD // __thumb  //compile this in Thumb instruction set

    Glavni.c(34): error:  #20: identifier "GOTO_ADD" is undefined

                                            __asm void GOTO_ADD // __thumb  //compile this in Thumb instruction set

    Glavni.c(35): error:  #65: expected a ";"

                                            {

  • If you want to jump to a fixed address in C you can just do something like:

    #define FN_ADDR 0x6000 // be sure to set the low bit if the destination is Thumb state code

    ...

        ((void (*)(void))FN_ADDR)();

    ...

    Or, if you're not a fan of brevity:

    ...

        typedef void fn_t(void);

        ((fn_t *)FN_ADDR)();

    ...

    The cast is technically undefined behavior, but it'll do "the right thing".

  • The particular error you were getting I think is because you needed an "=" (LDR pc, =0x6000).  Also it would complain about the PC being the destination (in Thumb)  for earlier versions of the architecture.

    That said, I'd go with Scott's suggestion - use a function pointer.

    One thing to be wary of, if you perform an absolute branch the bottom bit of the address will be used to determine whether the branch target is ARM or Thumb (*).  So an absolute branch to 0x6000 arrives in ARM state, while an absolute branch to 0x6001 arrives in Thumb state. 

    (* I'm assuming ARMv7)