# 3.58

``````y=y-z;
x=x*y;
return x ^ (y<<63>>63);
``````

# 3.59

``````无符号64位，ux 和 uy

ux = x + Sx*2^64
ux = y + Sy*2^64
ux * uy = (x + Sx * 2^64) * (y + Sy * 2^64)
ux * uy = x*y + (Sx*y + Sy*x)*2^64 + Sx*Sy*2^128
ux * uy = x*y + (Sx*y + Sy*x)*2^64
x*y = ux * uy - (Sx*y + Sy*x)*2^64

movq    %rdx, %rax         rax 存有 y
cqto                       rdx 存有 -Sy (存的位要么是全 1，要么全 0）
movq    %rsi, %rcx         rcx 存有 x
sarq    \$63, %rcx          rcx 存有 -Sx
imulq   %rax, %rcx         rcx 存有 -Sx * y （注意，imul 不分有符号乘法还是无符号乘法，只保留低 64 位，这边不可能溢出，因为 Sx 要么 1 要么 0）
imulq   %rsi, %rdx         rdx 存有 -Sy * x
addq    %rdx, %rcx         rcx 存有 -Sx*y + -Sy*x
mulq    %rsi               rax 存有 ux * uy 低 64 位， rdx 存有积的高 64 位
addq    %rcx, %rdx         rdx 存有 (ux * uy)/2^64 - (Sx*y + Sy*x)
movq    %rax, (%rdi)       低 64 位
movq    %rdx, 8(%rdi)      高 64 位
ret

``````

# 3.60

``````long loop(long x, int n) {
long result = 0;
}
return result;
}
``````

# 3.61

``````long cread(long *xp) {
return (xp ? *xp : 0);
}

return (!xp ? 0 : *xp);
}

// 现在的编译器比较智能，已经不会像书中一样编译这段代码了。
``````

# 3.62

``````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;
case MODE_E:
result = 27;
break;
default:
result = 12;
break;
}
return result;
}
``````

# 3.63

``````long switch_prob(long x, long n) {
long result = x;
switch (n) {

case 60:
case 62:
result = 8 * x;
break;
case 63:
result = x >> 3;
break;
case 64:
result = x * 15;
x = result;
case 65:
x = x * x;
case 61:
default:
result = 75 + x;
}
return result;
}
``````

# 3.64

``````&D[i][j][k] = D + (S*T*i + T*j + k) * L

R = 7
S = 5
T = 13
``````

# 3.65

``````A.
&A[i][j] in %rdx

B.
&A[j][i] in %rax

C.
M = 15
``````

# 3.66

``````NR(n) == 3*n
NC(n) == n*4 + 1
``````

# 3.67

``````A.

104  +------------------+
|                  |
|                  |
|                  |
|                  |
|                  |
|                  |
|                  |
|                  |
64  +------------------+ <-- %rdi
|                  |
|                  |
|                  |
|                  |
|                  |
|                  |
32  +------------------+
|         z        |
24  +------------------+
|        &z        |
16  +------------------+
|         y        |
8  +------------------+
|         x        |
0  +------------------+ <-- %rsp

B.
eval 传了一个新地址给 process ，新地址是 %rsp+64

C.
process 通过栈指针来访问 s，而不是通过 %rdi

D.
process 将参数 %rsp+64 设置为起点，将 r 的成员设置进来，并在最后返回 r 的指针。

E.

104  +------------------+
|                  |
|                  |
|                  |
|                  |
|                  |
|                  |
88  +------------------+
|        z         |
80  +------------------+
|        x         |
72  +------------------+
|        y         |
64  +------------------+ <-- %rdi(eval pass in)
|                  |  \
|                  |   -- %rax(process pass out)
|                  |
|                  |
|                  |
|                  |
32  +------------------+
|         z        |
24  +------------------+
|        &z        |
16  +------------------+
|         y        |
8  +------------------+
|         x        |
0  +------------------+ <-- %rsp in eval
|                  |
-8  +------------------+ <-- %rsp in process

F.

``````

# 3.68

``````提示：考虑对齐产生的空隙，所以最后产生的一个范围
4 < B <= 8
6 < A <= 10
44 < A*B <= 46

``````

# 3.69

``````A.
CNT = 7

B.
typedef struct {
long idx,
long x[4]
} a_struct;
``````

# 3.70

``````A.
0 8 0 8

B.
16

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

# 3.71

``````#include <stdio.h>
#include <assert.h>

#define BUF_SIZE 12

void good_echo(void) {
char buf[BUF_SIZE];
while (1) {
/* function fgets is interesting */
char *p = fgets(buf, BUF_SIZE, stdin);
if (p == NULL) {
break;
}
printf("%s", p);
}
return;
}

int main(int argc, char *argv[]) {
good_echo();
return 0;
}
``````

# 3.72

A.
n 是奇数时：
s_2 = s_1 - (n * 8 + 24)
n 是偶数时：
s_2 = s_1 - (n * 8 + 16) s

B.
p 是 16 位的倍数

C.

-- e1 n s1

D.
p 按 16 字节对齐，
s2 十六的倍数，并且至少有 8*n 的空间。

# 3.73

``````#include <stdio.h>
#include <assert.h>

typedef enum {
NEG, ZERO, POS, OTHER
} range_t;

range_t find_range(float x) {
__asm__(
"vxorps %xmm1, %xmm1, %xmm1\n\t"
"vucomiss %xmm1, %xmm0\n\t"
"jp .P\n\t"
"ja .A\n\t"
"jb .B\n\t"
"je .E\n\t"
".A:\n\t"
"movl \$2, %eax\n\t"
"ret\n\t"
".B:\n\t"
"movl \$0, %eax\n\t"
"ret\n\t"
".E:\n\t"
"movl \$1, %eax\n\t"
"ret\n\t"
".P:\n\t"
"movl \$3, %eax\n\t"
"ret\n\t"
);
}

int main(int argc, char *argv[]) {
range_t n = NEG, z = ZERO, p = POS, o = OTHER;
assert(o == find_range(0.0 / 0.0));
assert(n == find_range(-2.3));
assert(z == find_range(0.0));
assert(p == find_range(3.33));
return 0;
}
``````

# 3.74

``````#include <stdio.h>
#include <assert.h>

typedef enum {
NEG, ZERO, POS, OTHER
} range_t;

range_t find_range(float x) {
__asm__(
"vxorps %xmm1, %xmm1, %xmm1\n\t"
"movq \$1, %rax\n\t"
"movq \$2, %r8\n\t"
"movq \$0, %r9\n\t"
"movq \$3, %r10\n\t"
"vucomiss %xmm1, %xmm0\n\t"
"cmovaq %r8, %rax\n\t"
"cmovbq %r9, %rax\n\t"
"cmovpq %r10, %rax\n\t"
);
}

int main(int argc, char *argv[]) {
range_t n = NEG, z = ZERO, p = POS, o = OTHER;
assert(o == find_range(0.0 / 0.0));
assert(n == find_range(-2.3));
assert(z == find_range(0.0));
assert(p == find_range(3.33));
return 0;
}
``````