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. ORACLE添加表约束的语法示例

    转自:http://jingyan.baidu.com/article/f54ae2fccda68d1e93b84942.html 示例: --班级表 CREATE TABLE TCLASS( cl_ ...

  2. 今天 同一个Nav 左右button 替换不显示的问题 viewDidLoad, viewWillDisappear, viewWillAppear等区别及各自的加载顺序

    viewWillAppear:  Called when the view is about to made visible. Default does nothing视图即将可见时调用.默认情况下不 ...

  3. 3、JavaScript

    1.    JavaScript简介 1.1. JavaScript由来 Netscape 发明了 JavaScript JavaScript由Netscape 在1995年发明.早期的主要目的是处理 ...

  4. 搭建HTTP Live Streaming直播系统

    最近,需要将苹果的HTTP Live Streaming系统搭建起来.完全没有头绪,故第一步就是学习. 一.学习资料 官网资料 1. http://developer.apple.com/resour ...

  5. sql必知必会(第四版) 学习笔记

    还有一个<Sqlserver2008技术内幕>的笔记,也很好!~ http://www.cnblogs.com/liupeng61624/p/4354983.html 温习一遍简单的sql ...

  6. 分布式拒绝服务攻击(DDoS)原理及防范

    DDoS攻击概念 DoS的攻击方式有很多种,最基本的DoS攻击就是利用合理的服务请求来占用过多的服务资源,从而使合法用户无法得到服务的响应. DDoS攻击手段是在传统的DoS攻击基础之上产生的一类攻击 ...

  7. 修改datagridview中其中一列的值

    控件.rows[0].cells['名'].value = 值

  8. Codeforces Canada Cup 2016

    A. Jumping Ball time limit per test 2 seconds memory limit per test 256 megabytes input standard inp ...

  9. UPDATE语句:将一个表里的字段更新到另一个表的字段里的语句

    update table2 b,(select b.area_id as arid,sum(a.user_amount) as bcount from table1 a,table2 b where ...

  10. django下的ckeditor 5.0 文本编辑器上传功能。

    完整的后台界面怎么可以没有文本编辑器,但是django的admin界面很疑惑,没有自带文本编辑器,好在网上有不少成型的库可以用 我用的是ckeditor编辑器,安装和配置我引用别人的博客 这篇博客配置 ...