进程映像学习
转自:https://www.yiibai.com/ipc/ipc_process_image.html
https://blog.csdn.net/u010191034/article/details/39108635
1.介绍
进程映像是执行程序时所需的可执行文件。(它和PCB有所区分,PCB更像是一个数据结构来保存程序的运行时信息。)
它从低地址到高地址包含以下:
- 代码段或文本段
- 数据段
- 堆段
- 栈段
进程地址空间,即进程映像,或者进程的内存映像
2.展开
2.1 文本段或代码段TEXT
固定长度,保存程序,由可执行指令组成的目标文件或程序虚拟地址空间的一部分。通常属于只读。
2.2 数据段DATA
用来存放程序中已初始化的全局/静态变量的一块内存区域。数据段属于静态内存分配。
//但我还有一个问题,就是如果是函数中的static,那应该是等到运行函数时才创建了static,并且生成周期会一直存在,那它会被存储在哪个区域?
//下面做了一个实验,如果初始化的话会被放在data区,未初始化会被放在bss区,逻辑是一样的。
2.3 BSS段
BSS是英文Block Started by Symbol(符号启动的块)的简称。用来存放程序中未初始化的全局变量的一块内存区域。
2.4 堆HEAP
用于存放进程运行中被动态分配的内存段,它的大小并不固定,可动态扩张或缩减。由低地址向高地址增长。
通过malloc或free来申请或释放。
2.5 栈段STACK
是用户存放程序临时创建的局部变量,也就是说我们函数括弧“{}”中定义的变量。由高地址向低地址增长。
在函数被调用时,其参数也会被压入发起调用的进程栈中,并且待到调用结束后,函数的返回值也会被存放回栈中。
3.例子
//segment_size1.c //无其他变量 #include<stdio.h> int main() { printf("Hello World\n"); return 0; } //segment_size2.c //包含一个未初始化的静态变量 #include<stdio.h> int main() { static int a; printf("Hello World\n"); return 0; } //segment_size3.c //包含一个未初始化的和一个初始化的静态变量 #include<stdio.h> int main() { static int a; static int b=5; printf("Hello World\n"); return 0; } //segment_size4.c //包含一个未初始化的、一个初始化的静态变量,一个初始化的全局变量 #include<stdio.h> int c=100; int main() { static int a; static int b=5; printf("Hello World\n"); return 0; } //funcs.c //在4的基础上又添加了一个函数内部的局部静态变量 #include<stdio.h> int c=100; void fun(){//没有调用到这个函数 static int d=100; } int main() { static int a; static int b=5; printf("Hello World\n"); return 0; }
结果:
size segment_size1 segment_size2 segment_size3 segment_size4 funcs text data bss dec hex filename 1514 600 8 2122 84a segment_size1 //不包含变量 1514 600 8 2122 84a segment_size2 //一个未初始化的静态变量(应该是bss+4的) 1514 604 12 2130 852 segment_size3 //一个初始化、一个未初始化(data和bss分别+4) 1514 608 8 2130 852 segment_size4 //多加一个初始化全局(data+4) 1554 612 12 2178 882 funcs //放在了初始化的data区!