欢迎光临
我们一直在努力

Linux 进程内存模型 (2)

建站超值云服务器,限时71元/月

接下来我们分析不同生存周期变量在进程空间的位置。

int x = 0x1234; // 全局初始化变量
char *s; // 全局未初始化变量

int test()
{
  static int i = 0x4567; // 静态局部变量
  return ++i;
}

int main(int argc, char** argv)
{
  int i = test() + x; // i: 局部变量
  s = “Hello, World!”;

  char* p = (char*)malloc(10); // 动态分配地址

  return 0;
}

在分析 ELF 文件结构时我们就已经知道全局变量和静态局部变量在编译期就决定了其内存地址。

$ readelf -s hello

Symbol 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 hello

There 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)

通过对比相关段,我们可确定全局初始化变量和静态局部变量被分配在 .data 中,而全局非初始化变量则分配在 .bss。可以用反汇编代码验证一下。

$ objdump -dS -M intel hello | less

int x = 0x1234;
char *s;

int test()
{
  … …
    static int i = 0x4567;
    return ++i;
  80484c7: mov eax,ds:0x804a024 ; 静态局部变量 i (对照上面符号表) 地址 0x804a024, .data 段
  80484cc: add eax,0x1
  80484cf: mov ds:0x804a024,eax
  80484d4: mov eax,ds:0x804a024
}
  … …

080484db :

int main(int argc, char** argv)
{
  … …
    int i = test() + x;
  80484e4: call 80484c4
  80484e9: mov edx,DWORD PTR ds:0x804a020 ; 全局初始化变量 x 地址 0x804a020, .data 段
  80484ef: add eax,edx
  80484f1: mov DWORD PTR [esp+0x1c],eax
    s = “Hello, World!”;
  80484f5: mov DWORD PTR ds:0x804a030,0x8048620 ; 全局未初始化变量 s 地址 0x804a030, .bss 段
    ; 字符串 “Hello, World!” 地址 0x8048620, .rodata 段
  … …

接下来我们看看局部变量和 malloc 在堆上分配的情况。

(gdb) p &i ; main() 局部变量 i 地址

$2 = (int *) 0xbffff45c

(gdb) p p ; malloc 返回空间指针 p

$3 = 0x804b008 “”

(gdb) info proc mappings

Mapped 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]

很显然,局部变量 i 分配在 stack (0xBFFEB000 ~ 0xC0000000)。而 p 则是在 Heap (0x804B000 ~ 0x806C000) 上分配。

转自:http://www.rainsts.net/

赞(0)
版权申明:本站文章部分自网络,如有侵权,请联系:west999com@outlook.com 特别注意:本站所有转载文章言论不代表本站观点! 本站所提供的图片等素材,版权归原作者所有,如需使用,请与原作者联系。未经允许不得转载:IDC资讯中心 » Linux 进程内存模型 (2)
分享到: 更多 (0)

评论 抢沙发

  • 昵称 (必填)
  • 邮箱 (必填)
  • 网址