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修饰的仅仅读变量具有特定的类型.


  • 相关阅读:
    VisualSVN-Server windows 版安装时报错 "Service 'VisualSVN Server' failed to start. Please check VisualSVN Server log in Event Viewer for more details."
    Pytest 单元测试框架之初始化和清除环境
    Pytest 单元测试框架入门
    Python(email 邮件收发)
    Python(minidom 模块)
    Python(csv 模块)
    禅道简介
    2020年最好的WooCommerce主题
    Shopify网上开店教程(2020版)
    WooCommerce VS Magento 2020:哪个跨境电商自建站软件更好?
  • 原文地址:https://www.cnblogs.com/yfceshi/p/6910045.html
Copyright © 2011-2022 走看看