这是本人在做本实验时了解的前置知识,有不对或者不清晰的内容希望能在评论区提出,会认真改正和学习。
目录
Memory Layout
^_^
概述
在这张图中,介绍了内存的存储结构,分别是:
- stack:栈
- heap:堆
- BSS Segment:Block Started by Symbol
- Data Segment:数据段
- Text Segment:代码段
从代码中学习
...
// data stored in Data Segment
int x = 100;
int main(){
// data stored on stack (Local Variable)
int a=2;
float b = 2.5;
// data stored in BSS Segment
static y;
//allocate memory on heap
int *ptr = (int*)malloc(2*sizeof(int));
// value 5 and 6 stored on heap
ptr[0]=5;
ptr[1]=6;
// deallocate memory on heap
free(ptr);
return 1;
}
- stack 栈中存储的是局部变量(不包括static变量)
- 可读可写
- 存储代码中的局部变量
- 栈的生存期取决于代码块,代码块运行就会分配空间但代码块结束就会自动收回空间。
- heap 堆
- 可读可写
- 存储程序运行期间动态分配的空间,一般为malloc/realloc函数
- 堆从分配一直存在,一直到执行free函数释放。进程创建就存在,进程死亡就消失
- BSS Segment
- 可读可写
- 存储未被初始化的全局变量或者static变量
- 未被初始化的值会存储到这里,并且会有默认值为0。因为操作系统在其中放入了0,OS并不想让未初始化的值获取一个随机的值。
- 进程创建就存在,进程死亡就消失
- Data Segment
- 可读可写
- 存储未被初始化的全局变量或者static变量
- 进程创建就存在,进程死亡就消失
- Text Segment
- 用于存放指令,运行代码的一块内存空间
- 空间大小一般在运行之前就已经确定
- 在这其中可能包含一些只读的常数变量,比如字符串常量。
在上述代码中,已经有了详细的注释每个数据存储到了哪里。但是仍有几点要说明一下。
- 首先,虽然在堆中分配了动态存储空间,但是ptr仍然是局部变量,所以应该放在stack中。
- Data Segment和BSS Segment中存储的变量主要区别就是是否初始化。
- 全局变量存储在
全局数据区
Virtual Address & Physical Address
^_^
由于本人操作系统学的不是很好,所以这里只能简单说一下实验可能会涉及到的知识。后续我会多了解这方面的内容放在博客上。
我们知道,物理地址(Physical Address)是unique的,基于你的物理存储器RAM。
如果一个process在使用一部分,另一个人在同一时间就不可以使用,否则会产生矛盾。
但当讨论process中的内存地址时,就会涉及到Virtual Address,虚拟地址。
每一个Process都有一个自己专属的Virtual Addrss,比如如图中V1、V2的空间大小均为0~4G,它们都可以存在这样一个地址0x5000。虚拟地址和物理地址之间存在一个映射机制,来把虚拟地址映射到物理地址中,这个过程由OS完成。
尽管他们使用了相同的虚拟地址,但是映射到了不同的物理地址。
具体的细节我会在后续学习中继续了解,并且整理到博客中。
这时就存在一个问题,如果V1中的一块虚拟地址在映射不能找到物理地址,这个就成为valid address
,如果有指令想要从这里获取数据,程序可能会crash掉,必须能映射到物理地址才能访问这一块虚拟地址。