/*
* 3.69.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;
}
# void test(long i, b_struct *bp)
# i in %rdi, bp in %rsi
test:
mov 0x120(%rsi), %ecx # bp+0x120 fetch bp->last
add (%rsi), %ecx # bp->first + bp->last
lea (%rdi,%rdi,4), %rax # i*5
lea (%rsi,%rax,8), %rax # bp+i*40
# ap = &bp->a[i] = bp+i*40+8, +8 means skip int first
# so a_struct is aligned by 8, size is 40
# check last instrction, %rdx here saves value ap->idx!!!
# so in a_struct, idx is first element
mov 0x8(%rax), %rdx
movslq %ecx, %rcx # n = bp->first + bp->last, convert to long
# save n to address 8*(ap->idx) + bp+i*40+0x8 + 0x8 (0x10)
# bp+i*40+0x8 means ap
# ap + 0x8 means &(ap->x)
# ap + 0x8 + 8*(ap->idx) means &(ap-x[ap->idx])
# second element of a_struct is x, x is an array of long
# 8*(ap->idx) means idx is also long type
mov %rcx, 0x10(%rax,%rdx,8)
# size of a_struct is 40 and aligned by 8
# so array x has 4 long elements
# finally, a_struct is
# typedef struct {
# long idx,
# long x[4]
# } a_struct
retq
A.
7*40 + 8 = 288 = 0x120
, so
CNT = 7
thanks https://github.com/zagortenay333
B.
typedef struct {
long idx,
long x[4]
} a_struct