从反汇编的角度看C++语法(hani199012@gmail.com.cn/QQ :1121797386)

写在前面的话

写这些文章,主要是对自己在学习C++过程中遇到的一些问题进行总结,同时,利用反汇编工具来看C++语法在实际内存中的体现,因为,C++是一门高级语言,其实是写给人看的,但是机器只认识0  1 ,查看在学习过程中编写的一些练习的程序的反汇编代码,这样,看得更加实际,不那么抽象。

主要的参考书籍是《C++反汇编与逆向分析》(钱林松 赵海旭),需要推荐一下这本书,

这本书确实写的很好,我也是通过这本书来学习的,通过这本书,可以深刻的领会,逆向分析的威力。

其实,我也只是个学习者,通过,写一点总结性的文章,放到网上,希望,能够得到读者的批评,进一步能够相互学习。

用到的工具: VC++6.0

构造函数:

#include "stdafx.h"

#include "stdio.h"

class CNumber

{

public:

CNumber()

{

m_nNumber=1;

}

private:

int m_nNumber;

};

int main(int argc, char* argv[])

{

CNumber number;

return 0;

}

这段代码很简单,当然,重点不是代码本身,而是反汇编代码,通过查看反汇编代码,来认识在一个类创建了一个对象,也就是类实例化一个对象时,在内存中究竟发生了什么。

学习编程也应该保持这份好奇心,凡是探个究竟,一直深挖到不能再挖为止。

用VC6.0(我用的是英文版的)自带的反汇编工具查看(最好先设置一个端点, Build->

StartDebug->Go)单击右上角disassembly就可以查看反汇编代码

@ILT+0(??0CNumber@@QAE@XZ):

00401005   jmp         CNumber::CNumber (00401060)  ;构造函数

@ILT+5(_main):

0040100A   jmp         main (00401020)              ;主函数

0040100F   int         3

00401010   int         3

13:   private:

14:       int m_nNumber;

15:   };

16:

17:   int main(int argc, char* argv[])

18:   {

00401020   push        ebp

00401021   mov         ebp,esp

00401023   sub         esp,44h

00401026   push        ebx

00401027   push        esi

00401028   push        edi

00401029   lea         edi,[ebp-44h]

0040102C   mov         ecx,11h

00401031   mov         eax,0CCCCCCCCh

00401036   rep stos    dword ptr [edi]

19:       CNumber number;

00401038   lea         ecx,[ebp-4]       ;取得对象首地址,传入ecx中

0040103B   call        @ILT+0(CNumber::CNumber) (00401005);调用构造函数

20:

21:       return 0;

00401040   xor         eax,eax

22:   }

00401042   pop         edi

00401043   pop         esi

00401044   pop         ebx

00401045   add         esp,44h

00401048   cmp         ebp,esp

0040104A   call        __chkesp (004010a0)

0040104F   mov         esp,ebp

00401051   pop         ebp

00401052   ret

1:    // construct.cpp : Defines the entry point for the console application.

2:    //

3:

4:    #include "stdafx.h"

5:    #include "stdio.h"

6:    class CNumber

7:    {

8:    public:

9:        CNumber()

00401060   push        ebp                    ;一系列的入栈出栈动作

00401061   mov         ebp,esp     ;入栈前保存一系列的寄存器的值

00401063   sub         esp,44h                 ;出栈的时候恢复这些寄存器的值

00401066   push        ebx    ;进入一个函数前,这个函数要借寄存器

00401067   push        esi                ;做到有借有还

00401068   push        edi

00401069   push        ecx

0040106A   lea         edi,[ebp-44h]

0040106D   mov         ecx,11h

00401072   mov         eax,0CCCCCCCCh

00401077   rep stos    dword ptr [edi]      ;

00401079   pop         ecx   ;   还原ecx,ecx中保存对象的首地址,

0040107A   mov         dword ptr [ebp-4],ecx   ; [ebp-4]就是this指针

10:       {

11:           m_nNumber=1;

0040107D   mov         eax,dword ptr [ebp-4]

00401080   mov         dword ptr [eax],1

12:       }

00401086   mov         eax,dword ptr [ebp-4]

00401089   pop         edi

0040108A   pop         esi

0040108B   pop         ebx

0040108C   mov         esp,ebp

0040108E   pop         ebp

0040108F   ret

按照内存中地址顺序拷贝出来,可以看到,先执行类的构造函数,在执行main函数,

然而,本来写在一起的类的成员变量和构造函数确实被编译器活生生的分割了,

这里也可以推测,所谓,类(暂时不考虑虚函数静态成员等问题)的大小是类的成员变量的大小,而不包括成员函数,是有一定道理的。

通过分析,可知,this指针是有构造函数产生的,构造函数结束后,会将this指针作为返回值。如果没有构造函数,编译器会默认的提供一个构造函数,而类的成员函数是根据this指针区分每个对象的,所以就算没有构造函数,也不会出现分不清类对象的情况。

接下来的情况没有给出代码,

1、类中有构造函数,但是没有成员变量,依然会执行构造函数,产生tihs指针,

00401079   pop         ecx

0040107A   mov         dword ptr [ebp-4],ecx

2、空类,什么都没有生成,但是仍然会有构造函数,而这个地址却什么都没有

@ILT+0(??0CNumber@@QAE@XZ):

00401005   jmp         CNumber::CNumber (00401060)

@ILT+5(_main):

0040100A   jmp         main (00401020)

据说,C++编译时空类的大小是1,可以推测,这个空类的大小和构造函数没有什么关系,可能仅仅是为了保证语法的一致性,编译器就让空类为1了

3, 没有构造函数或其他成员函数,只有成员变量

同上一个情况类似

4, 有成员函数的时候,会将看到

00401079   pop         ecx

0040107A   mov         dword ptr [ebp-4],ecx

代码的出现,表示this 指针出现,而这唯一的一个成员函数返回this指针,作为这个类的构造函数

13:   int  foo()

14:   {

00401060   push        ebp

00401061   mov         ebp,esp

00401063   sub         esp,44h

00401066   push        ebx

00401067   push        esi

00401068   push        edi

00401069   push        ecx

0040106A   lea         edi,[ebp-44h]

0040106D   mov         ecx,11h

00401072   mov         eax,0CCCCCCCCh

00401077   rep stos    dword ptr [edi]

00401079   pop         ecx

0040107A   mov         dword ptr [ebp-4],ecx

15:    return 3;

0040107D   mov         eax,3

16:   }

00401082   pop         edi

00401083   pop         esi

00401084   pop         ebx

00401085   mov         esp,ebp

00401087   pop         ebp

00401088   ret

综上,构造函数并不是总会存在的。

从反汇编的角度看C++语法(构造函数)相关推荐

  1. 编译器角度看C++复制构造函数

    [C++对象模型]复制构造函数的建构操作 关于复制构造函数的简单介绍,可以看我以前写过的一篇文章C++复制控制之复制构造函数该文章中介绍了复制构造函数的定义.调用时机.也对编译器合成的复制构造函数行为 ...

  2. 从JDK源码角度看Long

    概况 Java的Long类主要的作用就是对基本类型long进行封装,提供了一些处理long类型的方法,比如long到String类型的转换方法或String类型到long类型的转换方法,当然也包含与其 ...

  3. 从一个程序员的角度看——微信小应用

    前言: 最近初步了解了一下微信小应用,APP端的同事也非常感兴趣,于是在公司内部做了一个小小的分享,分享的过程中有很多讨论内容,大家也是非常感兴趣和有自己的看法,当时"混乱"的场面 ...

  4. 公司技术管理角度看C++游戏程序员发展

    公司技术管理角度看C++游戏程序员发展 H3D 这是我多年来招聘培训游戏程序员的一点想法.一直想汇总一下.主要目的是为了更好的对公司新进C++程序员进行培训,并且建立起游戏程序员培训,发展,成才,成为 ...

  5. 从程序员角度看ELF

    从程序员角度看ELF 原文:< ELF:From The Programmer's Perspective> 作者:Hongjiu Lu <mailto: hjl@nynexst.c ...

  6. go conn 读取byte数组后是否要_【技术推荐】正向角度看Go逆向

    Go语言具有开发效率高,运行速度快,跨平台等优点,因此正越来越多的被攻击者所使用,其生成的是可直接运行的二进制文件,因此对它的分析类似于普通C语言可执行文件分析,但是又有所不同,本文将会使用正向与逆向 ...

  7. 2015年《大数据》高被引论文Top10文章No.2——大数据时代的数据挖掘 —— 从应用的角度看大数据挖掘(下)...

    2015年<大数据>高被引论文Top10文章展示 [编者按]本刊将把2015年<大数据>高被引论文Top10的文章陆续发布,欢迎大家关注!本文为高被引Top10论文的No.2, ...

  8. 【2015年第4期】大数据时代的数据挖掘 —— 从应用的角度看大数据挖掘(下)...

    大数据时代的数据挖掘 -- 从应用的角度看大数据挖掘(下) 李 涛1,2,曾春秋1,2,周武柏1,2,周绮凤3,郑 理1,2 1. 南京邮电大学计算机学院 南京 210023:2. 美国佛罗里达国际大 ...

  9. 从用户的角度看 c语言中函数有两种,【南开大学】20秋学期(1709、1803、1809、1903、1909、2003、2009 )《C语言程序设计》在线作业答卷...

    20秋学期(1709.1803.1809.1903.1909.2003.2009 )<C语言程序设计>在线作业 试卷总分:100  得分:100 一.单选题 (共 40 道试题,共 80 ...

最新文章

  1. 微信小程序实例开发教程之知乎新闻
  2. Fedora 19配置心得
  3. sobol敏感性分析 matlab代码
  4. oracle 存储过程 输入,Oracle 存储过程加密方法
  5. 官方首次披露,TDSQL十年自主可控之路(附PDF)
  6. 初一七年级计算机信息全册教案,新川教版七年级信息技术全册教案(全册)
  7. SIEM比以往更重要的5个原因
  8. Linux 发展历史
  9. thinkpad解决Win8.1电源管理的方法
  10. 圆柱体积计算机公式,圆柱体积计算公式
  11. TypeError: list indices must be integers or slices, not float
  12. 嵌入式开发培训靠谱吗,嵌入式开发培训怎么样?
  13. python之selenium爬取数据(爬取airbnb房源信息)
  14. 在Python中操作谷歌浏览器
  15. 科研伦理与学术规范期末考试1题库
  16. ddt数据驱动 python接口 xls_013 python接口 数据驱动ddt
  17. c624芯片组的服务器,技嘉另类的服务器主板C422芯片组
  18. python计算长方体体积最简单代码_C语言编程简单的小程序,计算长方体体积!...
  19. Python实现Catboost分类模型(CatBoostClassifier算法)项目实战
  20. 移动端H5常见问题以及解决方案

热门文章

  1. 【LeetCode】860. 柠檬水找零(C语言)
  2. ieee下载文献的方法
  3. 小苹果软件_游戏拼音魔卡动画教学软件使用说明书
  4. 【Python黑科技】tkinter库实战制作一个计算器(保姆级图文+实现代码)
  5. 实时渲染:Tone Mapping 色调映射
  6. JAVA计算两个日期相差天、时、分、秒方法
  7. 如何用计算机打出妈妈我爱你,母亲节快乐!教你用30种语言说“妈妈我爱你”...
  8. 海康网络摄像机如何配置网络硬盘
  9. 知道焊缝长度如何确定节点板尺寸_节点板厚根据什么确定
  10. 影视专家热议新媒体时代如何加强电影新建设