linux堆栈

进 程(执行的程序)会占用一定数量的内存,它或是用来存放从磁盘载入的程序代码,或是存放取自用户输入的数据等等。不过进程对这些内存的管理方式因内存用途 不一而不尽相同,有些内存是事先静态分配和统一回收的,而有些却是按需要动态分配和回收的。对任何一个普通进程来讲,它都会涉及到5种不同的数据段。

一、Linux进程的五个段

下面我们来简单归纳一下进程对应的内存空间中所包含的5种不同的数据区都是干什么的。

1)代码段:代码段是用来存放可执行文件的操作指令,也就是说是它是可执行程序在内存中的镜像。代码段需要防止在运行时被非法修改,所以只准许读取操作,而不允许写入(修改)操作——它是不可写的。

2)数据段:数据段用来存放可执行文件中已初始化全局变量,换句话说就是存放程序静态分配的变量和全局变量。

3)BSS段:BSS段包含了程序中未初始化的全局变量,在内存中 bss段全部置零。

4)堆(heap):堆是用于存放进程运行中被动态分配的内存段,它的大小并不固定,可动态扩张或缩减。当进程调用malloc等函数分配内存时,新分配的内存就被动态添加到堆上(堆被扩张);当利用free等函数释放内存时,被释放的内存从堆中被剔除(堆被缩减)

它的物理内存空间是由程序申请的,并由程序负责释放。

5)栈:栈是用户存放程序临时创建的局部变量,也就是说我们函数括弧“{}”中定义的变量(但不包括static声明的变量,static意味着在数据段中存放变量)。除此以外,在函数被调用时,其参数也会被压入发起调用的进程栈中,并且待到调用结束后,函数的返回值也会被存放回栈中。由于栈的先进先出特点,所以栈特别方便用来保存/恢复调用现场。从这个意义上讲,我们可以把堆栈看成一个寄存、交换临时数据的内存区。

它是由操作系统分配的,内存的申请与回收都由OS管理。

举个具体的C语言的例子吧:

//main.c

int a = 0; //全局初始化区

char *p1; //全局未初始化区

main()

{

static int c =0; //全局(静态)初始化区

int b; //栈

char s[] = "abc"; //栈

char *p2; //栈

char *p3 = "123456"; //"123456\0"在常量区,p3在栈上。

p1 = (char *)malloc(10);

p2 = (char *)malloc(20); //分配得来得10和20字节的区域就在堆区。

}

二、各个段在内存中的组织

各个段段在线性空间中的组织。直接上图:

+--------------------------------   高地址

+ envstrings 环境变量字串

+--------------------------------

+ argv string 命令行字串

+--------------------------------

 

+ env pointers 环境变量指针表

+--------------------------------

+ argv pointers命令行参数指针表

+--------------------------------

+ argc 命令行参数个数

+--------------------------------

 

+     main函数的栈帧

+--------------------------------

+     被调用函数的栈帧

+--------------------------------

+         ......

+--------------------------------

+       堆(heap)

+--------------------------------

+ BSS 未初始化全局数据

+--------------------------------

+   Data 初始化的全局数据

+--------------------------------

 

+   Text 代码段

+--------------------------------

其中,Heap,BSS,Data这三个段在物理内存中是连续存放的,可以这么理解:这三个是一体的。Text、Stack是独立存放的,这是现在Linux中个段的分布,在0.11中代码段和数据段不是分立的,是在一起的也就是说数据段和代码段是一个段,当然了,堆与BSS也与它们一起了。从0.11的task_struct中还可以看出数据段、堆栈段的描述符是一个,都在ldt[2]处。

时间: 2024-11-09 22:18:45

linux堆栈的相关文章

LINUX - 堆栈

堆栈模型: 函数调用: EBP:ESP EBP当前调用函数的栈底: ESP当前调用函数的栈顶: 参考及图: https://blog.csdn.net/hoi0714/article/details/7658100 原文地址:https://www.cnblogs.com/wangqiwen-jer/p/11294304.html

linux内核学习资料链接

1. 内核学习方法,编译.调试等常见问题1.1 关于编译升级内核到2.6.0的一些问题 作者:ommm        http://linux.chinaunix.net/bbs/thread-281831-1-5.html 1.2 VMWare Workstation 6.0调试Linux Kernel,竟如此方便 作者:albcamus        http://linux.chinaunix.net/bbs/thread-896214-1-5.html 1.3 基于S3C2410的Lin

Linux栈搜索算法优化随想

Linux网络协议栈可以准确但仍进行说明,不用说,Netfilter.简单地说,TC够了,但有几个硬伤,本文不构成一个完整的记录,如果是随笔,不可当真. 0.发现物种 Linux堆栈作为一个纯软件实现,保留的硬件接口,但文章并不涉及硬件. 在Linux的协议栈实现中,由于没有硬件电路的固化,查找算法是难免的.比方路由查找,邻居查找.conntrack查找,socket查找,不一而足.其实.协议栈作为一个公共组织,为全部的数据包服务,假设一个数据包到达协议栈.处理逻辑必须帮它找到和它相关的数据结构

面向物联网的几大开源操作系统

在过去的十年间,大多数新型开源操作系统已从移动市场转向物联网市场.本文介绍了面向物联网的许多新型开源操作系统.我们之前的文章介绍了开源物联网框架,以及面向物联网和消费者智能家居设备的Linux和开源开发硬件. 除了介绍面向物联网的新型嵌入式Linux发行版外,我还介绍了OpenWrt等几款比较老的轻量级发行版,它们在这个领域迎来了新生.虽然Linux发行版主要针对网关和集线器,但是面向物联网的非Linux开源操作系统取得了同样迅猛的发展,它们可以在微控制器单元(MCU)上运行,通常面向物联网边缘

常用的面向物联网的开源操作系统有哪些?

本文主要为大家介绍了面向物联网的许多新型开源操作系统,希望可以帮助大家更好的选择相应系统进行开发. 虽然Linux发行版主要针对网关和集线器,但是面向物联网的非Linux开源操作系统取得了同样迅猛的发展,它们可以在微控制器单元(MCU)上运行,通常面向物联网边缘设备. 请记住一点:如今几乎所有的操作系统都声称有一些物联网连接功能,所以本文这份名单有点随意.本文介绍的开源操作系统大多数符合下列属性:占用内存少.电源效率高.模块化可配置通信堆栈,对特定的无线和传感器技术提供强有力的支持.一些项目注重

工作碰上的技术问题及处理经验(二)

续上一篇随笔: https://www.cnblogs.com/kingstarer/p/8469016.html <工作碰上的技术问题及处理经验> 由于内容有很多空格,如果直接在正文粘贴,发表后空格会消失,导致版本看起来比较难看. 所以我把主要内容做为代码发表. 我觉得每天把工作碰上的问题做一个简单的笔记挺不错的,一来可以锻炼自己的表达能力,二来也方便自己以后复查,因为以后工作很可能再碰上同样的问题. 由于我每次记录笔记时,可能只是记录了关键字,而要发出来做为共享随笔,只有这些关键字肯定是不

在linux代码中打印函数调用的堆栈的方法

之前一直有这样的需求,当时问到,也没搜到方法,现在竟然既问到了,也搜到了,哎,世事真是不能强求啊! 在Linux内核调试中,经常用到的打印函数调用堆栈的方法非常简单,只需在需要查看堆栈的函数中加入: dump_stack();或 __backtrace();即可. dump_stack()在~/kernel/ lib/Dump_stack.c中定义 void dump_stack(void){ printk(KERN_NOTICE  "This architecture does not imp

在Linux与Windows上获取当前堆栈信息

在编写稳定可靠的软件服务时经常用到输出堆栈信息,以便用户/开发者获取准确的运行信息.常用在日志输出,错误报告,异常检测. 在Linux有比较简便的函数获取堆栈信息: #include <stdio.h> #include <execinfo.h> #include <signal.h> #include <stdlib.h> #include <unistd.h> void handler(int sig) { void *array[5]; s

从汇编角度来理解linux下多层函数调用堆栈执行状态

注:在linux下开发经常使用的辅助小工具: readelf .hexdump.od.objdump.nm.telnet.nc 等,详细能够man一下. 我们用以下的C代码来研究函数调用的过程. C++ Code 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 int bar(int c, int d) { int e = c + d; return e; } int foo(int a, int b) { return bar(a, b); } int main(