MemoryRegions 01

You might also like

Download as pdf or txt
Download as pdf or txt
You are on page 1of 4

28/01/2021 PrintWhatYouLike on text, data and bss: Code and Data Size Explained | MCU on Eclipse

text, data and bss: Code and Data Size Explained


Posted on April 14, 2013 by Erich Styger

In “Code Size Information with gcc for ARM/Kinetis” I use an option in the ARM gcc tool chain for Eclipse to show me the code
size:

text data bss dec hex filename


0x1408 0x18 0x81c 7228 1c3c size.elf

I have been asked by a reader of this blog what these item numbers really mean. Especially: what the heck is ‘bss’????

Note: I’m using the ARM GNU ‘printsize’ utility for gcc, with an example for Kinetis-L (KL25Z).

text

‘text’ is what ends up in FLASH memory. I can show this with adding

1 void foo(void) {
2 /* dummy function to show how this adds to 'text' */
3 }

to my program, the ‘text’ part increases so:

text data bss


0x1414 0x18 0x81c

Likewise, my new function ‘foo’ gets added to the .text segment, as I can see in the map file generated by the linker:

*(.text*)
.text.foo 0x000008c8 0x8 ./Sources/main_c.o
0x000008c8 foo

But it does not only contain functions, it has constant data as too. If I have a constant table like

1 const int table[] = {5,0,1,5,6,7,9,10};

then this adds to ‘text’ too. That variable ‘table’ will be in FLASH, initialized with the values specified in the source.

Another thing which is included in ‘text’ is the interrupt vector table (more on this later).

In summary: ‘text’ is what ends up typically in FLASH and has code and constant data.

data

‘data’ is used for initialized data. This is best explained with the following (global/extern) variable:

1 int32_t myVar = 0x12345678;

Adding above variable to my application will increase the ‘data’ portion by 4 bytes:

text data bss


0x1414 0x1c 0x81c

This variable ‘myVar’ is not constant, so it will end up in RAM. But the initialization (0x12345678) *is* constant, and can live in
FLASH memory. The initialization of the variable is done during the normal ANSI startup code. The code will assign/copy the
initialization value. This is sometimes named ‘copy-down’. For the startup code used by CodeWarrior for MCU10.3 for Kinetis-L
(ARM Cortex-M0+), this is performed in __copy_rom_sections_to_ram():

https://www.printwhatyoulike.com/print?url=https%3A%2F%2Fmcuoneclipse.com%2F2013%2F04%2F14%2Ftext-data-and-bss-code-and-data-si… 1/4
28/01/2021 PrintWhatYouLike on text, data and bss: Code and Data Size Explained | MCU on Eclipse

— ARM Startup Code Initializing Variables

Just one thing to consider: my variable ‘myVar’ will use space in RAM (4 bytes in my case), *plus* space in FLASH/ROM for the
initialization value (0x12345678). So I need to count the ‘data’ size twice: that size will end up in RAM, plus will occupy
FLASH/ROM. That amount of data in FLASH is *not* counted in the text portion.

The ‘data’ only has the initialization data (in my example 0x12345678. And not the variable (myVar).

bss

The ‘bss’ contains all the uninitalized data.

bss (or .bss, or BSS) is the abbreviation for ‘Block Started by Symbol’ by an old assembler (see this link).

This is best explained with following (global/extern) variable:

1 int32_t myGlobal;

Adding this variable will increase the ‘bss’ portion by 4:

text data bss


0x1414 0x18 0x820

I like to remember ‘bss’ as ‘Better Save Space’ :-). As bss ends up in RAM, and RAM is very valuable for a microcontroller, I
want to keep the amount of variables which end up in the .bss at the absolute minimum.

The bss segment is initialized in the startup code by the zero_fill_bss() function:

1 static void zero_fill_bss(void)


2 {
3 extern char __START_BSS[];
4 extern char __END_BSS[];
5
6 memset(__START_BSS, 0, (__END_BSS - __START_BSS));
7 }

dec

The ‘dec’ (as a decimal number) is the sum of text, data and bss:

dec = text + data + bss

Size – GNU Utility

The size (or printsize) GNU utility has more options:

size [-A|-B|--format=compatibility]
[--help]
[-d|-o|-x|--radix=number]
[--common]
[-t|--totals]
[--target=bfdname] [-V|--version]
[objfile...]

The ‘System V’ option can be set directly in the Eclipse panel:

https://www.printwhatyoulike.com/print?url=https%3A%2F%2Fmcuoneclipse.com%2F2013%2F04%2F14%2Ftext-data-and-bss-code-and-data-si… 2/4
28/01/2021 PrintWhatYouLike on text, data and bss: Code and Data Size Explained | MCU on Eclipse

— GNU Print Size Option in CodeWarrior for MCU10.3

It produces similar information as shown above, but with greater detail.

To illustrate this, I use

1 int table[] = {1,2,3,4,5};

While in ‘Berkeley’ mode I get:

text data bss dec hex filename


0x140c 0x2c 0x81c 7252 1c54 size.elf

I get this in ‘System V’ mode:

section size addr


.interrupts 0xc0 0x0
.text 0x134c 0x800
.data 0x14 0x1ffff000
.bss 0x1c 0x1ffff014
.romp 0x18 0x1ffff030
._user_heap_stack 0x800 0x1ffff048
.ARM.attributes 0x31 0x0
.debug_info 0x2293 0x0
.debug_abbrev 0xe66 0x0
.debug_loc 0x27df 0x0
.debug_aranges 0x318 0x0
.debug_macinfo 0x53bf3 0x0
.debug_line 0x1866 0x0
.debug_str 0xc23 0x0
.comment 0x79 0x0
.debug_frame 0x594 0x0
Total 0x5defe

I’m using an ARM Cortex-M0+ in my example, so addresses greater 0x1ffff000 are in RAM.

The lines from .ARM.attributes up to .debug_frame are not ending up in the target, they are debug and other information.

.interrupts is my interrupt vector table, and .text is my code plus constants, and is in FLASH memory. That makes the
0xc0+0x134c=0x140c for text in ‘Berkeley’.

https://www.printwhatyoulike.com/print?url=https%3A%2F%2Fmcuoneclipse.com%2F2013%2F04%2F14%2Ftext-data-and-bss-code-and-data-si… 3/4
28/01/2021 PrintWhatYouLike on text, data and bss: Code and Data Size Explained | MCU on Eclipse

.bss is my uninitialized (zero-outed) variable area. Additionally there is .user_heap_stack: this is the heap defined in the ANSI
library for malloc() calls. That makes the total of 0x1c+0x800=0x81c shown in ‘Berkeley’ format.

.data is for my initialized ‘table[]’ variable in RAM (5*4 bytes=0x14)

The .romp is used by the linker for the ‘copy-down’ and initialization of .data. But it looks confusing: it is shown with addresses
in RAM? Checking the linker map file shows:

.romp 0x1ffff030 0x18 load address 0x00001b60


0x00001b60 __S_romp = _romp_at
0x1ffff030 0x4 LONG 0x1b4c ___ROM_AT
0x1ffff034 0x4 LONG 0x1ffff000 _sdata
0x1ffff038 0x4 LONG 0x14 ___data_size
0x1ffff03c 0x4 LONG 0x0
0x1ffff040 0x4 LONG 0x0
0x1ffff044 0x4 LONG 0x0

Ah! That actually is not in RAM, but in FLASH: the linker maps this to the FLASH address 0x1b60! So this size 0x18 really
needs to be added to the FLASH size too!

Summary

I hope I have sorted out things in a correct way. The way how the initialized data is reported might be confusing. But with the
right knowledge (and .map file in mind), things get much clearer:

‘text’ is my code, vector table plus constants.

‘data’ is for initialized variables, and it counts for RAM and FLASH. The linker allocates the data in FLASH which then is copied
from ROM to RAM in the startup code.

‘bss’ is for the uninitialized data in RAM which is initialized with zero in the startup code.

Happy Sizing

https://www.printwhatyoulike.com/print?url=https%3A%2F%2Fmcuoneclipse.com%2F2013%2F04%2F14%2Ftext-data-and-bss-code-and-data-si… 4/4

You might also like