C语言提供的联合语法,可以使得多种数据类型的数据共享同一块内存地址。
示例1:
unsigned float2bit(float f)
{
union {
float f;
unsigned u;
}temp;
temp.f = f;
return temp.u;
};
gcc -O1 -S -m32 union1.c
float2bit:
pushl %ebp
movl %esp, %ebp
movl 8(%ebp), %eax
popl %ebp
ret
生成的汇编代码相当简单,就是把传入参数作为返回值来返回,float类型和无符号整数的大小相同,都是四个字节,所以可以这样做。
示例2:
double bit2double(unsigned word0, unsigned word1)
{
union {
doubled;
unsigned u[2];
}temp;
temp.u[0] = word0;
temp.u[1] = word1;
return temp.d;
}
gcc -O1 -S -m32 union2.c
bit2double:
pushl %ebp
movl %esp, %ebp
subl $8, %esp //esp下移8个字节,给temp变量分配8字节的空间
movl 8(%ebp), %eax //eax = word0
movl 12(%ebp), %edx //edx =word1
movl %eax, -8(%ebp) // temp.u[0]= word0
movl %edx, -4(%ebp) // temp.u[1]= word1
fldl -8(%ebp) //把temp.d值保存到x87 FPU浮点寄存器中
leave //清理栈
ret
双精度数不能直接保存到eax中,需要通过fldl指令把数据保存到x87 FPU浮点寄存器中,然后调用者从浮点寄存器中取出数据。
示例3:
union ele {
struct {
int *p;
int y;
}e1;
struct {
int x;
union ele *next;
}e2;
};
void proc (union ele *up)
{
up->e2.next->e1.y = *(up->e2.next->e1.p) - up->e2.x;
}
gcc -O1 -S -m32 union3.c
proc:
pushl %ebp
movl %esp, %ebp
movl 8(%ebp), %edx //edx = up
movl 4(%edx), %ecx //ecx =up-> e2.next
movl (%ecx), %eax //eax = up->e2.next->e1.p
movl (%eax), %eax //eax = *( up->e2.next->e1.p)
subl (%edx), %eax //eax = *( up->e2.next->e1.p) – up->e2.x
movl %eax, 4(%ecx) // up-> e2.next->e1.y =*( up-> e2.next->e1.p) – up->e2.x
popl %ebp
ret