2.61 A. !(~x) B. !x C. !((x & 0xFF) ^ 0xFF) D. !(x >> ((sizeof(int) - 1) << 3))
2.62 int int_shifts_are_arithmetic() { return(-1 >> 1) == -1; }
2.65 int odd_ones(unsigned x) { x = x ^ (x >> 16); x = x ^ (x >> 8); x = x ^ (x >> 4); x = x ^ (x >> 2); x = x ^ (x >> 1); return x & 1; }
=======
第一题:正确
第二题:正确
第三题:正确
2.88 208, 01110, 1010 -7/1024, 1 0000 0111, -7/1024 5/131072, 0 0000 0000, 0 -4096, 1 1111 0000, -inf 768, 0 1111 0000, inf
2.92 float_bits float_neganate(float_bits f){ if((f & 0x7f800000) == 0x7f800000 && (0x7ffff & f)) return f; else return f ^ 0x80000000; }
2.96 int float_f2i(float_bits f){ int sign = f >> 31; int exp = f & 0x7f800000; int frac = f & 0x7fffff; int e = exp - 127; if(e < 0) return 0; if(e > 30) return 0x80000000; if(e > 23) return (frac | 0x800000) << (e - 23); return (frac | 0x800000) >> (23 - e); }
第一题:有1个错误
第二题:正确
第三题:正确
3.60 A x rdi n esi result rax mask rdx B result 0 mask 1 C M != 0 D mask << n E result = (x & mask) | result F long result = 0; for(mask = 1; mask != 0; mask = mask << n) result |= (x & mask);
3.62 case MODE_A: {result = *p2; action = *p1; *p2 = action; break;} case MODE_B: {result = *p1; result = result + *p2; *p1 = result; break;} case MODE_C: {*p1 = 59; result = *p2; break;} case MODE_D: {result = *p2; *p1 = result; result = 27; break;} case MODE_E: {result = 27; break;} default: {result = 12;}
3.64 A &A[i][j][k] = A + (65 * i + 13 * j + k) B
第一题:正确
第二题:有点小问题
第三题:有误
3.68 A的取值可能有10,9,8,7, B的取值可能有8,7,6,5, A * B的取值可能有46,45, 所以 A = 9,B = 5 。
3.69 A. CNT = 7; B. typedef struct { long idx; long x[7]; }a_struct;
3.70 A. 0 8 0 8 B. 16 C. up -> e2 -> x = *(up -> e2 -> next -> p) - up -> e2 -> next -> y;
第一题:正确
第二题:有误
第三题:正确
4.47 A void bubble_a(long *data, long count){ long i, last; for(last = count - 1; last > 0; last--){ for(i = 0; i < last; i++){ if(data[i + 1] < data[i]){ long t = *(data + i + 1); *(data + i + 1) = *(data + i); *(data + i) = t; } } } } B #void bubble_a(long *data, long count) bubble_a: irmovq $1, %r8 rrmovq %rsi, %r9 irmovq $8, %r10 irmovq %rdi, %11 test: addq %rax, %r9 xorq %rax, %rax #i = 0 subq %r8, %r9 #last = count - 1 jle done loop1: subq %rax, %r9 jle test mrmovq (%r11), %r12 mrmovq 8(%r11), %r13 subq %r13, %r12 jle loop1 mrmovq (%r11), %r12 rmmovq %r13, (%r11) rmmovq %r12, 8(%r11) addq %r8, %rax jmp loop1 done: ret
4.56 #Predict next value of PC int f_predPC = [ # BBTFNT: This is where you'll change the branch prediction rule f_icode in { ICALL } : f_valC; f_icode in { IJXX } && ( f_ifun == 0 || f_valC < f_valP ) : f_valC; 1 : f_valP; ];
5.13 A 
 关键路径:%xmm0->add->%xmm0 B 3.00 C 1.00 D 两次连续的迭代之间,对sum的更新只需要一个浮点加法
5.14 A 两次从内存读取数据有消耗 B 关键路径中只有一次浮点加法,不会因循环展开而消除
第一题:Y86有点小问题
第二题:有误
第三题:正确
第四题:代码呢??
7.6 buf 是 外部 main.o .data bufp0 是 全局 swap.o .data bufp1 是 局部 swap.o .bss swap 是 全局 swap.o .text temp 否 / / / incr 是 局部 swap.o .text count 是 局部 swap.o .bss
7.7 /* bar5.c */ static double x; void f(){ x = -0.0; }
7.12 A. addr(s) = addr(.test) = 0x4004e0 addr(r.symbol) = addr(swap) = 0x4004f8 refaddr = addr(s) + r.offset = 0x4004ea *refptr = (unsigned)(addr(r.symbol) + r.addend - refaddr) = 0x4004f8 - 0x4 - 0x4004ea = 0xa B. addr(s) = addr(.test) = 0x4004d0 addr(r.symbol) = addr(swap) = 0x400500 refaddr = addr(s) + r.offset = 0x4004da *refptr = (unsigned)(addr(r.symbol) + r.addend - refaddr) = 0x400500 - 0x4 - 0x4004da = 0x22
7.13 A. 1579 471 zxm@ubuntu:/usr/lib/x86_64-linux-gnu$ ar -t libc.a | wc -l 1579 zxm@ubuntu:/usr/lib/x86_64-linux-gnu$ ar -t libm.a | wc -l 471 B. 以-g选项调用编译器驱动程序,会得到.debug、.line。 C. zxm@ubuntu:/usr/bin$ ldd gcc linux-vdso.so.1 => (0x00007ffe1a778000) libc.so.6 => /lib/x86_64-linux-gnu/libc.so.6 (0x00007f01b14f0000) /lib64/ld-linux-x86-64.so.2 (0x00005564e701f000)
第一题:有一处错误
第二题:正确
第三题:正确
第四题:正确
8.9 f t t t t t
8.18 ACE
8.24
int main(){ int status, i; pid_t pid; char err[128];
for(i = 0; i < N; ++i)
if((pid = Fork()) == 0)
exit(100 + i);
while((pid = waitpid(-1, &status, 0)) > 0){
if(WIFEXITED(status))
printf("child %d terminated normally with exit status=%d\n", pid, WEXITSTATUS(status));
else if(WIFSIGNALED(status)){
printf("child %d terminated by signal %d: ", pid, WTERMSIG(status));
psignal(WTERMSIG(status), err);
}
}
if(errno != ECHILD)
unix_error("waitpid error");
exit(0);
}
10.6 fd2 = 4
10.9 int fd = open("foo.txt", O_RDONLY, 0); dup2(fd, 1); close(fd);
第一题:正确
第二题:正确
第三题:错误
第四题:正确
第五题:有误
#include <stdio.h> #include <unistd.h> #include <math.h> #include "csapp.h" pid_t pid; void *s; void *e; long vpn; jmp_buf buf; long pagesize; long vposize; long i; char filename[60]; FILE *fin; char ch; void *j;
void sigsegv_handler(int sig){ siglongjmp(buf, 1); }
int main(int argc, const char * argv[]) { pid = getpid(); pagesize = sysconf(_SC_PAGESIZE); sprintf(filename, "/proc/%d/maps", pid); fin = fopen(filename, "r");
for(i = pagesize, vposize = 0; i != 1; i = i >> 1)
++vposize;
signal(SIGSEGV, sigsegv_handler);
while(fscanf(fin, "%p-%p", &s, &e)){
while((ch = fgetc(fin)) != '\n');
for(j = s; j <= e; j += pagesize){
if(!sigsetjmp(buf, 1))
printf("%lx\n", (long)j >> vposize);
}
} return 0; }
11.8 在serve_dynamic函数中 定义变量后添加一行 signal(SIGCHLD, sigchld_handler); 删除Wait(NULL); 此外添加SIGCHLD处理函数 void sigchld_handler(int sig){ while(waitpid(-1, NULL, WNOHANG) > 0); return; }
11.9 void serve_static(int fd, char *filename, int filesize){ int srcfd; char *srcp, filetype[MAXLINE], buf[MAXBUF];
get_filetype(filename, filetype);
sprintf(buf, "HTTP/1.0 200 OK\r\n");
sprintf(buf, "%sServer: Tiny Web Server\r\n", buf);
sprintf(buf, "%sConnection: close\r\n", buf);
sprintf(buf, "%sContent-lengrh: %d\r\n", buf, filesize);
sprintf(buf, "%sContent-type: %s\r\n\r\n", buf, filetype);
Rio_writen(fd, buf, strlen(buf));
printf("Response headers:\n");
printf("%s", buf);
srcfd = Open(filename, O_RDONLY, 0);
srcp = Malloc(filesize);
Rio_readn(srcfd, srcp, filesize);
Rio_writen(fd, srcp, filesize);
Close(srcfd);
Free(srcp);
}
第一题:有误
第二题:正确