---
description: ★★★
---

# 3.69 Struct

You are charged with maintaining a large C program, and you come across the following code:

```c
typedef struct {
    int first;
    a_struct a[CNT];
    int last;
} b_struct;

void test(long i, b_struct *bp) {
    int n = bp->first + bp->last;
    a_struct *ap = &bp->a[i];
    ap->x[ap->idx] = n;
}
```

The declarations of the compile-time constant `CNT` and the structure `a_struct` are in a file for which you do not have the necessary access privilege. Fortunately, you have a copy of the `.o` version of code, which you are able to disassemble with the OBJDUMP program, yielding the following disassembly:

```
0000000000000000 <test>:
    0: 8b 8e 20 01 00 00     mov 0x120(%rsi),%ecx
    6: 03 0e                 add (%rsi),%ecx
    8: 48 8d 04 bf             lea (%rdi,%rdi,4),%rax
    c: 48 8d 04 c6             lea (%rsi,%rax,8),%rax
   10: 48 8b 50 08             mov 0x8(%rax),%rdx
   14: 48 63 c9             movslq %ecx,%rcx
   17: 48 89 4c d0 10         mov %rcx,0x10(%rax,%rdx,8)
   1c: c3                     retq
```

Using your reverse engineering skills, deduce the following:

A. The value of `CNT`.

The offset of `last` in `b_struct` is 288, and in line 10, we retrive `*(bp+8+40*i)` to %rdx, so `a_struct` is align 8, and we know:

$$
272\lt 8+L\cdot CNT\le 288
$$

and L=40, so CNT=7.

B. A complete declaration of struture `a_struct`. Assume that the only fields in this structure are `idx` and `x`, and that both of these contain signed values.

Line 7 converts %ecx to %rcx, convert n to long. And save n to 16+%rax+8\*%rdx, %rax is bp+40i, and %rdx is bp+40i+8, so `idx` has type of long, and is the first field of `a_struct`. The type of x is also long, and has 4 elements.

```c
typedef struct {
    long idx;
    long x[4];
} a_struct;
```
