(公共部分):代码区,BSS区,数据区.
1.代码区:存放可执行的指令.顺便规划局部变量的相关信息(??).
独有性:一份指令在内存(不管虚拟内存还是实际)中只要有一份就可以的
只读性:汇编指令包含 操作码+操作数;一般操作码是不可变的,但是操作数可以改变.
而且有不同的寻址方式.
立即数 | 数据包含在指令区 |
局部数据 | 运行时在栈中分配,然后在指令中引用地址 |
BSS区,数据区 | 同上在,指令中引用"对象"的地址. |
2静态区:
1.函数外的已初始化全局变量(包括函数外部静态变量).
2.静态变量.
至于static的访问权限问题老生长谈:1.静态变量运行时不会被"释放"2.static限定本文件访问.
3未初始化变量区(BSS Block Started by Symbol)
未初始化的全局变量和静态变量.特点:被系统自动置NULL的指针(引用类型),或者被置0的基本数字类型.
在被加载到内存中执行的时候,以上三段都赋予了不同的特点.
代码段 | 由加载器确定,一般是由OS支持的,如果在OS外,要手动指定加载位置了.试想一下ueft和boot程序的内存位置是没有OS支持的. |
静态区 | 生命周期为程序进入内存到释放整个阶段 |
BSS区 | 同静态区 |
栈 | 局部变量,函数参数值,返回值等等. Note:在堆栈出栈(函数运行结束)时失效,这就是为啥函数内变量不能被作用域外使用 以及 进行(地址引用:野指针的生产大户) 管理者:编译器管理. 特性:线性地址(地址连续,都有唯一前驱后继) |
堆 | 用于动态分配内存.BSS区和栈区之间. 一般由User分配和释放.(Java只由自己分配,释放交JVM) 特性:非线性,可能产生内存碎片. |
这样分配的原因:
1.代码和数据分开,可以在哈弗架构下的CPU更高效.Code-Cache-Bus与Data-Cache-Bus分开并行工作.
2.同上,即使在冯诺依曼结构下,代码执行也是PC自加进行的.如果混编会破坏Code地址的线性特性,降低效率,(定位数组和链表那个更快?)
3.临时变量生命周期短,放在栈中有效提高效率.
4.堆可以使程序更具有灵活性.
配合修饰符
(懒得打字了直接上图)
全局变量,函数在外使用的方法:
1.头文件中定义:可能会产生重复定义(在链接阶段*.o-->elf文件时候).因为头文件在处理的时候是copy到*.c/*.cc/*.cpp文件内的,在编译阶段每个文件(*.o)都会生成一个"该标识符",而且作用域是整个工程.多重定义实例
2.extern定义:extern过程符号表解析