码迷,mamicode.com
首页 > 其他好文 > 详细

使用汇编分析c代码的内存分布

时间:2014-12-15 00:13:34      阅读:336      评论:0      收藏:0      [点我收藏+]

标签:blog   io   ar   使用   sp   for   on   文件   数据   

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\n, 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段,也就是初始化数据段.
//所有全局||static关键字修饰)&&初始化不为的变量)

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的变量.
	这些变量应该满足如下,条件才会被放到给区域:
	(全局的|被static关键字修饰的)&&(为初始化||初始化为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变量被默认优化,不存在了.因为没有被使用,也没有使用volatile关键字修饰,
							  //编译在当前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修饰的只读变量具有特定的类型.


使用汇编分析c代码的内存分布

标签:blog   io   ar   使用   sp   for   on   文件   数据   

原文地址:http://blog.csdn.net/shaohuazuo/article/details/41932923

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!