c 函数调用产生的汇编指令和数据在内存情况(1)

一直对函数调用的具体汇编指令和各种变量在内存的具体分配,一知半解。各种资料都很详细,但是不实践,不亲自查看下内存总不能笃定。那就自己做下。

两个目的:

一,函数和函数调用编译后的汇编指令基本样貌

二,各种变量类型的内存状况。

二,各种变量类型的内存状况。

1)常见变量在内存的位置

2)自定义结构体

1),常见变量在内存的位置。

结论:全局变量:程序一加载,和代码一样,已经在内存,放入静态区。

未初始化,内存数据用00或默认直代替。

地址变量(指针类型)放入地址直。

未初始化放入0x00000000.

局部变量: int 和char 等基本类型,程序加载时,不放入任何地方。

只有通过代码才能知道定义了一个变量。

运行代码时 push 1,放入栈中,通过 ebp+x等方式获取。

而int[5] 和char[5] 类拭固定大小数据,一般是放入静态区,编译器在编译阶段已经把使用变量的地方用 变量的偏移地址代替了。如果函数没使用,直接作为其他函数的参数,那也会直接push。不放入静态区,如下例的 p_char2[5]。

不是固定大小的变量放入,如指针,放入静态区。。等等,如果中途改变大小呢,怎么办?等下测试。测试发现会有2个临时变量名。

char * p_char3="hi.";

int p_int2[5]={1,2,3,4,5};

p_char3="hihi.";

LC2:

DB       "hihi.",0x00

LC0:

DB       "hi.",0x00

代码

int g_int1=3;//静态区.装载程序时已经放入内存

int g_int2;//静态区.装载程序时已经放入内存(放在 char * p_char3="hi."的后面).用4个字节的0来占位。

int HariMain(void)

{

int p_int=1;//代码没有执行,不存在任何地方,执行后,push 1,放入栈中。

char p_char='a';// 代码没有执行,不存在任何地方,执行后,push 1,放入栈中。

char p_char2[5]={'a','b','c','d','e'};//

//代码没有执行,不存在任何地方,执行后,用mov指令放入栈.

//mov BYTE [-56+EBP],97

char

* p_char3="hi.";//静态区. 装载程序时已经放入内存

int p_int2[5]={1,2,3,4,5};//静态区. 装载程序时已经放入内存

unsigned int sum;

sum=count(p_int,p_char,p_char2,p_char3,p_int2);

sum+=g_int1;

sum+=g_int2;

}

unsigned int count(int a,char c1,char c2[5],char * c3,int i2[5])

{

unsigned int c;

c=0;

c+=a;

c=c+c1;

c+=c2[0];

c+=c2[3];

c+=i2[0];

c+=i2[4];

c+=c3[0];

c+=c3[1];

return c;

}

数据 在内存的位置

程序装载时,

//代码区 0x0028001b

//

//^

//栈顶(空栈) 0x00310000

//静态区    0x00310000

程序运行时

//代码区 0x0028001b

/

//(栈顶)被调者的临时变量

//被调者的局部变量

//调用前的ebp寄存器直(而当前的ebp寄存器存放的这个位置的地址)

//返回地址

//参数

//栈底(空栈) 0x00310000

//静态区    0x00310000

二,自定义结构体

结论:自定义结构,可以看作数组。

自定义结构,作为参数的话,会把所有成员变量,一个一个入栈

如果 传递自定义结构指针,那么只传地址。

//全局自定义结构体变量, 和全局定长数组类拭。

程序一加载,和代码一样,已经在内存,放入静态区。

未初始化放入00数据,

代码中出现变量名,用地址代替。[_struce_a]

赋直:

MOV       BYTE [_myStruck_a+4],97

直接   地址+数字定位成员

全局自定义结构体地址变量(指针),

程序一加载,和代码一样,已经在内存,放入静态区。

但是大小不是struck的大小,而是4B,也就是一个地址变量的大小。

未初始化放入0x00000000.

赋直:

MOV       EDX,DWORD [_myStruck_c]

MOV       DWORD [8+EDX],3

必须取地址的直得到真正的地址再加数字定位成员

//局部变量,

程序一加载,不存在任何地方。

只有运行时,放入栈中。如:

struct myStruck myStruck_d;

编译为SUB       ESP,60

myStruck_d.char_b='e'

编译为

MOV   BYTE [-36+EBP],101

 call 之后的栈数据.

struct myStruck{

int int_a;

char char_b;

int int_array[2];

char * char_array;

};

int HariMain(void)

{

char c1[2]={'b','c'};

//myStruck_a.int_a=1;

myStruck_a.char_b='a';//MOV       BYTE [_myStruck_a+4],97

myStruck_a.int_array[0]=1;//MOV       DWORD [_myStruck_a+8],1

myStruck_a.int_array[1]=2;//MOV       DWORD [_myStruck_a+12],2

//myStruck_a.char_array=c1;

//MOV       EAX,DWORD [_myStruck_c]

myStruck_c->int_a=2;//MOV       DWORD [EAX],2

myStruck_c->char_b='c';//MOV       BYTE [4+EAX],99

//MOV       EDX,DWORD [_myStruck_c]

myStruck_c->int_array[0]=3;//MOV       DWORD [8+EDX],3

myStruck_c->int_array[1]=4;//MOV       DWORD [12+EDX],4

myStruck_c->char_array=c1;//LEA       EAX,DWORD [-42+EBP]     MOV       DWORD [16+EDX],EAX

//MOV       EBP,ESP

//SUB       ESP,60

struct myStruck myStruck_d;

myStruck_d.char_b='e';//MOV       BYTE [-36+EBP],101

myStruck_d.int_array[0]=5;//MOV       DWORD [-32+EBP],5

myStruck_d.int_array[1]=6;//MOV       DWORD [-28+EBP],6

unsigned int c=counta(myStruck_a,myStruck_c,myStruck_d);

io_hlt();

return 0;

}

unsigned int counta(struct myStruck mys,struct myStruck * mysc,struct myStruck mys2)

{

unsigned int c;

c=0;

c=mys.int_a;

c=c+mysc->int_a;//ADD       EAX,DWORD [8+EBP]

c=c+mysc->char_array[0];//MOV       EDX,DWORD [28+EBP]  MOV       EDX,DWORD [16+EDX]  ADD       EAX,EDX  //char_array[0]

c=c+mys.char_array[0];//

c=c+mys2.int_a;

return c;

}

c 函数调用产生的汇编指令和数据在内存情况(2)的更多相关文章

  1. c 函数调用产生的汇编指令和数据在内存情况(1)

    一直对函数调用的具体汇编指令和各种变量在内存的具体分配,一知半解.各种资料都很详细,但是不实践,不亲自查看下内存总不能笃定.那就自己做下. 两个目的: 一,函数和函数调用编译后的汇编指令基本样貌 二, ...

  2. C语言函数调用过程,汇编角度查看

    C语言函数调用过程,汇编角度查看 把函数的参数按照调用约定压栈或者存储到寄存器中 调用要使用的函数,先把调用者的地址入栈,方便回来 跳转到函数 把函数使用到的一些寄存器压栈,避免修改寄存器的值 执行函 ...

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

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

  4. iOS图片加载到内存中占用内存情况

    我的测试结果: 图片占用内存   图片尺寸           .png文件大小 1MB              512*512          316KB 4MB              10 ...

  5. php测试程序运行时间和占用内存情况

    php测试程序运行时间和占用内存情况: $HeaderTime = microtime(true);//参数true表示返回浮点数值 /** *CODE */ printf(" total ...

  6. Android内存管理(5)*官方教程:Logcat内存日志各字段含义,查看当前内存快照,跟踪记录内存分配,用adb查看内存情况时各行列的含义,捕获内存快照的3种方法,如何让程序暴漏内存泄漏的方法

    Investigating Your RAM Usage In this document Interpreting Log Messages                 内存分析日志中各消息的含 ...

  7. linux 查看cpu个数,内存情况,系统版本

    查看cpu个数 总核数 = 物理CPU个数 * 每颗物理CPU的核数 总逻辑CPU数 = 物理CPU个数 * 每颗物理CPU的核数 * 超线程数 查看物理CPU个数 cat /proc/cpuinfo ...

  8. Linux 查看进程消耗内存情况总结

    在Linux中,有很多命令或工具查看内存使用情况,今天我们来看看如何查看进程消耗.占用的内存情况,Linux的内存管理和相关概念要比Windows复杂一些.在此之前,我们需要了解一下Linux系统下面 ...

  9. 使用jconsole分析内存情况-JVM

    JVM调优分析演练: Jconsole中对内存为如下结构: 原始代码: public static void main(String[] args) { BigInteger [] pArr=new ...

随机推荐

  1. 【jqGrid for ASP.NET MVC Documentation】.学习笔记.4.性能

    1 HTML / ViewState 大小 1.1 HTML 大小 jqGrid for ASP.NET MVC 使用最佳的客户端渲染,意味着 HTML gird 的 尺寸是最小的.事实上,只有 gr ...

  2. js对select动态添加和删除OPTION

    <select id="ddlResourceType" onchange="getvalue(this)"> </select> 动态 ...

  3. declare和typeset DEMO

    declare=typeset,用法完成相同. declare不指定变量:显示所有变量的值. -r选项,把指定变量定义为只读变量: [xiluhua@vm-xiluhua][~]$ declare - ...

  4. Ganglia监控MySQL

    1.下载mysql监控脚本: [root@node1 app]# wget http://www.javabloger.com/att/gmetric-mysql.sh 2.修改脚本中的msyql用户 ...

  5. 项目管理:CocoaPods建立私有仓库

    CocoaPods是iOS,Mac下优秀的第三方包管理工具,类似于java的maven,给我们项目管理带来了极大的方便. 个人或公司在开发过程中,会积累很多可以复用的代码包,有些我们不想开源,又想像开 ...

  6. 减少GC开销的措施

    程序的运行会直接影响系统环境的变化,从而影响GC的触发.若不针对GC的特点进行设计和编码,就会出现内存驻留等一系列负面影响.为了避免这些影响,基本的原则就是尽可能地减少垃圾和减少GC过程中的开销.具体 ...

  7. ACM题目————Equations

    Description Consider equations having the following form: a*x1^2+b*x2^2+c*x3^2+d*x4^2=0 a, b, c, d a ...

  8. Unity-Animator深入系列---录制与回放

    回到 Animator深入系列总目录 Animator自带了简单的动画录制,回放功能.但可惜的是不支持持久化的数据输出.因而不能作为录像保存 不过这种可以作为竞速,格斗类游戏在结束时经常出现的游戏回放 ...

  9. 翻译之basename()

    NAME top basename, dirname - parse pathname components SYNOPSIS top #include <libgen.h> char * ...

  10. Bootstrap——基本模板

    <!DOCTYPE html><html lang="zh-cn">  <head>    <meta charset="utf ...