You, the programmer, ultimately decide how the memory is divided up. Not the tools, with some exceptions definitely not ARM.
unsigned int x;
unsigned int y=5;
void fun ( void )
{
x=3;
y++;
}
arm-none-eabi-gcc -O2 -c so.c -o so.o
arm-none-eabi-objdump -D so.o
so.o: file format elf32-littlearm
Disassembly of section .text:
00000000 <fun>:
0: e3a00003 mov r0, #3
4: e59f2014 ldr r2, [pc, #20] ; 20 <fun+0x20>
8: e5923000 ldr r3, [r2]
c: e59f1010 ldr r1, [pc, #16] ; 24 <fun+0x24>
10: e2833001 add r3, r3, #1
14: e5823000 str r3, [r2]
18: e5810000 str r0, [r1]
1c: e12fff1e bx lr
...
Disassembly of section .data:
00000000 <y>:
0: 00000005 andeq r0, r0, r5
Disassembly of section .bss:
00000000 <x>:
0: 00000000 andeq r0, r0, r0
That is at the object level.
Then if we link
MEMORY
{
one : ORIGIN = 0x00000000, LENGTH = 0x1000
two : ORIGIN = 0x20000000, LENGTH = 0x1000
three : ORIGIN = 0x20002000, LENGTH = 0x1000
}
SECTIONS
{
.text : { *(.text*) } > one
.rodata : { *(.rodata*) } > one
.bss : { *(.bss*) } > two
.data : { *(.data*) } > three
}
arm-none-eabi-ld -T flash.ld so.o -o so.elf
arm-none-eabi-objdump -D so.elf
so.elf: file format elf32-littlearm
Disassembly of section .text:
00000000 <fun>:
0: e3a00003 mov r0, #3
4: e59f2014 ldr r2, [pc, #20] ; 20 <fun+0x20>
8: e5923000 ldr r3, [r2]
c: e59f1010 ldr r1, [pc, #16] ; 24 <fun+0x24>
10: e2833001 add r3, r3, #1
14: e5823000 str r3, [r2]
18: e5810000 str r0, [r1]
1c: e12fff1e bx lr
20: 20002000 andcs r2, r0, r0
24: 20000000 andcs r0, r0, r0
Disassembly of section .bss:
20000000 <x>:
20000000: 00000000 andeq r0, r0, r0
Disassembly of section .data:
20002000 <y>:
20002000: 00000005 andeq r0, r0, r5
A picture like the one you are looking at the .data and .bss are your global data. .data being initialized and .bss being uninitialized.
This of course is not a usable binary there is no exception table there is no bootstrap, etc. But this also shows that the tools just do what you tell them. You are ultimately responsible.
this is the pool here
20: 20002000 andcs r2, r0, r0
24: 20000000 andcs r0, r0, r0
I used the disassembler so it tries to disassemble the address, ignore the andcs stuff. You can see how the code is generated so that later during linking the linker can connect the code to the address where these data items live.
So as covered in the comments under the question the variable is in the global data area and the pool points at it. The pool can be used for other reasons too. Any time the code needs more "immediate" type data. If this were x86 or some other variable length instructions then these type of values may be part of the "instruction" as the instruction if you look at it from the view that it has its own pool.
unsigned int fun ( void )
{
return(0x12345678);
}
00000000 <fun>:
0: e59f0000 ldr r0, [pc] ; 8 <fun+0x8>
4: e12fff1e bx lr
8: 12345678 eorsne r5, r4, #120, 12 ; 0x7800000
This instruction set cannot have 32 bits of immediate, so it could build up with four instructions or two with newer arm instructions. Or do a load from the pool.
To demonstrate that comment, not that x86 matters here.
0000000000000000 :
0: c7 05 00 00 00 00 03 movl $0x3,0x0(%rip) # a <fun+0xa>
7: 00 00 00
a: 83 05 00 00 00 00 01 addl $0x1,0x0(%rip) # 11 <fun+0x11>
11: c3 retq
0000000000000000 :
0: b8 78 56 34 12 mov $0x12345678,%eax
5: c3 retq
Disassembly of section .text:
0000000000000000 <fun>:
0: c7 05 f6 ff ff 1f 03 movl $0x3,0x1ffffff6(%rip) # 20000000 <x>
7: 00 00 00
a: 83 05 ef 1f 00 20 01 addl $0x1,0x20001fef(%rip) # 20002000 <y>
11: c3 retq
Disassembly of section .bss:
0000000020000000 <x>:
20000000: 00 00 add %al,(%rax)
...
Disassembly of section .data:
0000000020002000 <y>:
20002000: 05 .byte 0x5
20002001: 00 00 add %al,(%rax)
...
And the linker modifies the instruction itself and not a pool area. I am sure there are, and sure I can generate, some pool space for x86 as well.
Also notice that the same linker script used on x86, tells x86 what I want it to do.
End of the day you are in control of the consumption of memory at this level. There are some hardware rules like where the chip comes out of reset and how, and in some cases like cortex-m some chunks of memory are for flash/code some are for data, some are for peripherals. You ultimately should know this and design your memory map accordingly. Most of the time folks just take tools from someone else set up for the target in question, and it all just magically happens.
Just like when you use your compiler for your host windows/linux/etc computer that toolchain is configured to make binaries for that target processor and operating system. Same source code compiled for linux is a different result than for windows, same toolchain/version, built for the different target.