20135220谈愈敏-第三章家庭作业

第三章家庭作业

3.66

分值:3分

题目:根据以下代码推测CNT的值和a_struct的完整申明

C程序:

typedef struct {
int left;
a_struct a[CNT];
int right;
}b_struct;

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

反汇编代码:

1 push %ebp
2 mov %esp,%ebp
3 push %ebx
4 mov 0x8(%ebp),%eax
5 mov 0xc(%ebp),%ecx
6 imul $0x1c,%eax,%ebx
7 lea 0x0(,%eax,8)
8 sub %eax,%edx
9 add 0x4(%ecx,%ebx,1),%edx
10 mov 0xc8(%ecx),%eax
11 add (%ecx),%eax
12 mov %eax,0x8(%ecx,%edx,4)
13 pop %ebx
14 pop %ebp
15 ret

中心思想:逆向推断

具体思考过程:为了方便,先用结构体A表示a_struct。

首先,根据第10和11行,可以得到 CNT*size(A) = 196。

根据12行,知道 ecx + 4*edx + 8为 ap->x[ap->idx]的地址。

ecx存储的是bp(地址)。

ap的地址是 bp + 4 + i*size(A)

我们知道,ap->x[0] 的地址是 bp + 4 + i*size(A) + pos(x),pos(x)为结构体A中x的偏移。

那么ap->x[ap->idx] 的地址是 bp + 4 + isize(A) + pos(x) + 4(ap->idx)。

所以 4edx + 8 = 4 + isize(A) + pos(x) + 4*(ap->idx)。

所以,不难猜测,pos(x)=4,也就是说,在A中,首先是idx,再是x数组。

那么,我们看ap->idx在哪里计算过。

到第9行,edx的结果是 7i + bp[4 + 28*i],

bp[4 + 28*i]是什么呢?它很可能是bp中的a[i]的首地址。

我们先这样猜测,于是size(A) = 28,并且bp[4+28*i]的值为ap->idx。

另一方面:4edx = 28i + 4bp[4+28i] = isize(A) + 4(ap->idx)。

所以,我们的猜想是正确的。

因此,size(A) = 28,里面包含了一个int idx和一个数组int x[6]。

总共有多少个A呢?CNT = 196/size(A) = 7。

最终结果:

CNT=7

struct a_struct{

int idx;

int x[6];

}

posted on 2015-10-27 19:35  20135220谈愈敏  阅读(159)  评论(0)    收藏  举报