#PS:请尊重原创,不喜勿喷
#PS:要转载请注明出处,本人版权所有
#PS:这个只是 《 我自己 》理解,如果和你的原则相冲突,请
谅解,勿喷
近段时间看一些代码,自己也写了一些。但是写着写着感觉自己迷茫了,自己对程序的结构越来越模糊,甚至都不相信自己的写的部分,或者相信自己的知识。
那么现在就来终结这些想法,让自己提升一下。
本系列文章主要分为两部分,(一)是分析程序在内存中的分布(二)是linux下程序的执行流程
注释:现在PC平台流行的可执行文件格式(Executable)主要是Windows下的PE(Portable
Executable)和linux下的ELF(Executable Linkable Format),他们都是COFF(Common
file format)的变种。
下面是程序在内存中的分布:
一般具有一个完整内存分布的程序大概有以下几部分。
------------------
CODE/TEXT SEGMENT ---存放程序中的机器指令(过程)
------------------
RO DATA SEGMENT---存放只读数据(在程序执行过程中不会改变但是有用的数据),如const常量(局部与全局)等等
------------------
RW DATA SEGMENT---存放读写数据(在程序执行过程中,会改变的数据),如static 修饰的变量(全局与局部),初始化全局变量等等
------------------
BSS SEGMENT---未初始化数据段,存放未初始化变量的声明
------------------
HEAP SEGMENT---堆,malloc/realloc等等。。。
------------------
STACT SEGMENT---栈,函数内部普通变量,现场保护信息等等
------------------
小提示:
code/text ,rw/ro data,bss属于静态区(如:static修饰,全局变量(默认为extern修饰)),而heap,stack属于动态区(如:局部普通变量(默认auto修饰,可选为register))
实例分析:
注意:
test.c
#include <stdio.h>
#include <stdlib.h>
const char g_ro[] = {"save to ro data segment"};
static char g_rw[] = {"save to rw data segment"};
int g_bss[100];//save to bss segment
int main(int argc, char *argv[]){
int l_stack;//stack 4bytes
char l_stack_1[100];//stack 100bytes
char * l_stack_2 = "this string save to ro data segment,but l_stack_2 save to stack(4bytes)";
char * l_stack_3;//l_stack_3 save to stack(4bytes)
char l_stack_4[] = {"this string save to ro data segment,but l_stack_4 save to stack(4bytes)"};
static char l_rw[] = {"save to rw data segment"};
static char l_bss[100];//save to bss segment
static int l_rw_1 = 1;//save to rw data segment
char * m_p = (char *) malloc(100*sizeof(char));//save to heap
free(m_p);
return 0;
}
通过以下图片,验证变量g_rw,g_ro是否在ro/rw data segment
首先,确定ro data segment / rw data segment 起始地址
在符号表中:
符号表中关于g_rw和g_ro的描述:
调入到gdb中调试显示:
同理,可以继续分析其他变量。
注意:符号表使用readelf -a elf_file_name读取
#PS:请尊重原创,不喜勿喷
#PS:要转载请注明出处,本人版权所有
有问题请留言,看到后我会第一时间回复