关于Linux进程环境


32位的Linux操作系统使用分页机制为每个进程提供了4G线性地址空间。其中1G空间用于内核,3G空间用于用户空间。

内核开始于0xC0000000,占用0xC0000000以下的IG内存。用户空间开始于0x00000000至0xC0000000,占用3G内存。

关于1G内核运行的机制不在本文的描述之内,本文主要描述3G空间的使用。

进程是从fork系统调用开始的。fork是Linux下生成进程副本的系统调用。执行fork时,内核会根据执行fork的进程(进程A),复制一个与进程A一样的进程B。此时,进程B已经

拥有了4G的线性空间,但进程B用户空间与进程A的用户空间是一样的(进程B为进程A的子进程,进程B为进程A的父进程)。举例说:

int main(int argc,char *argv[])
{
	int pid;
	
	pid=fork()
	if(pid<0)
	{
		printf("fork wrong\n");
	}else if(pid>0)
	{
		printf("child \n");  //子进程将执行
	}else
	{
		printf("father \n"); //父进程将执行
	}
	return 0;
}

程序将有两个输出,是由两个程序分别输出。

一般fork系统调用后,会执行execve(char *filename,char **argv,char **envp)系统调用,将用户的3G的地址空间释放,将filename可执行文件的内容放入3G地址空间,替换地址空间。

exec以后用户进程空间布局已经完成。进程空间大致被分为4个区域,代码段,数据段,堆空间,栈空间。代码段从0x08048000开始,内容为程序的机器指令,eip指向此处,当切换到此处运行时,程序将从eip处开始执行。数据段为程序中的全局变量,静态变量(以C语言为例)。紧接着代码段。内核中存在一个变量brk指向数据段最后一个数据的下一个地址,指明数据段的结束地址。栈空间从0xC0000000开始,向上生长,栈空间底部内容由字符串与字符指针组成,这些值都是从argv和envp处获取。简单用图来表明栈的底部使用情况。

字符串的组成{N个非o字符}+0,字符串可分为命令行参数字符串和环境变量字符串。字符串指针也可分为指向命令行参数字符串的指针和指向环境变量字符串的指针。

环境变量字符串n

环境变量字符串n-1

    |

环境变量字符串0

命令行参数字符串n

命令行参数字符串n-1

    |

命令行参数字符串0

0

环境变量字符指针pn,指向环境变量字符串n

环境变量字符指针pn-1,指向环境变量字符串n-1

|

环境变量字符指针0,指向环境变量字符串0

0

命令行参数字符指针pn,指向命令行参数字符串n

命令行参数字符指针pn-1,指向命令行参数字符串n-1

|

命令行参数字符指针0,指向命令行参数字符串0

命令行参数个数

---->esp指向此处

栈是函数运行的基本条件,函数的返回地址,参数,局部变量都用到栈。 栈空间在程序运行时会向上增减。内核规定了栈的最大长度,大概有8M的空间。在栈(esp)和brk之间产生了大量的空间(空间A),大都在2G以上,这片空间我们称之为堆。我们可以调用brk系统调用开扩展和缩小堆空间。但我们一般都使用malloc和free来获取或释放其中的空间。malloc和free是库函数,基本原理是将空间A看成是一个个连续的块,有的块被使用,有的为空闲,malloc遍历所有的块,找到满足大小的空闲块,free将使用过的块标为空闲。当malloc找不到适合的块,就使用brk系统调用扩展一块区域,来供malloc使用。

进程空间确立后,程序开始执行。但在C语言中我们执行的开始是main函数。main函数的声明是int main(int argc,char **argv,char **envp),也就是执行main的时候其函数返回地址下面是int argc,char **argv,char **envp,这与我们知道的程序开始的栈空间布局不同。所以main函数并非程序开始执行处,Linux编译程序会为每个C程序添加一个启动代码,启动代码执行获取argv,envp值,并放入栈空间,接着调用main函数,并调用exit函数,在main返回后执行。(简单的C的启动程序的实现可以看我的另一篇文章--http://blog.csdn.net/pk_20140716/article/details/45619969)。



评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值