3.69
Solution
Let's annotate the assembly code
void test(long i, b_struct *bp)
i in %rdi, bp in %rsi
0000000000000000 <test>:
0: 8b 8e 20 01 00 00 mov 0x120(%rsi),%ecx # fetch bp->last
6: 030e add (%rsi),%ecx # bp->last + bp->first
8: 48 8d 04 bf lea (%rdi,%rdi,4),%rax # 5i
c: 48 8d 04 c6 lea (%rsi,%rax,8),%rax # %rax <- bp + 40i
10: 48 8b 50 08 mov 0x8(%rax),%rdx # %rdx <- M[bp + 40i + 8]
14: 48 63 c9 movslq %ecx,%rcx # sign-extend %ecx
17: 48 89 4c d0 10 mov %rcx,0x10(%rax,%rdx,8) # M[bp + 40i + 16 + %rdx*8] <- %rcx
1c: c3 retq
bp->last
has an offset of 288 \(\implies\)sizeof(int) + padding + sizeof(a_struct) * CNT
is 288.ap
=bp + 8 + 40i
%rdx
storesap->idx
A.
In b_struct
, first
comes before the array a[CNT]
, and as we can see from the way ap
is gotten,
there is an extra offset of 8 apart from the offset caused by preceding elements in a
.
These 8 bits include int first
, and a padding of 4 bytes after that.
From the first point, we see 4 + 4 + 40 * CNT = 288
\(\implies\) CNT = 7
.
B.
In the final mov
instruction, bp + 40i + 16 + %rdx * 8
can be written as
ap + 8 + idx * 8
.
We can conclude from this that in a_struct
, the first 8 bits are occupied by idx
, and the later
bits are occupied by an array with elements of size 8
, i.e. of type long
.
Because the size of a_struct
is 40 (from its array in b_struct
), \(8 + 8 * len(x) = 40\).
We obtain that length of array x is 4.
typedef struct {
long idx;
long x[4];
};