首页
学习
活动
专区
圈层
工具
发布
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.7节C风格数据结构内存布局之结构体数组

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

在探究过数组和结构体这两种非原生的数据类型之后,可能会想知道这两种类型结合成结构体数组,会有什么特征。

先看一个例子:

代码语言:javascript
复制
  #include <stdlib.h>
  struct xuzhina_dump_c05_s3_3
  {
      short idx;
      int sq;
  };
  
  void init( struct xuzhina_dump_c05_s3_3* test, int n )
 {
     for ( int i = 0; i < n; i++ )
     {
         test[i].idx = i;
         test[i].sq = i*i;
     }
 }
 
 int sum( struct xuzhina_dump_c05_s3_3* test, int n )
 {
     int sum = 0;
     for ( int i = 0; i < n; i++ )
     {
         sum += test[i].sq;
     }
     return sum;
 }
 
 int main(int argc, char* argv[] )
 {
     if ( argc < 2 )
     {
         return 1;
     }

     int num = atoi( argv[1] );

     struct xuzhina_dump_c05_s3_3* test =
         (struct xuzhina_dump_c05_s3_3*)malloc( num * sizeof( struct xuzhina_dump_c05_s3_3 ) );
 
     init( test, num );
 
     return sum( test, num );
 }

汇编(只看init和sum即可)

代码语言:javascript
复制
(gdb) disassemble init
Dump of assembler code for function _Z4initP21xuzhina_dump_c05_s3_3i:
   0x080484d0 <+0>:     push   %ebp
   0x080484d1 <+1>:     mov    %esp,%ebp
   0x080484d3 <+3>:     sub    $0x10,%esp
   0x080484d6 <+6>:     movl   $0x0,-0x4(%ebp)		;i
   0x080484dd <+13>:    jmp    0x8048511 <_Z4initP21xuzhina_dump_c05_s3_3i+65>

   0x080484df <+15>:    mov    -0x4(%ebp),%eax
   0x080484e2 <+18>:    lea    0x0(,%eax,8),%edx		;edx = i*8
   0x080484e9 <+25>:    mov    0x8(%ebp),%eax		;eax = test
   0x080484ec <+28>:    add    %eax,%edx				;edx = test[i]
   0x080484ee <+30>:    mov    -0x4(%ebp),%eax		;i
   0x080484f1 <+33>:    mov    %ax,(%edx)			;test[i].idx = i
   0x080484f4 <+36>:    mov    -0x4(%ebp),%eax		;i
   0x080484f7 <+39>:    lea    0x0(,%eax,8),%edx		;edx = i*8
   0x080484fe <+46>:    mov    0x8(%ebp),%eax		;eax = test
   0x08048501 <+49>:    add    %eax,%edx				;edx = test[i]
   0x08048503 <+51>:    mov    -0x4(%ebp),%eax		;eax = i
   0x08048506 <+54>:    imul   -0x4(%ebp),%eax		;eax *= i
   0x0804850a <+58>:    mov    %eax,0x4(%edx)		;test[i].sq = eax
   0x0804850d <+61>:    addl   $0x1,-0x4(%ebp)			;i++
   0x08048511 <+65>:    mov    -0x4(%ebp),%eax
   0x08048514 <+68>:    cmp    0xc(%ebp),%eax
   0x08048517 <+71>:    setl   %al
   0x0804851a <+74>:    test   %al,%al
   0x0804851c <+76>:    jne    0x80484df <_Z4initP21xuzhina_dump_c05_s3_3i+15>

   0x0804851e <+78>:    leave  
   0x0804851f <+79>:    ret    
End of assembler dump.

(gdb) disassemble sum
Dump of assembler code for function _Z3sumP21xuzhina_dump_c05_s3_3i:
   0x08048520 <+0>:     push   %ebp
   0x08048521 <+1>:     mov    %esp,%ebp
   0x08048523 <+3>:     sub    $0x10,%esp
   0x08048526 <+6>:     movl   $0x0,-0x4(%ebp)		;sum
   0x0804852d <+13>:    movl   $0x0,-0x8(%ebp)		;i
   0x08048534 <+20>:    jmp    0x804854f <_Z3sumP21xuzhina_dump_c05_s3_3i+47>

   0x08048536 <+22>:    mov    -0x8(%ebp),%eax		;i
   0x08048539 <+25>:    lea    0x0(,%eax,8),%edx
   0x08048540 <+32>:    mov    0x8(%ebp),%eax		;test
   0x08048543 <+35>:    add    %edx,%eax
   0x08048545 <+37>:    mov    0x4(%eax),%eax		;test[i].sq
   0x08048548 <+40>:    add    %eax,-0x4(%ebp)
   0x0804854b <+43>:    addl   $0x1,-0x8(%ebp)			;i++
   0x0804854f <+47>:    mov    -0x8(%ebp),%eax
   0x08048552 <+50>:    cmp    0xc(%ebp),%eax		;i < n 
   0x08048555 <+53>:    setl   %al
   0x08048558 <+56>:    test   %al,%al
   0x0804855a <+58>:    jne    0x8048536 <_Z3sumP21xuzhina_dump_c05_s3_3i+22>

   0x0804855c <+60>:    mov    -0x4(%ebp),%eax
   0x0804855f <+63>:    leave  
   0x08048560 <+64>:    ret    
End of assembler dump.

从上面的汇编,结构体数组的特征如下:

1.        先是找到数组的首地址

2.        再根据索引找到每个元素,得到每个元素的地址。

3.        再以每个元素的地址作为结构体基址,再获取成员变量的地址。

下一篇
举报
领券