首页
学习
活动
专区
圈层
工具
发布
21 篇文章
1
《coredump问题原理探究》Linux x86版6.3节有成员变量的类coredump例子
2
《coredump问题原理探究》Linux x86版6.5节虚函数的coredump例子
3
《coredump问题原理探究》Linux x86版6.8节多继承coredump例子
4
《coredump问题原理探究》Linux x86版7.2节vector coredump例子
5
《coredump问题原理探究》Linux x86版7.4节List coredump例子
6
《coredump问题原理探究》Linux x86版7.6节 Map coredump例子
7
《coredump问题原理探究》Linux x86版5.9节C风格数据结构内存布局之联合体
8
《coredump问题原理探究》Linux x86版6.1节C++风格数据结构内存布局之无成员变量的类
9
《coredump问题原理探究》Linux x86版6.2节C++风格数据结构内存布局之有成员变量的类
10
《coredump问题原理探究》Linux x86版4.5节函数的逆向之coredump例子
11
《coredump问题原理探究》Linux x86版5.1节C风格数据结构内存布局之引言
12
《coredump问题原理探究》Linux x86版5.2节C风格数据结构内存布局之基本数据类型
13
《coredump问题原理探究》Linux x86版5.3节C风格数据结构内存布局之数组
14
《coredump问题原理探究》Linux x86版5.4节C风格数据结构内存布局之数组coredump例子
15
《coredump问题原理探究》Linux x86版5.5节C风格数据结构内存布局之基本数据类型构成的结构体
16
《coredump问题原理探究》Linux x86版5.6节C风格数据结构内存布局之复合类型构成的结构体
17
《coredump问题原理探究》Linux x86版5.7节C风格数据结构内存布局之结构体数组
18
《coredump问题原理探究》Linux x86版5.8节C风格数据结构内存布局之结构体数组结构体coredump
19
《coredump问题原理探究》Linux x86版3.5节栈布局之-fomit-frame-pointer编译选项
20
《coredump问题原理探究》Linux x86版3.6节栈布局之gcc内嵌关键字
21
《coredump问题原理探究》Linux x86版3.8节栈布局之栈溢出coredump例子

《coredump问题原理探究》Linux x86版5.9节C风格数据结构内存布局之联合体

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://cloud.tencent.com/developer/article/1344521

在C语言中,联合体(union)有点像结构体那样,把不同类型的数据组织起来,但和结构体不大一样,在结构体各成员有各自的内存空间,一个结构体对象的总长度是各成员长度之和。而在联合体中,各成员共享一段内存空间,一个联合体对象的长度等于各成员中最长的长度。

由上面描述可知,联合体应该具备多面性,即在汇编层面上,有时候会显示结构体的特征,或数组特征,或其它基本数据类型特征。

先看一下例子:

代码语言:javascript
复制
1	 #include <stdio.h>
  2	 union xuzhina_dump_c05_s4
  3	 {
  4	     int i;
  5	     char hello[4];
  6	 };
  7 
  8	 int main()
  9	 {
 10	     union xuzhina_dump_c05_s4 test;
 11	     test.i = 0x656463;
 12	     for ( int i = 0; i < 4; i++ )
 13	     {
 14	         printf( "%c", test.hello[i] );
 15	     }
 16	 
 17	     printf( "\n" );
 18	     return 0;
 19	 }

汇编代码:

代码语言:javascript
复制
(gdb) disassemble main
Dump of assembler code for function main:
   0x08048570 <+0>:     push   %ebp
   0x08048571 <+1>:     mov    %esp,%ebp
   0x08048573 <+3>:     and    $0xfffffff0,%esp
   0x08048576 <+6>:     sub    $0x20,%esp
   0x08048579 <+9>:     movl   $0x656463,0x18(%esp)
   0x08048581 <+17>:    movl   $0x0,0x1c(%esp)
   0x08048589 <+25>:    jmp    0x80485a8 <main+56>
   0x0804858b <+27>:    lea    0x18(%esp),%edx
   0x0804858f <+31>:    mov    0x1c(%esp),%eax
   0x08048593 <+35>:    add    %edx,%eax
   0x08048595 <+37>:    movzbl (%eax),%eax
   0x08048598 <+40>:    movsbl %al,%eax
   0x0804859b <+43>:    mov    %eax,(%esp)
   0x0804859e <+46>:    call   0x8048430 <putchar@plt>
   0x080485a3 <+51>:    addl   $0x1,0x1c(%esp)
   0x080485a8 <+56>:    cmpl   $0x3,0x1c(%esp)
   0x080485ad <+61>:    setle  %al
   0x080485b0 <+64>:    test   %al,%al
   0x080485b2 <+66>:    jne    0x804858b <main+27>
   0x080485b4 <+68>:    movl   $0xa,(%esp)
   0x080485bb <+75>:    call   0x8048430 <putchar@plt>
   0x080485c0 <+80>:    mov    $0x0,%eax
   0x080485c5 <+85>:    jmp    0x80485cf <main+95>
   0x080485c7 <+87>:    mov    %eax,(%esp)
   0x080485ca <+90>:    call   0x8048460 <_Unwind_Resume@plt>
   0x080485cf <+95>:    leave  
   0x080485d0 <+96>:    ret    
End of assembler dump.

从上面汇编代码来看,unionxuzhina_dump_c05_s4确实以int和char数组进行访问。见下面这两组指令

代码语言:javascript
复制
   0x08048579 <+9>:     movl   $0x656463,0x18(%esp)

   0x0804858b <+27>:    lea    0x18(%esp),%edx
   0x0804858f <+31>:    mov    0x1c(%esp),%eax
   0x08048593 <+35>:    add    %edx,%eax
   0x08048595 <+37>:    movzbl (%eax),%eax

由上面的探讨,union成员类型最好避免是指针类型。因为指针容易被覆盖,会发生“Accessviolation”的错误。假设指针是函数指针,则会出现上一节的coredump。

下一篇
举报
领券