CTOCIO IT专家网

天极传媒 比特网 | 天极网 | IT专家网 | IT商网 | 52PK游戏网 | 手机天极 | IT分众 |
IT专家网搜索

您现在的位置: IT专家网 > WinSystem子站 > 技巧

windows进程中的内存结构

作者: ,  出处:Internet, 责任编辑: 绍龙, 
2007-03-05 15:43
  接触过编程的人都知道,高级语言都能通过变量名来访问内存中的数据。那么这些变量在内存中是如何存放的呢?程序又是如何使用这些变量的呢?下面就会对此进行深入的讨论。下文中的C语言代码如没有特别声明,默认都使用VC编译的release版。

  接触过编程的人都知道,高级语言都能通过变量名来访问内存中的数据。那么这些变量在内存中是如何存放的呢?程序又是如何使用这些变量的呢?下面就会对此进行深入的讨论。下文中的C语言代码如没有特别声明,默认都使用VC编译的release版。

  首先,来了解一下 C 语言的变量是如何在内存分部的。C 语言有全局变量(Global)、本地变量(Local),静态变量(Static)、寄存器变量(Regeister)。每种变量都有不同的分配方式。先来看下面这段代码:

  #include

  int g1=0, g2=0, g3=0;

  int main()

  {

  static int s1=0, s2=0, s3=0;

  int v1=0, v2=0, v3=0;

  //打印出各个变量的内存地址

  printf("0x%08x\n",&v1); //打印各本地变量的内存地址

  printf("0x%08x\n",&v2);

  printf("0x%08x\n\n",&v3);

  printf("0x%08x\n",&g1); //打印各全局变量的内存地址

  printf("0x%08x\n",&g2);

  printf("0x%08x\n\n",&g3);

  printf("0x%08x\n",&s1); //打印各静态变量的内存地址

  printf("0x%08x\n",&s2);

  printf("0x%08x\n\n",&s3);

  return 0;

  }

  编译后的执行结果是:

  0x0012ff78

  0x0012ff7c

  0x0012ff80

  0x004068d0

  0x004068d4

  0x004068d8

  0x004068dc

  0x004068e0

  0x004068e4

  输出的结果就是变量的内存地址。其中v1,v2,v3是本地变量,g1,g2,g3是全局变量,s1,s2,s3是静态变量。你可以看到这些变量在内存是连续分布的,但是本地变量和全局变量分配的内存地址差了十万八千里,而全局变量和静态变量分配的内存是连续的。这是因为本地变量和全局/静态变量是分配在不同类型的内存区域中的结果。对于一个进程的内存空间而言,可以在逻辑上分成3个部份:代码区,静态数据区和动态数据区。动态数据区一般就是“堆栈”。“栈(stack)”和“堆(heap)”是两种不同的动态数据区,栈是一种线性结构,堆是一种链式结构。进程的每个线程都有私有的“栈”,所以每个线程虽然代码一样,但本地变量的数据都是互不干扰。一个堆栈可以通过“基地址”和“栈顶”地址来描述。全局变量和静态变量分配在静态数据区,本地变量分配在动态数据区,即堆栈中。程序通过堆栈的基地址和偏移量来访问本地变量。

  ├———————┤低端内存区域

  │ …… │

  ├———————┤

  │ 动态数据区 │

  ├———————┤

  │ …… │

  ├———————┤

  │ 代码区 │

  ├———————┤

  │ 静态数据区 │

  ├———————┤

  │ …… │

  ├———————┤高端内存区域

  堆栈是一个先进后出的数据结构,栈顶地址总是小于等于栈的基地址。我们可以先了解一下函数调用的过程,以便对堆栈在程序中的作用有更深入的了解。不同的语言有不同的函数调用规定,这些因素有参数的压入规则和堆栈的平衡。windows API的调用规则和ANSI C的函数调用规则是不一样的,前者由被调函数调整堆栈,后者由调用者调整堆栈。两者通过“__stdcall”和“__cdecl”前缀区分。先看下面这段代码:

  #include

  void __stdcall func(int param1,int param2,int param3)

  {

  int var1=param1;

  int var2=param2;

  int var3=param3;

  printf("0x%08x\n",¶m1); //打印出各个变量的内存地址

  printf("0x%08x\n",¶m2);

  printf("0x%08x\n\n",¶m3);

  printf("0x%08x\n",&var1);

  printf("0x%08x\n",&var2);

  printf("0x%08x\n\n",&var3);

  return;

  }

  int main()

  {

  func(1,2,3);

  return 0;

  }

共2页。 1 2 :

网友评论

笔名 
请您注意:遵守国家有关法律、法规,尊重网上道德,承担一切因您的行为而直接或间接引起的法律责任。    IT专家网友拥有管理笔名和留言的一切权利。
  • 周排行榜
  • 月排行榜

邮件订阅

天极服务 | 关于我们 | 网站律师 | 加入我们 | 联系我们 | 广告业务 | 友情链接 | 我要挑错
All Rights Reserved, Copyright 2004-2008, Ctocio.com.cn
渝ICP证B2-20030003号 如有意见请与我们联系 powered by 天极内容管理平台CMS4i