Linux调试私房菜(六)深入理解程序的结构

十三、深入理解程序的结构

1. 程序由不同的段构成(代码段,数据段)

  • 程序的静态特征就是指令和数据
  • 程序的动态特征就是执行指令处理数据

2. 源程代码到可执行程序文件的对应关系

静态分析工具多半都是通过文件头来获得信息。

局部变量存储在栈上。

3. 代码段(.text

  • 源代码中的可执行语句编译后进入代码段
  • 代码段在有内存管理单元的系统中具有只读属性
  • 代码段的大小在编译结束后就已经固定(不能动态改变)
  • 代码段中可以包含常量数据(如︰常量字符串)

4. 数据段(.data, .bss, .rodata

  • 数据段用于存放源代码中具有全局生命期的变量
    • .bss
      • 存储未初始化(初始化为0)的变量
    • .data
      • 存储具有非0初始值的变量
    • .rodata
      • 存储const关键字修饰的变量

5. 问题

同是全局变量静态局部变量为什么初始化的和未初始化的保存在不同段中

6. 深入理解.data.bss

  • 程序加载后
    • .bss段中的所有内存单元被初始化为 0
    • 将程序文件中.data段相关的初始值写入对应内存单元

.bss段中的变量不用在程序文件中保存初始值,从而减小可执行程序文件的体积,并且提高程序的加载效率。

7. 编程实验:关键段的分析

编译器默认四字节对齐

查看.data的初始值  objdump -s -j .data test.out

查看.rodata的初始值  objdump -s -j .rodata test.out

8. 程序中的栈(Stack

  • 程序中栈的本质是一片连续的内存空间
  • SP 寄存器作为栈顶“指针”实现入栈操作和出栈操作

9. 栈的深入理解

  • 中断发生时,栈用于保存寄存器的值
  • 函数调用时,栈用于保存函数的活动记录(栈帧信息)
  • 并发编程时,每一个线程拥有自己独立的栈

10. 程序中的堆( Heap )

  • 堆是一片闲置的内存空间,用于提供动态内存分配
  • 堆空间的分配需要函数支持(malloc)
  • 堆空间在使用结束后需要归还(free)

11. 内存映射段(Memory Mapping Segment

  • 内核将硬盘文件的内容直接映射到内存映射段(mmap)
  • 动态链接库在可执行程序加载时映射到内存映射段
  • 程序执行时能够创建匿名映射区存放程序数据

12. 内存映射文件原理简介

  • 将硬盘上的文件数据逻辑映射到内存中(零耗时)
  • 通过缺页中断进行文件数据的实际载入(一次数据拷贝)
  • 映射后的内存的读写就是对文件数据的读写

13. 实例分析:内存映射文件的原理

14. 小结

  • 0 - 0x00048000  操作系统使用
  • 堆的起始地址是随机的,为了安全。
  • 内存映射段的起始地址是随机的,为了安全。
  • 栈的起始地址是随机的,为了安全。
  • 起始地址是随机的,防止恶意程序进行破坏,导致系统崩溃。
  • 栈、内存映射段生长方向是由高地址向低地址生长。
  • 堆生长方向是由低地址向高地址生长。
  • 内核空间占用1gb
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值