3

I am coding a small cortex M0+ bootloader. I have a inline assembly below that start the main application from the bootloader by loading the stack pointer and reset handler from application position in Flash.

#define FLASH_APP_START 0x1000

[...]

    __asm(
            // Update stack pointer from user code vector table
            "LDR     r0, =%0 \n"
            "LDR     r1, [r0] \n"
            "MOV     sp, r1 \n"

            // Load user code reset handler and jump to the user code
            "LDR     r0, [r0, #4] \n"
            "BX      r0 \n"
            :
            : "X"(FLASH_APP_START)
            :
        );

When compiling this code I get the following error:

Error: bad expression -- `ldr r0,=#4096'

GCC add the # before the constant that should not be there. If I replace the first line by the following it works perfectly.

LDR r0, =0x1000

So the question is how could I use the defined constant ?

Thanks in advance for any help

3
  • 1
    A few thoughts: You are changing r0 and r1 in this template without clobbering them. That seems bad. As for the #, you could try %c0. Commented Dec 22, 2015 at 10:47
  • A capital 'R' as a constraint for the literal pool is improperly documented in the gcc manual. David's suggestion is correct; use the '%creg' modifier as per godbolt example. The manual has this under the title 'Modifier Description '. Commented Dec 23, 2015 at 15:50
  • A related question on inline assembler and the constant pool. Commented Dec 23, 2015 at 15:56

1 Answer 1

1

First there's as no reason to use inline assembly here, the simple solution would be to just write this code as a normal assembly language file. You can define the FLASH_APP_START macro in a header file that you can include in both the assembly and C source files if necessary.

If you still want to use inline assembly then next simplest solution would be to let the compiler do most of the work for you and reduce the assembly statement to just what it can't do:

    void ** const flash_vector_table = (void **) FLASH_APP_START;
    asm volatile ("mov sp, %[stack]\n\t"
                  "bx %[reset]\n"
                  :
                  :
                  [stack] "r" (flash_vector_table[0]),
                  [reset] "r" (flash_vector_table[1]));
Sign up to request clarification or add additional context in comments.

1 Comment

As it should be. Thanks !

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.