1. arm平台下使用反汇编分析c内存分布:
  2.  
  3. arm:使用arm-linux-objdump命令将编译完毕之后的elf文件,进行反汇编.
  4. 之后重定向到tmp.s文件里.
  5.  
  6. 第一步变量例如以下c文件.
  7. vim tmp.c
  8.  
  9. #include<stdio.h>
  10.  
  11. #define VAR 0xFF
  12.  
  13. int a = 0;
  14. static int b = 0;
  15.  
  16. int c = 10;
  17. static int d = 20;
  18.  
  19. const int finalone = 10;
  20. const int final;
  21.  
  22. int main(void)
  23. {
  24.  
  25. char *hell = "hhhhhhh";
  26. const int finaltwo = 50 ;
  27. static int f = 0;
  28. static int k = 10;
  29. int aa;
  30. int bb=10;
  31. printf("VAR = %d\n, finalone = %d, finaltwo = %d",VAR,finalone,finaltwo);
  32. }
  33.  
  34. 第二步:编写Makefile文件例如以下
  35. Makefile文件例如以下:
  36. vim Makefile
  37. CC=arm-linux-gcc
  38. CFLAGS += -march=armv7-a
  39.  
  40. 第三步:编译生成可执行文件.
  41. 然后使用make命令编译给文件.make tmp 生成tmp elf格式文件.
  42.  
  43. 第四步:
  44. 以下通过使用arm-linux-objdump -D tmp > tmp.s
  45.  
  46. //得到例如以下文件tmp.s文件.
  47.  
  48. : file format elf32-littlearm
  49. 以下是摘出来的相关内如例如以下:
  50.  
  51. //以下是相应的.data段相关的初始化的变量.
  52. //变量c,d,k都存取再该区域内.结论例如以下:
  53. //须要满足例如以下要求的变量被放在.data段,也就是初始化数据段.
  54. //全部全局||statickeyword修饰)&&初始化不为的变量)
  55.  
  56. sassembly of section .data:
  57. 00011020 <__data_start>:
  58. 11020: 00000000 andeq r0, r0, r0
  59.  
  60. 00011024 <__dso_handle>:
  61. 11024: 00000000 andeq r0, r0, r0
  62.  
  63. 00011028 <c>:
  64. 11028: 0000000a andeq r0, r0, sl
  65.  
  66. 0001102c <d>:
  67. 1102c: 00000014 andeq r0, r0, r4, lsl r0
  68.  
  69. 00011030 <k.1728>:
  70. 11030: 0000000a andeq r0, r0, sl
  71.  
  72. //以下是相应的.bss段.变量a,b,f都存储再这个区域.
  73. //该区域存储的是没有初始化或者初始化为0的变量.
  74. 这些变量应该满足例如以下,条件才会被放到给区域:
  75. (全局的|被statickeyword修饰的)&&(为初始化||初始化为0的变量)
  76.  
  77. Disassembly of section .bss:
  78. 00011034 <completed.5796>:
  79. 11034: 00000000 andeq r0, r0, r0
  80.  
  81. 00011038 <a>:
  82. 11038: 00000000 andeq r0, r0, r0
  83.  
  84. 0001103c <b>:
  85. 1103c: 00000000 andeq r0, r0, r0
  86.  
  87. 00011040 <f.1727>:
  88. 11040: 00000000 andeq r0, r0, r0
  89.  
  90. 00011044 <final>:
  91. 11044: 00000000 andeq r0, r0, r0
  92.  
  93. //这个区域存放了一些字符串常量.如上c程序中的 "hhhhhhh"相应的686868.....
  94. //还有使用const修饰的全局初始化的常量.如上面的const int finalone变量.它的仅仅相应的是848c的00000000a.
  95. sassembly of section .rodata:
  96.  
  97. 00008488 <_IO_stdin_used>:
  98. 8488: 00020001 andeq r0, r2, r1
  99.  
  100. 0000848c <finalone>:
  101. 848c: 0000000a andeq r0, r0, sl
  102. 8490: 68686868 stmdavs r8!, {r3, r5, r6, fp, sp, lr}^
  103. 8494: 68686868 stmdavs r8!, {r3, r5, r6, fp, sp, lr}^
  104. 8498: 00000068 andeq r0, r0, r8, rrx
  105. 849c: 20524156 subscs r4, r2, r6, asr r1
  106. 84a0: 6425203d strtvs r2, [r5], #-61 ; 0x3d
  107. 84a4: 66202c0a strtvs r2, [r0], -sl, lsl #24
  108. 84a8: 6c616e69 stclvs 14, cr6, [r1], #-420 ; 0xfffffe5c
  109. 84ac: 20656e6f rsbcs r6, r5, pc, ror #28
  110. 84b0: 6425203d strtvs r2, [r5], #-61 ; 0x3d
  111. 84b4: 6966202c stmdbvs r6!, {r2, r3, r5, sp}^
  112. 84b8: 746c616e strbtvc r6, [ip], #-366 ; 0x16e
  113. 84bc: 3d206f77 stccc 15, cr6, [r0, #-476]! ; 0xfffffe24
  114. 84c0: 2c642520 cfstr64cs mvdx2, [r4], #-128 ; 0xffffff80
  115. 84c4: 203d2068 eorscs r2, sp, r8, rrx
  116. 84c8: 00732520 rsbseq r2, r3, r0, lsr #10}
  117.  
  118. //上面还使用#define声明一个宏.它存储再哪里呢.我们能够看一下啊main中的汇编例如以下:
  119. //第一步找出.在main中声明的局部变量.
  120. char *hell = "hhhhhhh" //这个是hell变量的声明,83c0: e3083490 movw r3, #33936 ; 0x8490
  121. const int finaltwo = 50 ; // 83cc: e3a03032 mov r3, #50 ; 0x32 //它会被保存的栈中.
  122. static int f = 0;
  123. static int k = 10;
  124. int aa; //aa变量被默认优化,不存在了.由于没有被使用,也没有使用volatilekeyword修饰,
  125. //编译在当前arm平台下默认优化等级是O2,那么将将会再汇编中步存在.
  126. int bb=10; //83d4: e3a0300a mov r3, #10 这个是bb=10
  127.  
  128. //这段汇编代码中还包括一个#255,也就是我们使用#define VAR 255 常量,
  129. //它是一个马上数.说明它仅仅占用.text文本段,也就是我们常说的代码段.
  130. //以下由段具体的解释:说明const,和#define常量的不同之处.
  131.  
  132. 000083b4 <main>:
  133. 83b4: e92d4800 push {fp, lr}
  134. 83b8: e28db004 add fp, sp, #4
  135. 83bc: e24dd018 sub sp, sp, #24
  136. 83c0: e3083490 movw r3, #33936 ; 0x8490
  137. 83c4: e3403000 movt r3, #0
  138. 83c8: e50b3008 str r3, [fp, #-8]
  139. 83cc: e3a03032 mov r3, #50 ; 0x32
  140. 83d0: e50b300c str r3, [fp, #-12]
  141. 83d4: e3a0300a mov r3, #10
  142. 83d8: e50b3010 str r3, [fp, #-16]
  143. 83dc: e308349c movw r3, #33948 ; 0x849c
  144. 83e0: e3403000 movt r3, #0
  145. 83e4: e308248c movw r2, #33932 ; 0x848c
  146. 83e8: e3402000 movt r2, #0
  147. 83ec: e5922000 ldr r2, [r2]
  148. 83f0: e51b1008 ldr r1, [fp, #-8]
  149. 83f4: e58d1000 str r1, [sp]
  150. 83f8: e1a00003 mov r0, r3
  151. 83fc: e3a010ff mov r1, #255 ; 0xff
  152. 8400: e51b300c ldr r3, [fp, #-12]
  153. 8404: ebffffbc bl 82fc <_init+0x44>
  154. 8408: e1a00003 mov r0, r3
  155. 840c: e24bd004 sub sp, fp, #4
  156. 8410: e8bd8800 pop {fp, pc}
  157.  
  158. //解析define和const的不同之处.
  159. const 定义的仅仅读变量从汇编角度来看 仅仅是给出了相应的内存地址
  160. 而不是像define一样给出的是马上数 所以 const定义的仅仅读变量在程序执行过程中仅仅有一份拷贝
  161. (由于它是全局的仅仅读变量 存放在静态区) define定义的宏变量在内存中有若干个拷贝 define宏是在预编译阶段进行替换
  162. const修饰的仅仅读变量是在编译的时候确定其值 define宏没有类型 const修饰的仅仅读变量具有特定的类型.

使用汇编分析c代码的内存分布的更多相关文章

  1. c++内存分布之虚函数(单一继承)

    系列 c++内存分布之虚函数(单一继承) [本文] c++内存分布之虚函数(多继承) 结论 1.虚函数表指针 和 虚函数表 1.1 影响虚函数表指针个数的因素只和派生类的父类个数有关.多一个父类,派生 ...

  2. C语言中内存分布及程序运行中(BSS段、数据段、代码段、堆栈)

      BSS段:(bss segment)通常是指用来存放程序中未初始化的全局变量的一块内存区域.BSS是英文Block Started by Symbol的简称.BSS段属于静态内存分配. 数据段 : ...

  3. 程序的内存分布 - 以 Linux 为例,基于 C 语言分析

    这里以 Linux 为例,用 C 语言进行演示. 内存模型 - 内存空间名称 内容 读写操作 分配时机 高地址 kernel 内核空间 命令行参数.环境变量等 不可读写 程序运行时 - stack 栈 ...

  4. 内存模型 Memory model 内存分布及程序运行中(BSS段、数据段、代码段、堆栈

    C语言中内存分布及程序运行中(BSS段.数据段.代码段.堆栈) - 秦宝艳的个人页面 - 开源中国 https://my.oschina.net/pollybl1255/blog/140323 Mem ...

  5. c++ 汇编代码看内存分配

    汇编代码看内存分配 (1). 程序运行时分为存储区域分为 存储区域 存储内容 extra 代码区 存放代码指令,包括除字符串常量的字面值 静态存储区 存放静态变量和全局变量 执行main之前就分配好了 ...

  6. 【linux】linux下对java程序生成dump文件,并使用IBM Heap Analyzer进行分析,查找定位内存泄漏的问题代码

    1.首先,java程序启动在linux,怎么生成dump文件? 1>第一步,首先你需要得到java程序的PID,最简单的方法使用如下命令 ps -ef|grep java 或者如果是docker ...

  7. GDB调试汇编分析

    GDB调试汇编分析 代码 本次实践我参照了许多先做了的同学的博客,有卢肖明,高其,张梓靖同学.代码借用的是卢肖明同学的代码进行调试运行. GCC编译 使用gcc -g gdbtest.c -o gdb ...

  8. 20145233 GDB调试汇编分析

    GDB调试汇编分析 代码 #include<stdio.h> short addend1 = 1; static int addend2 = 2; const static long ad ...

  9. VC++中的类的内存分布(上)

    0.序 目前正在学习C++中,对于C++的类及其类的实现原理也挺感兴趣.于是打算通过观察类在内存中的分布更好地理解类的实现.因为其实类的分布是由编译器决定的,而本次试验使用的编译器为VS2015 RC ...

随机推荐

  1. 【知识总结】扩展卢卡斯定理(exLucas)

    扩展卢卡斯定理用于求如下式子(其中\(p\)不一定是质数): \[C_n^m\ mod\ p\] 我们将这个问题由总体到局部地分为三个层次解决. 层次一:原问题 首先对\(p\)进行质因数分解: \[ ...

  2. debug时红点消失

    问题描述:debug时红色断点和黄色小箭头不见,而用行代码高亮的形式时. 解决办法:可以用设置 工具 => 选项 => 文本编辑器 => 指示器边距 勾上选项

  3. 我正在学英语是用learning english还是用studying english?

    学一门语言用 learn. study 表示深入研究,一般指在大学里.如果大学里的专业是英语,就可以说 study English. 1. If you study hard, you will le ...

  4. jq-文本框只能输入数字

    <input type="text" onKeyUp="value=value.replace(/\D/g,'')"  /> onKeyUp: 当输 ...

  5. dedecms:解析Robots.txt 协议标准

    Robots.txt 是存放在站点根目录下的一个纯文本文件.虽然它的设置很简单,但是作用却很强大.它可以指定搜索引擎蜘蛛只抓取指定的内容,或者是禁止搜索引擎蜘蛛抓取网站的部分或全部内容. 下面我们就来 ...

  6. css nth-child 的应用

    最近改视频监控页面,由于窗口比较多,以前是通过计算窗口大小位置来处理页面布局的,其实还是比较麻烦,而且偶尔会有页面位置错乱的现象,虽然只是及其偶尔的现象,但总归是不好. 计算窗口位置的代码: /*监控 ...

  7. 无需编写代码,用接口管理工具 eoLinker 高效完成API测试流程相关业务

    引言 作为开发人员,有时需要协助市场部门进行开发,比如在市场推广中,经常通过给用户赠送优惠券来提高复购率.这篇文章,将介绍如何使用接口管理工具 eoLinker 的自动化测试 [UI模式] 构建此业务 ...

  8. react typescript 父组件调用子组件

    //父组件import * as React from 'react'import { Input } from 'antd'const Search = Input.Searchimport &qu ...

  9. 内核调试-perf introduction

    perf概念 perf_event Perf_events是目前在Linux上使用广泛的profiling/tracing工具,除了本身是内核(kernel)的组成部分以外,还提供了用户空间(user ...

  10. 洛谷——P1063 能量项链

    P1063 能量项链 题目描述 在MarsMars星球上,每个MarsMars人都随身佩带着一串能量项链.在项链上有NN颗能量珠.能量珠是一颗有头标记与尾标记的珠子,这些标记对应着某个正整数.并且,对 ...