In our previous post we look into how the compiler organize our code into sections, now is time to see how we can assign those section in different addresses. We are going to require an extra step because dealing with memory addresses is a job for the Linker, let's write the following code:

unsigned long var1;
unsigned long var2 = 34;

int main( void )
{
    return 0;
}

Compile and display the header information one more time

$ arm-none-eabi-gcc -c main.c -o main.o -mcpu=cortex-m0plus
$ arm-none-eabi-objdump -h main.o

main.o:     file format elf32-littlearm

Sections:
Idx Name          Size      VMA       LMA       File off  Algn
  0 .text         0000000c  00000000  00000000  00000034  2**1
                  CONTENTS, ALLOC, LOAD, READONLY, CODE
  1 .data         00000004  00000000  00000000  00000040  2**2
                  CONTENTS, ALLOC, LOAD, DATA
  2 .bss          00000004  00000000  00000000  00000044  2**2
                  ALLOC
  3 .comment      0000001f  00000000  00000000  00000044  2**0
                  CONTENTS, READONLY
  4 .ARM.attributes 0000002c  00000000  00000000  00000063  2**0
                  CONTENTS, READONLY

Nothing new. This time lets focus on column VMA ( virtual memory address ), for the moment we can observe all sections had been assigned a memory address of 0x00000000 which is not what we want because that’s mean all of them will be overlapped, we need somehow assign different addresses. We can do that easily with our friend Linker just like this

$ arm-none-eabi-gcc -c main.c -o main.o -mcpu=cortex-m0plus
$ arm-none-eabi-gcc main.o -o main.elf -nostdlib -e main -mcpu=cortex-m0plus -Ttext 0x1000 -Tbss 0x2000 -Tdata 0x3000 
$ arm-none-eabi-objdump -h main.elf

main.elf:     file format elf32-littlearm

Sections:
Idx Name          Size      VMA       LMA       File off  Algn
  0 .text         0000000c  00001000  00001000  00001000  2**2
                  CONTENTS, ALLOC, LOAD, READONLY, CODE
  1 .bss          00000004  00002000  00002000  0000100c  2**2
                  ALLOC
  2 .data         00000004  00003000  00003000  00003000  2**2
                  CONTENTS, ALLOC, LOAD, DATA
  3 .persistent   00000000  00003004  00003004  00003004  2**0
                  CONTENTS, ALLOC, LOAD, DATA
  4 .noinit       00000000  00002004  00002004  00000000  2**0
                  ALLOC
  5 .comment      0000001e  00000000  00000000  00003004  2**0
                  CONTENTS, READONLY
  6 .ARM.attributes 0000002c  00000000  00000000  00003022  2**0
                  CONTENTS, READONLY

On column VMA sections .text, .bss and .data we can observe addresses are now the ones we indicated at the moment we link our program using -Ttext, -Tbss and -Tdata options, The numbers I used are just for illustrative purpose but in theory you will assigned the address where the flash and RAM memories are located.

And what about the .rodata and the custom sections we create, how can we indicate where to place those section with the linker?. well you can not, at least not in this way, we need a different approach, something more sophisticated. We need a Linker script!!