Next, we will analyze the location of different lifecycle variables in the process space.
Int x = 0x1234; // global initialization variable
Char * s; // global uninitialized variable
Int test ()
{
Static int I = 0x4567; // static local variable
Return ++ I;
}
Int main (int argc, char ** argv)
{
Int I = test () + x; // I: local variable
S = "Hello, World! ";
Char * p = (char *) malloc (10); // Dynamic Address Allocation
Return 0;
}
When analyzing the ELF File structure, we know that the global variables and static local variables determine the memory address during the compilation period.
$Readelf-s helloSymbol table '. symtab' contains 84 entries:
Num: Value Size Type Bind Vis Ndx Name
......
50: 0804a024 4 object local default 24 I .2347
57: 0804a030 4 object global default 25 s
65: 0804a020 4 object global default 24 x
$Readelf-S helloThere are 38 section headers, starting at offset 0x1a10:
Section Headers:
[Nr] Name Type Addr Off Size ES Flg Lk Inf Al
......
[16]. rodata PROGBITS 08048618 000618 000030 00 A 0 0 4
[24]. data PROGBITS 0804a018 001018 000010 00 WA 0 0 4
[25]. bss NOBITS 0804a028 001028 00000c 00 WA 0 0 4
Key to Flags:
W (write), A (alloc), X (execute), M (merge), S (strings)
I (info), L (link order), G (group), x (unknown)
O (extra OS processing required) o (OS specific), p (processor specific)
By comparing the related segments, we can determine that the global initialization variables and static local variables are allocated in. data, while the Global Non-initialization variables are allocated in. bss. You can use the disassembly code to verify it.
$Objdump-dS-M intel hello | lessInt x = 0x1234;
Char * s;
Int test ()
{
......
Static int I = 0x4567;
Return ++ I;
80484c7: mov eax, ds: 0x804a024; static local variable I (compare with the above symbol table) Address 0x804a024,. data Segment
80484cc: add eax, 0x1
80484cf: mov ds: 0x804a024, eax
80484d4: mov eax, ds: 0x804a024
}
......
080484db <main>:
Int main (int argc, char ** argv)
{
......
Int I = test () + x;
80484e4: call 80484c4 <test>
80484e9: mov edx, dword ptr ds: 0x804a020; global initialization variable x address 0x804a020,. data Segment
80484ef: add eax, edx
80484f1: mov dword ptr [esp + 0x1c], eax
S = "Hello, World! ";
80484f5: mov dword ptr ds: 0x804a030, 0x8048620; Global uninitialized variable s address 0x804a030,. bss segment
; String "Hello, World! "Address 0x8048620,. rodata segment
......
Next, let's look at the allocation of local variables and malloc on the stack.
(Gdb)P & I; Main () local variable I address $2 = (int *) 0xbff45c
(Gdb)P; Malloc returns the space pointer p $3 = 0x804b008 ""
(Gdb)Info proc mappingsMapped address spaces:
Start Addr End Addr Size Offset objfile
0x804b000 0x806c000 0x21000 0 [heap]
0xb7fef000 0xb7ff0000 0x1000 0
0xb7ffe000 0xb8000000 0x2000 0
0xbffeb000 0xc0000000 0x15000 0 [stack]
Obviously, the local variable I is allocated to the stack (0xBFFEB000 ~ 0xC0000000 ). P is in Heap (0x804B000 ~ 0x806C000.