Linux应用程序地址布局

来源:互联网 发布:php模拟登录教务处 编辑:程序博客网 时间:2024/06/06 00:48
Linux应用程序在内存中的地址分布:

代码段(正文段):CPU执行的机器指令部分。。通常为共享的,也是只读的,以防止程序由于意外而修改其指令。
初始化数据段: 通常被称为数据段,它包含了程序中需明确赋初值的变量。
未初始化数据段(bss段):意为由符号开始的块(block started by symbol),在程序开始之前,内核将此段中的数据初始化为0或空指针。。
:自动变量、局部变量以及每次函数调用时所需保存的信息都存放在此段。。
:通常在堆中进行动态存储分配,,历史惯例,,堆位于未初始化数据段(bss)和栈之间。
注:对于32位Intel x86处理器上的Linux,代码段(正文段)都是从0x08048000单元开始的,栈底在0xc0000000之下开始。

linux命令size可以报告代码段、数据段、bss段的长度(以字节为单位)--------dec:十进制三段长度总和,hex十六进制三段长度总和



在另一个终端查看运行程序的内存分布:
1、先找到运行代码的进程ID  ---- ps  aux

2、查看该进程ID 的代码分布---- cat /proc/4040/maps



然后比较代码中变量的地址,,找到对应的段地址。  (主要注意局部常量存储在栈上)

以下为比对结果

同样也可使用 readelf -S test 命令查看详细的各个段的位置。



遇到的问题:

以上代码是在linux终端并不会输出hello。因为当一个流涉及终端输入或者输出时,该流的缓冲类型为行缓冲。而行缓冲在遇到换行符才进行IO操作(输入或输出到终端)。所以应该为printf("hello \n");才能输出
对于行缓冲有两个限制。第一,因为标准I/O库用来收集每一行的缓冲区的长度是固定的,所以只要填满了缓冲区,那么即使没有写一个换行符,也进行I/O操 作。第二,任何时候只要通过标准I/O库要求从a一个不带缓冲的流,或者b一个行缓冲的流得到输入数据,那么就会造成冲洗所有行缓冲输出流。在b中带了一 个在括号中的说明,其理由是,所需的数据可能已在缓冲区中,他并不需求在需要数据时才从内核读数据。很明显,从不带缓冲的一个流中进行输入要求当时从内核得到数据  
ISO C要求下列缓冲特征:
当且仅当标准输入和标准输出并不涉及交互式设备时,他们才是全缓冲的。
标准出错绝不会是全缓冲的。
很多系统默认使用下列类型的缓冲:
标准出错是不带缓缓冲的。
如若是涉及终端设备的其他流,则他们是行缓冲的;否则是全缓冲的。
对任何一个给定的流,如果我们并不喜欢这些系统默认的情况,则可调用下列函数中的一个更改缓冲类型:
void setbuf(FILE *restrict fp, char *restrict buf)
int setvbuf(FILE *restrict fp, char *restrict buf,int mode,size_t size)

见apue--p116页。


0 0
原创粉丝点击