从反汇编的角度看C++语法(构造函数)
来源:互联网 发布:数据字典中的条目 编辑:程序博客网 时间:2024/05/01 04:22
从反汇编的角度看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++语法(构造函数)
- 从汇编角度看Linux C函数的调用约定和参数传递的细节
- 从反汇编的角度看引用和指针的区别
- 从反汇编看C++(一)
- 从汇编的角度看段错误
- 从汇编的角度看栈
- 从汇编的角度看递归
- 从内存角度看C函数的调用过程
- 从汇编的角度看inline函数与非inline函数
- 从汇编和底层的角度看c和类c语言
- 从汇编角度看计算机
- 从汇编角度看英特尔x86函数调用规范
- 从汇编角度看C语言类型转换
- 从逆向分析角度看C++拷贝构造函数
- 从汇编看c语言函数调用
- 从汇编看c语言函数调用
- 从编译器的角度看C代码
- 从汇编、内存的角度看类中的this指针 .
- JSP基本注册登录系统(含验证码)
- POJ:1125 Stockbroker Grapevine
- UILabel 详解
- ZOJ:2027 Travelling Fee
- cdm自定义数据类型
- 从反汇编的角度看C++语法(构造函数)
- 三分哥实验室永久的独立地址为 http://www.yaqupjan.com !!! 欢迎访问!
- 类 执行顺序
- 记录
- iphone开发中的一些小技巧
- 开篇
- SQL Server 斐波那契数列
- XML--- 简单的DOM解析XML文件,并实现增,删,查,改的操作
- 递归与循环