Program at any address in ARM cortex M3 assembler

0

Does anyone know how to put a program in an ARM assembler at an arbitrary address in memory? By default, the program is located starting from the address 0x00000008, but it is necessary that it be located, for example, at the address 0x20002000. I tried to use DCD 0x20002000, but this only changes the register-pointer, while the program remains at the old address. The SPACE 0x400 command works well, but if the address is too large, then the compilation takes a very long time. Tell me, maybe faced with this?

enter image description here

assembly
arm
cortex-m3
asked on Stack Overflow Feb 22, 2019 by MadEvil • edited Feb 22, 2019 by fuz

2 Answers

1

You can usually achieve this result by modifying the linker script you are using, or by providing certain command-line options to GNU ld.

From the information you provided, I am assuming that your code is currently starting right after the two first vector entries table, i.e. the Initial SP Value, and the Reset Value, and that your vector table is located at 0x00000000.

example1.s should more or less look like your current code:

        .cpu    cortex-m3
        .thumb    
        .syntax unified
        .global Reset_Handler
        .equ    StackTop, 0x1000
        .word   StackTop         
        .word   Reset_Handler
Reset_Handler:
         b .
        .end


/opt/arm/gcc-arm-8.2-2019.01-x86_64-arm-eabi/bin/arm-eabi-as -o example1.o -c example1.s
/opt/arm/gcc-arm-8.2-2019.01-x86_64-arm-eabi/bin/arm-eabi-ld -g -e Reset_Handler -Ttext-segment=0x00000000 -Map=example1.map -o example1.elf example1.o
/opt/arm/gcc-arm-8.2-2019.01-x86_64-arm-eabi/bin/arm-eabi-objdump -d example1.elf

example1.elf:     file format elf32-littlearm

Disassembly of section .text:

00000000 <Reset_Handler-0x8>:
   0:   00001000        .word   0x00001000
   4:   00000008        .word   0x00000008

00000008 <Reset_Handler>:
   8:   e7fe            b.n     8 <Reset_Handler>

The code will then be located at 0x00000008.

example2.s defines a new linker section named .vectors.

We will now use GNU ld --section-start command-line option to force the .vectors section to reside at 0x00000000, and still use -Ttext-segment to force the .text section/ text segment to reside at 0x20002000.

example2.s:

    .cpu    cortex-m3                                                                                                                                                                                                                                              
    .thumb                                                                                                                                                                                                                                                                 
    .syntax unified                                                                                                                                                                                                                                                        
    .global Reset_Handler                                                                                                                                                                                                                                                  
    .equ    StackTop, 0x1000                                                                                                                                                                                                                                               

    .section .vectors                                                                                                                                                                                                                                                      
    .word   StackTop                                                                                                                                                                                                                                                       
    .word   Reset_Handler                                                                                                                                                                                                                                                  

    .section .text                                                                                                                                                                                                                                                         

Reset_Handler:
b .

/opt/arm/gcc-arm-8.2-2019.01-x86_64-arm-eabi/bin/arm-eabi-as -o example2.o -c example2.s
/opt/arm/gcc-arm-8.2-2019.01-x86_64-arm-eabi/bin/arm-eabi-ld -g -e Reset_Handler --section-start=.vectors=0x00000000 -Ttext-segment=0x20002000 -Map=example2.map -o example2.elf example2.o
/opt/arm/gcc-arm-8.2-2019.01-x86_64-arm-eabi/bin/arm-eabi-ld: warning: address of `text-segment' isn't multiple of maximum page size
/opt/arm/gcc-arm-8.2-2019.01-x86_64-arm-eabi/bin/arm-eabi-objdump -d -j .vectors -j .text -d example2.elf

example2.elf:     file format elf32-littlearm


Disassembly of section .vectors:

00000000 <.vectors>:
   0:   00001000        .word   0x00001000
   4:   20002000        .word   0x20002000

Disassembly of section .text:

20002000 <Reset_Handler>:
20002000:       e7fe            b.n     20002000 <Reset_Handler>
        .end    

The vector table is still located at the correct memory location, but the code now resides at 0x20002000.

In order to describe the exact changes required in the linker script you are using for achieving the same result, I would need to see its content.

answered on Stack Overflow Feb 22, 2019 by Frant
1

There are basically two ways to control the location of the code region using Keil. Either using the scatter file, or using the 'target' tab in the build options dialogue.

You can define an IROM region which includes the region where you want your code to be located. You can also start by using this dialogue to generate an initial scatter file, then modify the scatter file based on the Keil documentation.

However, the location you have given here is in the RAM region, which is a little unusual (maybe inefficient, but valid). Have you considered how to initialise your target after power cycling it?

The biggest problem is that at reset, Cortex-M3 will ALWAYS read from addresses 0, 4 (and 8 due to prefetch). You need to provide an initial stack pointer (or not use the stack), and your reset vector (with bit 0, the T-bit, set). There may be hardware banking of the memory map (device specific), but the programmer's view is always that these fetches start at address 0.

answered on Stack Overflow Feb 25, 2019 by Sean Houlihane • edited Feb 26, 2019 by Sean Houlihane

User contributions licensed under CC BY-SA 3.0