C++类对象调用时的汇编表示

C代码

Class.h

class Creature
{
    
    
	public:
		int hp;
		int mp;
		char* name;
		void Attack();
		void Defend();
		void Dead();
		Creature(char* name);
};

class Player:public Creature
{
    
    
public:
	int nSmart;
	int nPower;
	void Buy();
	Player(char* name);
};

Class.cpp

void Creature::Attack()
{
    
    
	printf("I am Attacking...\n");
}
void Creature::Defend()
{
    
    
	printf("I am Defending...\n");
}
void Creature::Dead()
{
    
    
	printf("I am Dead.\n");
}
Creature::Creature(char* name)
{
    
    
	this->name = name;
	hp = 100;
	mp = 50;
}
void Player::Buy()
{
    
    
	printf("I am Buying.\n");
}
Player::Player(char *name):Creature(name)
{
    
    
	nSmart = 10;
	nPower = 7;
	printf("hp=%d,mp=%d,nSmart=%d,nPower=%d\n", hp, mp, nSmart, nPower);
}

main.cpp

int main()
{
    
    
	Player p((char*)"sanqiu");	
	p.Buy();
	p.Attack();
	getchar();

}

main汇编

push ebp
mov ebp,esp
sub esp,54
push ebx
push esi
push edi
push x86test.5D5BA8
lea ecx,dword ptr ss:[ebp-14]
call x86test.5D12BC				//Player()
lea ecx,dword ptr ss:[ebp-14]
call x86test.5D12E4				//Buy()
lea ecx,dword ptr ss:[ebp-14]
call x86test.5D1131				//attack()
call dword ptr ds:[<&getchar>]
xor eax,eax
pop edi
pop esi
pop ebx
mov esp,ebp
pop ebp
ret 

Player构造函数

push ebp
mov ebp,esp
sub esp,44
push ebx
push esi
push edi
mov dword ptr ss:[ebp-4],ecx	//Player对象指针当作第一个局部变量暂存
mov eax,dword ptr ss:[ebp+8]	//传入参数"sanqiu"
push eax
mov ecx,dword ptr ss:[ebp-4]	//传入Player对象指针
call x86test.5D10F0				//调用父类(Creature)的构造函数
mov eax,dword ptr ss:[ebp-4]
mov dword ptr ds:[eax+C],A		/Player.nSmart=10;
mov eax,dword ptr ss:[ebp-4]
mov dword ptr ds:[eax+10],7		//Player.nPower=7;
mov eax,dword ptr ss:[ebp-4]
mov ecx,dword ptr ds:[eax+10]	//接下来就开始printf了
push ecx
mov edx,dword ptr ss:[ebp-4]
mov eax,dword ptr ds:[edx+C]
push eax
mov ecx,dword ptr ss:[ebp-4]
mov edx,dword ptr ds:[ecx+4]
push edx
mov eax,dword ptr ss:[ebp-4]
mov ecx,dword ptr ds:[eax]
push ecx
push x86test.5D5B80
call x86test.5D10AA
add esp,14
mov eax,dword ptr ss:[ebp-4]
pop edi
pop esi
pop ebx
mov esp,ebp
pop ebp
ret 4

Player内部函数Buy

push ebp
mov ebp,esp
sub esp,44
push ebx
push esi
push edi
mov dword ptr ss:[ebp-4],ecx	//暂存Player对象指针
push x86test.5D5B70
call x86test.5D10AA				//printf
add esp,4
pop edi
pop esi
pop ebx
mov esp,ebp
pop ebp
ret 

Player父类函数Attack

push ebp
mov ebp,esp
sub esp,44
push ebx
push esi
push edi
mov dword ptr ss:[ebp-4],ecx //暂存Player对象指针
push x86test.5D5B30
call x86test.5D10AA			//printf
add esp,4
pop edi
pop esi
pop ebx
mov esp,ebp
pop ebp
ret 

Player父类的构造函数

push ebp
mov ebp,esp
sub esp,44
push ebx
push esi
push edi
mov dword ptr ss:[ebp-4],ecx	//Player对象指针
mov eax,dword ptr ss:[ebp-4]
mov ecx,dword ptr ss:[ebp+8]	
mov dword ptr ds:[eax+8],ecx	//Playe.name = "sanqiu"
mov eax,dword ptr ss:[ebp-4]
mov dword ptr ds:[eax],64		//Player.hp = 100
mov eax,dword ptr ss:[ebp-4]
mov dword ptr ds:[eax+4],32		//Player.mp = 50;
mov eax,dword ptr ss:[ebp-4]
pop edi
pop esi
pop ebx
mov esp,ebp
pop ebp
ret 4

总结
1.调用父类的函数跟调用子类自己的函数的操作完全相同
2.和C不同的是,在使用类的函数时,总会传一个类对象指针到ecx当中去,
并在函数内部并作为第一局部变量暂存
3.继承,相当于struct(父类的变量+自己的变量),省略了代码的编写,但其实没有减少内存开销
4.构造函数和没有返回值的普通函数没什么区别,唯一的区别是,构造函数属于回调函数

猜你喜欢

转载自blog.csdn.net/sanqiuai/article/details/124525875