题目:

 

解析: 

  1. 联合体的所有成员相对于基地址的偏移量都为0;
  2. 此结构空间要大到足够容纳最"宽"的成员
  3. 其对其方式要适合其中所有成员(4字节补齐)


对于2、3两点的解释:

联合体所占的空间不仅取决于最宽成员,还跟所有成员有关系,即其大小必须满足两个条件:1)大小足够容纳最宽的成员;2)大小能被其包含的所有基本数据类型的大小所整除。

具体例子:

	union U1 	{ 		char s[10]; 		int n; 		double d; 		};

s占10字节,n占4字节,d占8字节,因此其至少需10字节的空间。然而其实际大小并不是10,用运算符sizeof测试其大小为16.这是因为这里存在字节对齐的问题,10既不能被4整除,也不能被8整除。因此补充字节到16,这样就符合所有成员的自身对齐了。

 

 答案

A:

根据联合体的所有成员相对于基地址的偏移量都为0这一点,加上int占有4个字节,而地址(*next)也占有四个字节,即可做出此题。

e1.p:0

e1.x:4

e2.y:0

e2.next:4

B:

根据联合体的字节补齐和其满足的两个条件即可做出此题。

e1中int *p --4字节 int x---4字节 和为8字节

e2中int y --4字节 union ele *next --4字节 和为8字节

因为两个结构体所占有的字节大小均为8且符合字节补齐规则,所以该联合体结构总共需要8个字节。

C:

在做此题前先明确该联合体中,需要先访问成员才可以访问成员中的变量这一点,即你要获取x,必须要先获得e1,而后进入e1结构体访问x,最终形成e1.x。

1.很明显的movl 8(%ebp),%edx 此语句作用为get up at %edx

2.试着按顺序写出语句,但发现并不能确定每一个语句准确表示的是什么,所以就观察其中有特点的语句进行分析。

3.发现语句中subl (%edx), %eax表示为%eax = eax - (%edx),(%edx)为整数,并且%edx保存的是up,满足条件且偏移量为0的情况只有e2.y即,减数为up->e2.y。同时可得被减数存储在%eax中。

4.题目中有*(up->__)表示一个整数这个信息,再对应联合体结构中仅有int *p满足该条件,并且在汇编代码中,由上一步可知被减数存储在%eax中,可知movl (%eax), %eax是对被减数赋值的语句,可得在此语句之前%eax为地址,并且应该为up->e1.p,即被减数应该为up->e1.p。

5.但再往上看发现第三行的%eax是由(%ecx)获得,并且%ecx由4(%edx)获得,但%edx指向了up->e2.y,所以被减数应该是有4的偏移量,明显的%ecx应该为up->e2.next,对应的%eax为up->e2.next->e1.p。

6.最终只剩下得数的表示了,明显对应的是movl %eax,4(%ecx)这条语句,%ecx为up->e2.next,%ecx+4应该为up->e2.next->e1.x,即得数为up->e2.next->e1.x。

最终的结果:

up->e2.next->e1.x = *(up->e2.next->e1.p) - up->e2.y