.bss segment
$ vim uninitiailsed_global_variable.c
#include <stdio.h>
int uninitilised_global_variable;
int main(int argc, char **argv) {
return 0;
}
$ gcc -o uninitiailsed_global_variable uninitiailsed_global_variable.c
$ size uninitiailsed_global_variable
text data bss dec hex filename
1017 272 8 1297 511 uninitiailsed_global_variable
.data segment
The .data segment contains any global or static variables which have a pre-defined value and can be modified. That is any variables that are not defined within a function (and thus can be accessed from anywhere) or are defined in a function but are defined as static so they retain their address across subsequent calls.
$ vim initiailsed_global_variable.c
#include <stdio.h>
int initilised_global_variable = 78;
int main(int argc, char **argv) {
printf("address of : initilised_global_variable = %p\n", &initilised_global_variable);
return 0;
}
$ size initiailsed_global_variable
text data bss dec hex filename
1156 280 4 1440 5a0 initiailsed_global_variable
Now lets run this program to check, what is the address assigned to our initiailsed global integer variable as,
$ address of : initilised_global_variable = 0x804a01c
Now, lets check using nm tool what is the predefined address space our program got from the compiler as,
$ nm -s a.out
0804a020 B __bss_start
0804a020 b completed.7200
0804a014 D __data_start
0804a014 W data_start
08048350 t deregister_tm_clones
080483c0 t __do_global_dtors_aux
08049f0c t __do_global_dtors_aux_fini_array_entry
0804a018 D __dso_handle
08049f14 d _DYNAMIC
0804a020 D _edata
0804a024 B _end
080484a4 T _fini
080484b8 R _fp_hw
080483e0 t frame_dummy
08049f08 t __frame_dummy_init_array_entry
080485e4 r __FRAME_END__
0804a000 d _GLOBAL_OFFSET_TABLE_
w __gmon_start__
080484f0 r __GNU_EH_FRAME_HDR
080482ac T _init
08049f0c t __init_array_end
08049f08 t __init_array_start
0804a01c D initilised_global_variable
080484bc R _IO_stdin_used
w _ITM_deregisterTMCloneTable
w _ITM_registerTMCloneTable
08049f10 d __JCR_END__
08049f10 d __JCR_LIST__
w _Jv_RegisterClasses
080484a0 T __libc_csu_fini
08048440 T __libc_csu_init
U __libc_start_main@@GLIBC_2.0
0804840b T main
U printf@@GLIBC_2.0
08048380 t register_tm_clones
08048310 T _start
0804a020 D __TMC_END__
08048340 T __x86.get_pc_thunk.bx
output of nm shows that we got the address for “int initilised_global_variable” i.e. 0x804a01c which is predefined as seen in “nm -s” in bold ( just before _IO_stdin_used in above nm output ) and after data segment address has started at “0804a014 D __data_start”
$ vim local_initialised_and_uninitialised_variable.c
#include <stdio.h>
int main(int argc, char **argv) {
int local_initialised_variable = 78;
int local_variable;
return 0;
}
$ gcc -o local_initialised_and_uninitialised_variable local_initialised_and_uninitialised_variable.c
$ size local_initialised_and_uninitialised_variable
text data bss dec hex filename
1017 272 4 1293 50d local_initialised_and_uninitialised_variable
.stack segment
$ vim variables_in_stack.c
#include <execinfo.h>
#include <stdio.h>
#include <stdlib.h>
//check cat /proc/pid/maps to know address printed belogs to stack
int main(int argc, char **argv) {
int local_initialised_variable = 78;
int local_uninitialised_variable;
printf("Address of : local_initialised_variable = %p\n", &local_initialised_variable);
printf("Address of : local_uninitialised_variable = %p\n", &local_uninitialised_variable);
//create a infinite loop so we can check address mapped in /proc
while(1); //this is just to identify where we got the address mapped
return 0;
}
$ gcc -o variables_in_stack variables_in_stack.c
$ ./variables_in_stack
Address of : local_initialised_variable = 0xbf961c34
Address of : local_uninitialised_variable = 0xbf961c38
Now, lets identify from proc map of a process we created just now to identify which area the addresses we printed belongs to,
know the process Id as program running above from another terminal as,
$ ps -ax | grep variables_in_stack
6971 pts/9 R+ 1:37 ./variables_in_stack
We can see, we have got 6971 as process Id, now lets check the process map from proc file system as,
$ cd /proc/6971/
$ ls
$ sudo cat maps
08048000-08049000 r-xp 00000000 08:06 13894234 variables_in_stack
08049000-0804a000 r--p 00000000 08:06 13894234 variables_in_stack
0804a000-0804b000 rw-p 00001000 08:06 13894234 variables_in_stack
09859000-0987a000 rw-p 00000000 00:00 0 [heap]
b7539000-b76e9000 r-xp 00000000 08:06 18879084 /lib/i386-linux-gnu/libc-2.23.so
b76e9000-b76eb000 r--p 001af000 08:06 18879084 /lib/i386-linux-gnu/libc-2.23.so
b76eb000-b76ec000 rw-p 001b1000 08:06 18879084 /lib/i386-linux-gnu/libc-2.23.so
b76ec000-b76ef000 rw-p 00000000 00:00 0
b771b000-b771d000 rw-p 00000000 00:00 0
b771d000-b771f000 r--p 00000000 00:00 0 [vvar]
b771f000-b7720000 r-xp 00000000 00:00 0 [vdso]
b7720000-b7742000 r-xp 00000000 08:06 18874426 /lib/i386-linux-gnu/ld-2.23.so
b7742000-b7743000 rw-p 00000000 00:00 0
b7743000-b7744000 r--p 00022000 08:06 18874426 /lib/i386-linux-gnu/ld-2.23.so
b7744000-b7745000 rw-p 00023000 08:06 18874426 /lib/i386-linux-gnu/ld-2.23.so
bf942000-bf963000 rw-p 00000000 00:00 0 [stack]
As we can see above, the address printed by our program are 0xbf961c34 and 0xbf961c38 and the stack memory allocated for this program ranges from bf942000 to bf963000 . Which shows that the local variables resides in the stack memory of a program.
Heap Memory allocation
$ vim memory_allocated_in_heap.c
#include <execinfo.h>
#include <stdio.h>
#include <stdlib.h>
int main(int argc, char **argv) {
int *memory = malloc(sizeof(int));
printf("Address of : int memory allocated = %p\n", memory);
while(1);
return 0;
}