CSAPP第三章家庭作业参考答案

(CSAPP第三版系列)导航篇传送门


3.58写出等价的decode2的C代码。

/*rdi,rsi,rdx*/
long decode2(long x,long y,long z)
{
    y = y - z;
    x = x * y;
    y = (y << 63) >> 63;
    return x ^ y;
}


3.60 

A. x:%rdi  n:%rsi(%cl)  result:%rax  mask:%rdx

B. 初值: result = 0;  mask = 1;

C. mask的测试条件:mask != 0;

D. mask的修改:mask = mask << n;

E. result的修改:result |= x & mask;

F. 填写C代码

long loop(long x,int n)
{
    long result = 0;
    long mask;
    for(mask = 1;mask != 0;mask = mask << n)
        result |= x & mask;
    return result;
}


3.62填写C代码

typedef enum{MODE_A,MODE_B,MODE_C,MODE_D,MODE_E}mode_t;

long switch3(long *p1,long *p2,mode_t action)
{
    long result = 0;
    switch(action)
    {
    case MODE_A:
        result = *p2;
        *p2 = *p1;
        break;
    case MODE_B:
        result = *p1 + *p2;
        *p1 = result;
        break;
    case MODE_C:
        *p1 = 59;
        result = *p2;
        break;
    case MODE_D:
        *p1 = *p2;    //之后落入MODE_E
    case MDOE_E:
        result = 27;
        break;
    defult:
        result = 12;
    }
    return result;
}


3.64

A. 数组A[R][S][T]中数组元素A[i][j][k]的位置的公式。

&A[i][j][k] = Xa +L(i*S*T + j*T + k),其中L是数据类型以字节为单位的大小。

B. 确定R、S和T的值。

由汇编代码,可以得出R*S*T*8 = 3640(条件1)

由汇编代码,A[i][j][k]的位置的公式为A + (65i + 13j + k)*8,对照第一问得出的公式,可以得出T =13  S*T = 65(条件2)

综合条件1,2,可以计算出R = 7  S = 5  T= 13。


3.66  运用逆向工程技术,确定NR和NC的定义

通过分析汇编代码,可以得出该循环的循环次数3*n,每次循环%rcx + %r8,且%r8 = (4*n+1)*8,则有NR(n) = 3*n NC(n) = 4*n+1,

所以宏表达式为:#define NR(n) 3*(n)

                           #defineNC(n) 4*(n)+1


3.68  A和B的值是多少?

依据汇编代码及数据对齐规则:

q->t = 8(%rsi),即str2的t从第8位开始,按照8位对齐sizeof(array[B])小于等于8,且下边的t是int类型占4个字节,所以sizeof(array[B])大于4,可以得到4<B<=8。

q->u = 32(%rsi),即str2的u从第32位开始,则s占20个字节,得sizeof(s[A])<=20,且下边的u是long类型占8个字节,所以sizeof(s[A])大于20-8=12,可以得到6<A<=10。

p->y = 184(%rdi),即str1的y从第184位开始,所以184-8<A*B*4<=184,可以得到44<A*B<=46。

由以上三个约束条件,解得A = 9  B = 5。


3.70

A. 求字段的偏移量:

e1.p  0

e1.y  8

e2.x  0

e2.next  8

B. 这个结构总共需要16个字节。

C. 填写proc代码

只需弄清楚指针指向即可得出该C代码。

void proc(union ele *up)
{
    up->e2.x = *(up->e2.next->e1.p) - up->e2.next->e1.y;
}


3.72

A. 第5行的leaq指令计算值8n+30,然后第6行的andq指令把它向下舍入到最近的16的倍数。当n为奇数时,结果值会是8n+24,当n为偶数时,结果值会是8n+16,s1减去这个值就得到s2。

B. 第8-9行这两条指令将s2向上舍入到最近的16的倍数,利用了偏移和移位的组合,把这个值作为p。

C. 要使e1的值最小,则需使e1+e2最小同时e2最大。当n为偶数时,e1+e2=16最小;当s1%16=1时,e2=15最大。

即:n为偶数,s1%16=1时e1最小。

要使e1的值最大,则需使e1+e2最大同时e2最小。当n为奇数时,e1+e2=24最大;当s1%16=0时,e2=0最小。

即:n为奇数,s1%16=0时e1最大。

D. s2保证空间足够容纳数组p,且是最小的16的倍数。

P以16的倍数对齐。



猜你喜欢

转载自blog.csdn.net/qq512028505/article/details/79128284