zoukankan      html  css  js  c++  java
  • 使用汇编分析c代码的内存分布

    arm平台下使用反汇编分析c内存分布:
    
    arm:使用arm-linux-objdump命令将编译完毕之后的elf文件,进行反汇编.
    之后重定向到tmp.s文件里.
    
    第一步变量例如以下c文件.
    vim tmp.c
    	
    	#include<stdio.h>
    	
    	#define  VAR 0xFF
    	
    	int a = 0; 
    	static int  b =  0;
    	
    	int c = 10;
    	static int  d = 20; 
    	
    	const int finalone = 10;
    	const int final;
    	
    	int main(void)
    	{
    	
    		char *hell = "hhhhhhh";
    		const int finaltwo = 50 ;
    		static int f = 0;
    		static int k = 10;
    		int aa; 
    		int bb=10;
    		printf("VAR = %d
    , finalone = %d, finaltwo = %d",VAR,finalone,finaltwo);
    	}
    
    第二步:编写Makefile文件例如以下
    	Makefile文件例如以下:
    	vim Makefile
    	CC=arm-linux-gcc
    	CFLAGS += -march=armv7-a
    
    
    第三步:编译生成可执行文件.	
    	然后使用make命令编译给文件.make tmp 生成tmp elf格式文件.
    
    第四步:
    	以下通过使用arm-linux-objdump -D tmp  >  tmp.s
    
    //得到例如以下文件tmp.s文件.
    
    	:     file format elf32-littlearm
    	以下是摘出来的相关内如例如以下:
    
    //以下是相应的.data段相关的初始化的变量.
    //变量c,d,k都存取再该区域内.结论例如以下:
    //须要满足例如以下要求的变量被放在.data段,也就是初始化数据段.
    //全部全局||statickeyword修饰)&&初始化不为的变量)
    
    sassembly of section .data: 
    	00011020 <__data_start>:
    	11020:	00000000	andeq	r0, r0, r0
    
    	00011024 <__dso_handle>:
    	11024:	00000000	andeq	r0, r0, r0
    
    	00011028 <c>:
    	11028:	0000000a	andeq	r0, r0, sl      
    
    	0001102c <d>:
    	1102c:	00000014	andeq	r0, r0, r4, lsl r0
    
    	00011030 <k.1728>:
    	11030:	0000000a	andeq	r0, r0, sl
    
    //以下是相应的.bss段.变量a,b,f都存储再这个区域.
    //该区域存储的是没有初始化或者初始化为0的变量.
    	这些变量应该满足例如以下,条件才会被放到给区域:
    	(全局的|被statickeyword修饰的)&&(为初始化||初始化为0的变量)
    
    	Disassembly of section .bss:
    	00011034 <completed.5796>:
    	11034:	00000000	andeq	r0, r0, r0
    
    	00011038 <a>:
    	11038:	00000000	andeq	r0, r0, r0
    
    	0001103c <b>:
    	1103c:	00000000	andeq	r0, r0, r0
    
    	00011040 <f.1727>:
    	11040:	00000000	andeq	r0, r0, r0
    
    	00011044 <final>:
    	11044:	00000000	andeq	r0, r0, r0
    
    
    //这个区域存放了一些字符串常量.如上c程序中的 "hhhhhhh"相应的686868.....
    //还有使用const修饰的全局初始化的常量.如上面的const int finalone变量.它的仅仅相应的是848c的00000000a.	
    	sassembly of section .rodata:
    
    	00008488 <_IO_stdin_used>:
    	8488:	00020001	andeq	r0, r2, r1
    
    	0000848c <finalone>:
    	848c:	0000000a	andeq	r0, r0, sl
    	8490:	68686868	stmdavs	r8!, {r3, r5, r6, fp, sp, lr}^
    	8494:	68686868	stmdavs	r8!, {r3, r5, r6, fp, sp, lr}^
    	8498:	00000068	andeq	r0, r0, r8, rrx
    	849c:	20524156	subscs	r4, r2, r6, asr r1
    	84a0:	6425203d	strtvs	r2, [r5], #-61	; 0x3d
    	84a4:	66202c0a	strtvs	r2, [r0], -sl, lsl #24
    	84a8:	6c616e69	stclvs	14, cr6, [r1], #-420	; 0xfffffe5c
    	84ac:	20656e6f	rsbcs	r6, r5, pc, ror #28
    	84b0:	6425203d	strtvs	r2, [r5], #-61	; 0x3d
    	84b4:	6966202c	stmdbvs	r6!, {r2, r3, r5, sp}^
    	84b8:	746c616e	strbtvc	r6, [ip], #-366	; 0x16e
    	84bc:	3d206f77	stccc	15, cr6, [r0, #-476]!	; 0xfffffe24
    	84c0:	2c642520	cfstr64cs	mvdx2, [r4], #-128	; 0xffffff80
    	84c4:	203d2068	eorscs	r2, sp, r8, rrx
    	84c8:	00732520	rsbseq	r2, r3, r0, lsr #10}
    
    //上面还使用#define声明一个宏.它存储再哪里呢.我们能够看一下啊main中的汇编例如以下:
    //第一步找出.在main中声明的局部变量.
    	char *hell = "hhhhhhh"	  //这个是hell变量的声明,83c0:	e3083490	movw	r3, #33936	; 0x8490
    	const int finaltwo = 50 ; // 83cc:	e3a03032	mov	r3, #50	; 0x32 //它会被保存的栈中.
    	static int f = 0;
    	static int k = 10;
    	int aa;                   //aa变量被默认优化,不存在了.由于没有被使用,也没有使用volatilekeyword修饰,
    							  //编译在当前arm平台下默认优化等级是O2,那么将将会再汇编中步存在.
    	int bb=10;                //83d4:	e3a0300a	mov	r3, #10 这个是bb=10
    
    
    	//这段汇编代码中还包括一个#255,也就是我们使用#define VAR 255 常量, 
    	//它是一个马上数.说明它仅仅占用.text文本段,也就是我们常说的代码段.
    	//以下由段具体的解释:说明const,和#define常量的不同之处.
    
    	000083b4 <main>:
    	83b4:	e92d4800	push	{fp, lr}
    	83b8:	e28db004	add	fp, sp, #4
    	83bc:	e24dd018	sub	sp, sp, #24
    	83c0:	e3083490	movw	r3, #33936	; 0x8490
    	83c4:	e3403000	movt	r3, #0
    	83c8:	e50b3008	str	r3, [fp, #-8]
    	83cc:	e3a03032	mov	r3, #50	; 0x32
    	83d0:	e50b300c	str	r3, [fp, #-12]
    	83d4:	e3a0300a	mov	r3, #10
    	83d8:	e50b3010	str	r3, [fp, #-16]
    	83dc:	e308349c	movw	r3, #33948	; 0x849c
    	83e0:	e3403000	movt	r3, #0
    	83e4:	e308248c	movw	r2, #33932	; 0x848c
    	83e8:	e3402000	movt	r2, #0
    	83ec:	e5922000	ldr	r2, [r2]
    	83f0:	e51b1008	ldr	r1, [fp, #-8]
    	83f4:	e58d1000	str	r1, [sp]
    	83f8:	e1a00003	mov	r0, r3
    	83fc:	e3a010ff	mov	r1, #255	; 0xff
    	8400:	e51b300c	ldr	r3, [fp, #-12]
    	8404:	ebffffbc	bl	82fc <_init+0x44>
    	8408:	e1a00003	mov	r0, r3
    	840c:	e24bd004	sub	sp, fp, #4
    	8410:	e8bd8800	pop	{fp, pc}
    	
    //解析define和const的不同之处.	
    	const 定义的仅仅读变量从汇编角度来看 仅仅是给出了相应的内存地址 
    	而不是像define一样给出的是马上数 所以 const定义的仅仅读变量在程序执行过程中仅仅有一份拷贝
    	(由于它是全局的仅仅读变量 存放在静态区) 而define定义的宏变量在内存中有若干个拷贝 define宏是在预编译阶段进行替换 
    	而const修饰的仅仅读变量是在编译的时候确定其值 define宏没有类型 而const修饰的仅仅读变量具有特定的类型.


  • 相关阅读:
    LLVM 笔记(二)—— PHI node
    Ubuntu,sublime快速启动
    ubuntu14.04安装Thinkphp
    ubuntu,scrapy安装
    ubuntu,sublime text 3中文输入的问题
    ubuntu安装beatifulsoup,pip,creepy
    ubuntu,系统设置无法打开
    Ubuntu14.04安装完成的基本配置
    在Sublime Text 3中添加snippet
    领航工作室启用新域名啦!
  • 原文地址:https://www.cnblogs.com/yfceshi/p/6910045.html
Copyright © 2011-2022 走看看