【汇编】C++ 结构体实现

C语言允许用户自己指定这样一种数据结构,它由不同类型的数据组合成一个整体,以便引用,这些组合在一个整体中的数据是互相联系的,这样的数据结构称为结构体。
C++结构体中可以使用函数,有下面的测试代码:

int main(int argc,char *argv[])
{
	struct MyStruct
	{
		char *name;
		int income;
		int expenses;
		int profit(){
			return income-expenses;
		}
	};
	MyStruct person;
	person.name="Mike";
	person.income=3600;
	person.expenses=1200;

	int x=person.profit();

	return 0;
}
有一个名为MyStruct的结构体,有三个数据成员,有一个函数成员,下面声明一个这样的结构体变量,对其进行赋值,然后调用函数取得返回值。

对应汇编代码如下:

struct MyStruct
	{
		char *name;
		int income;
		int expenses;
		int profit(){
			return income-expenses;
		}
	};
//可以看到上面的声明中并没有编译出任何汇编码,包括函数,只是告诉编译器有这么一个数据结构
	MyStruct person;
	person.name="Mike";
00E43A58  mov         dword ptr [ebp-14h],0E458A8h  
//将字符串"Mike"的首地址放进第一个成员char*name指针,这个地址在内存中的表现见下图
//通过查看&person和&name可以发现是同一个位置,
	person.income=3600;
00E43A5F  mov         dword ptr [ebp-10h],0E10h  
//这里是第二个成员的赋值
	person.expenses=1200;
00E43A66  mov         dword ptr [ebp-0Ch],4B0h  
//第三个赋值
	int x=person.profit();
//第四个调用函数
00E43A6D  lea         ecx,[ebp-14h]  
00E43A70  call        00E433B0  
00E43A75  mov         dword ptr [ebp-20h],eax  
//可以看到先是把这个结构的首地址放进ecx,由于无参数所以没有压栈操作
//函数计算结果同样是放在了eax中
字符串"Mike"(0E458A8h):

注意这个Mike周围还有许多英文单词,而且每个字母之间都是00隔开的,这就是所谓的宽字符WCHAR,在Windows编程中常常看到。

再来看看结构体里面的函数编译到哪里去了?

struct MyStruct
	{
		char *name;
		int income;
		int expenses;
		int profit(){
//作为函数同样是要分配栈空间
00E433B0  push        ebp  
00E433B1  mov         ebp,esp  
00E433B3  sub         esp,0CCh  
00E433B9  push        ebx  
00E433BA  push        esi  
00E433BB  push        edi  
00E433BC  push        ecx  //由于下面必须要用ecx,这里先压入栈内保存
00E433BD  lea         edi,[ebp+FFFFFF34h]  
00E433C3  mov         ecx,33h  
00E433C8  mov         eax,0CCCCCCCCh  
00E433CD  rep stos    dword ptr es:[edi]  
00E433CF  pop         ecx  //这里恢复出来
00E433D0  mov         dword ptr [ebp-8],ecx  
//把传进来的该结构体地址(相当于this指针)放进栈
			return income-expenses;
00E433D3  mov         eax,dword ptr [ebp-8]  
00E433D6  mov         ecx,dword ptr [ebp-8]  
//把this放进eax和ecx,因为下面要用它来寻址
00E433D9  mov         eax,dword ptr [eax+4]  
00E433DC  sub         eax,dword ptr [ecx+8]  
//[this+4]就是变量income,[this+8]就是变量expenses,这里用[eax+8]应该也可以
//作差后返回
		}
00E433DF  pop         edi  
00E433E0  pop         esi  
00E433E1  pop         ebx  
00E433E2  mov         esp,ebp  
00E433E4  pop         ebp  
00E433E5  ret
小结:结构体最关键的还是首地址,或者叫做结构体的this指针,用它可以访问结构体中的每个成员,是通过[this+偏移]来实现的,这个偏移不同所访问到的成员就不同,偏移具体是多少是在编译期分析成员类型决定的。


转载于:https://my.oschina.net/ybusad/blog/147994

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值