内存一共4个区 
1.任何在函数内部声明的非static变量,其变量地址本身在栈区。栈是向低地址扩展的数据结构,即栈顶的地址和栈的最大容量是系统预先规定好的。
2.任何全局变量或者静态局部变量,其变量地址本身在全局区
3.任何指针变量 如果用malloc,relloc,calloc,或者c++中的new ,指针指向的内存在堆区。堆是向高地址扩展的
4.代码、字符常量在代码区

其中.bss段和.data段为全局区,.bss段存储还未初始化的全局变量,.data段则存储已初始化的全局变量,.text段是代码区。

例1:
char  sz[] = "string";  这条语句,该语句是按照数组的形式来一个个存放的,编译器将其解释为
char   sz[] = {'s','t','r','i','n','g','/0'}; 如果在函数内部出现的话,这几个字符将存放在堆栈中,所以不是字符串常量。
char *psz = "string"; 这条语句,该语句定义了一个指向"string"字符串的指针,并没有空间存放"string"字符串,显然把“string”当做字符串常量并存放在常量区是最合适的选择。并且语句 psz[4] = 'x'; 在编译时不会报错,执行时会产生异常,原因是“string”存放在只读存储区,不可以修改。这和C++中 const char *psz = "string";一句是一样的,所以最好显示的加上const关键字从而让编译器检测出“修改常量“错误。
函数中行参为数组时应怎么看待?
如:void  foo(char sz[100], int ival[10]);
答案是将其理解为指针的形式:
void  foo(char *sz, int *ival);
例2:
int a = ;   //全局区

int main()

{

    char *b = "Hello!~~";   //指针指向代码区,b变量本身也在栈区

    int c = ;   //栈区

    int *d = (int*)malloc( sizeof(int) ); //指针指向堆区,d变量本身同样在栈区

    *d = ;

    static char e = ;   //全局区

    static int (*f)() = main;  //指向代码区,f本身在全局区    

    return ;

}

例3:函数递归是通过栈来实现的,栈中是函数返回地址

procedure A1(…);  procedure A2(…);  procedure A3(…);
   begin         begin         begin
      ┇          ┇        ┇
    r:A2(…);      t:A3(…);     end;
    r1:┇         t1: ┇
   end;         end;

 
 
 

top→

 
 

r1

top→
 

 
t1
r1

top→

 
 
r1
 
 
 

top→
 

 
调用A2前
   
调用A2后
   
调用A3后
   
返回A2后

top→
 

 
返回A1后

具体地,当调用(call)一个函数时,主调函数将声明中的参数表以逆序压栈,然后将当前的代码执行指针(eip)压栈,跳转到被调函数的入口点。

VarType Func (Arg1, Arg2, Arg3, ... ArgN)
{
VarType Var1, Var2, Var3, ...VarN;
//...
return VarN;
}

假设sizeof(VarType) = 4(DWORD), 则一次函数调用汇编代码示例为:

调用方代码:

push ArgN ; 依次逆序压入调用参数
push ... 
push Arg1 
call Func_Address ; 压入当前EIP后跳转(EIP:指令寄存器,extended instruction pointer,指向下一条等待执行的指令地址)

跳转至被调方代码:

push ebp ; 备份调用方EBP指针(EBP:基址指针,base pointer,指向系统栈最上面一个栈帧的底部)
mov ebp, esp ; 建立被调方栈底(ESP:堆栈指针,stack pointer,指向系统栈最上面一个栈帧的栈顶)
sub esp, N * 4; 为局部变量分配空间(栈是从高地址向低地址拓展,即栈顶在低地址处)

内存低地址 | ESP - - - - - - - - - - - - - - - - EBP - - - - - - - - - - - - - - - - - - - - - >| 内存高地址

mov dword ptr[esp - 4 * 1 ], 0 ; 初始化各个局部变量 = 0 这里假定VarType不是类 
mov dword ptr[esp - 4 * ... ], 0
mov dword ptr[esp - 4 * N ], 0
. . . . . . ; 这里执行一些函数功能语句(比如将第N个参数[ebp + N * 4]存入局部变量), 功能完成后将函数返回值存至eax
add esp, N * 4 ; 销毁局部变量
mov esp, ebp ; 恢复主调方栈顶
pop ebp ; 恢复主调方栈底
ret ; 弹出EIP 返回主调方代码

接上面调用方代码: 
add esp, N * 4 ; 释放参数空间, 恢复调用前的栈 
mov dword ptr[ebp - 4], eax ; 将返回值保存进调用方的某个VarType型局部变量

(eax:4个字节;AX:eax的低2个字节;AH:AX的高字节;AL:AX的低字节)

C++内存的分区的更多相关文章

  1. Linux安装时内存如何分区的相关问题

    Linux系统安装时内存如何分区:Linux系统必须的分区是根分区(/)和swap交换分区.普通用户一般分三个区,一个根分区(/),一个家目录(home分区),一个交换分区(swap分区),以80G的 ...

  2. C语言程序内存的分区

    本文转载自:https://blog.csdn.net/shulianghan/article/details/20472269 C语言程序内存分配 (1) 内存分区状况 栈区 (stack) :  ...

  3. jvm的内存空间分区

    在方法(代码块)中定义一个变量时,java就在栈中为这个变量分配JVM内存空间,当超过变量的作用域后,java会自动释放掉为该变量所分配的JVM内存空间:而在堆中分配的JVM内存由java虚拟机的自动 ...

  4. C++学习(5)—— 内存的分区模型

    C++程序在执行时,将内存大方向划分为4个区域 代码区:存放函数体的二进制代码,由操作系统进行管理的 全局区:存放全局变量和静态变量以及常量 栈区:由编译器自动分配释放,存放函数的参数值.局部变量等 ...

  5. C/C++内存几大分区和存储空间的布局

    先看一下可执行文件加载进内存后形成的进程在内存中的结构,如下图: 代码区:存放CPU执行的机器指令,代码区是可共享,并且是只读的. 数据区:存放已初始化的全局变量.静态变量(全局和局部).常量数据. ...

  6. [内存管理]linux内存管理 之 内存节点和内存分区

    Linux支持多种硬件体系结构,因此Linux必须采用通用的方法来描述内存,以方便对内存进行管理.为此,Linux有了内存节点.内存区.页框的概念,这些概念也是一目了然的. 内存节点:主要依据CPU访 ...

  7. Eenterprise linux服务器分区

    分区说明: (在MBR格式的硬盘下我会分/ /boot swap /data 四个分区,不建议在服务器上面使用LVM,中大型企业的IDC都是有存储区域的,专门管理硬盘容量的.)(分区的时候,请注意顺序 ...

  8. C 内存管理初步了解

    1 首先变量了解几个概念 静态变量:用 static 修饰的变量 局部变量: 存储在栈区:作用域是函数块内:生存期是直到函数块结束 全局变量:存储在静态区:作用域是从定义到本源程序结束,生存期是运行期 ...

  9. C语言知识整理(3):内存管理(详细版)

    在计算机系统,特别是嵌入式系统中,内存资源是非常有限的.尤其对于移动端开发者来说,硬件资源的限制使得其在程序设计中首要考虑的问题就是如何有效地管理内存资源.本文是作者在学习C语言内存管理的过程中做的一 ...

随机推荐

  1. CF1051F The Shortest Statement Dijkstra + 性质分析

    动态询问连通图任意两点间最短路,单次询问. 显然,肯定有一些巧妙地性质(不然你就发明了新的最短路算法了233)有一点很奇怪:边数最多只比点数多 $20$ 个,那么就可以将这个图看作是一个生成树,上面连 ...

  2. 【CF1249F】Maximum Weight Subset(贪心)

    题意:给定一棵n个点带点权的树,要求从中选出一个点集,使得这些点两两之间距离都大于K,求最大点权和 n,K<=2e2,1<=a[i]<=1e5 思路:树形DP显然可做,极限是n方,然 ...

  3. Essential Java.《Java 编程要点》

    Essential Java.<Java 编程要点> Essential Java, is a book about the Essentials of Java Programming. ...

  4. [CSP-S模拟测试]:f(Trie树+二分答案+meet in middle+two pointers)

    题目传送门(内部题67) 输入格式 第一行,三个整数$n$.$k$.$p$.第二行,$n$个自然数,表示$\{a_i\}$. 输出格式 输出一行,两个自然数,表示$f(res)$.$res$. 样例 ...

  5. angular项目开发

    第 1 步:安装 Angular CLI 你可以使用 Angular CLI 来创建项目.生成应用和库代码,以及执行各种持续开发任务,比如测试.打包和部署. 全局安装 Angular CLI. 要使用 ...

  6. Web开发系列【1】实用的网页布局(PC端)

    在熟悉那些常用的软件.工具后,我们正式开始开发,在前期准备工作之后,我们要做的事情是写页面,也就是网页布局.在w3c.菜鸟.慕课网等等网站上都有基础的 HTML+CSS 知识讲解,在初期学习中,跟着教 ...

  7. k8s上的基础概念和术语

    kubernetes基本概念和术语   kubeernetes中的大部分概念如Node,Pod,Replication Controller ,Serverce等都可以看作一种“资源对象”,几乎所有的 ...

  8. navigation ObtacleCostFunction源码分析

    ObtacleCostFunction 定义了一个ObstacleCostFunction类,继承自Trajectory类,Trajectory类有8个类参 总共有8个类参 double xv_,yv ...

  9. Gradel 多渠道打包 代码混淆

    http://blog.csdn.net/ttccaaa/article/details/47687241 http://www.bubuko.com/infodetail-987756.html h ...

  10. Exchanger 源码分析

    Exchanger 此类提供对外的操作是同步的: 用于成对出现的线程之间交换数据[主场景]: 可以视作双向的同步队列: 可应用于基因算法.流水线设计.数据校对等场景 创建实例 /** * arena ...