CSAPP 第三版 第三章 家庭作业and so on

CSAPP 第三版 第三章 家庭作业
自己做的 仅供参考 可能出现错误

注:3.60 3.67mark一下

3.58

long decode2(long x, long y, long z)
{
	return (((y - z) << 63) >> 63) ^ (x * (y - z));
}

3.59

store_prod:
    movq   %rdx, %rax   # %rax = y
    cqto                # 4字按符号位拓展到8,%rdx = yh,%rax = yl
    movq   %rsi, %rcx   # %rcx = x
    sarq   $63,  %rcx   # 将%rcx向右移63,相当于做符号位扩展,%rcx = xh,%rsi = xl
    imulq  %rax, %rcx   # %rcx = yl * xh
    imulq  %rsi, %rdx   # %rdx = xl * yh
    addq   %rdx, %rcx   # %rcx = yl * xh + xl * yh
    mulq   %rsi         # 无符号计算 xl*yl,并将xl*yl的128位结果的高位放在%rdx,低位放在%rax
    addq   %rcx, %rdx   # 将高位计算结果加到%rdx
    movq   %rax, (%rdi) # 将%rax的值放到dest的低位
    movq   %rdx, 8(%rdi)# 将%rdx的值放到dest的高位
    ret

3.60

A. %rdi -> x;
   %esi -> n;
   %rax -> result;
   %rdx -> mask;
B. result = 0;  
   mask = 1;
C. mask != 0;
D. mask = mask << (n % 64);
E. result |= (x & mask);

F.

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

x86-64中,移位操作对w位长的数据值进行操作,移位量是由%cl寄存器的低m位决定的,这里2m=w。高位会被忽略。所以salb移位量由%cl低3位、salw移位量由%cl低4位、sall移位量由%cl低5位、salq移位量由%cl低6位决定。故

mask = mask << (n & 0x3F)

但是不取余(n % 64)也可以,因为编译器自己会处理

3.61

测试了各种,发现这种写法在-O1优化选项下没有跳转语句(有三目表达式)

long cread_alt1(long *xp)
{
	long t = 0;
	long *p = xp ? xp : &t;
	return *p;
}

3.62

/* Enumerated type creates set of constants numbered 0 and upward */
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;
      result = 27;
      break;
    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 = x * 8;
		break;
	case 63:
		result = result >> 3;
		break;
	case 64:
		result = (result << 4) - x;
		x = result;
	case 65:
		x = x * x;
	default:
		result = x + 75;
	}
}

3.64

A. &A[i][j][k] = A + L * (T * S * i + T * j + k);
B. R = 7;S = 5;T = 13;

3.65

A. %rdx;
B. %rax;
C. 15;

3.66

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

3.67

A. %rsp -> x;
   %rsp + 8 -> y;
   %rsp + 16 -> &z;//结构体strA s部分
   %rsp + 24 -> z;
B. %rsp + 64;
C. %rsp + bias;
D. %rdi + bias;
E. %rsp + 64 -> y
   %rsp + 72 -> x
   %rsp + 80 -> z//结构体strB s部分
F. 结构体传递参数或作为返回值均为其首地址值

3.68

A = 9; 
B = 5;

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.

union ele {
	struct {
		long *p;
		long y;
	}e1;
	struct {
		long x;
		union ele *next;
	}e2;
};
void proc(union ele *up) {
	up->e2.x = *(up->e2.next->e1.p) - up->e2.next->e1.y;
    //想写up->e2.x = *(*(up->e2.next).e1.p) - *(up->e2.next).e1.y;但是vs报错:表达式必须包含类类型
}

3.71

首先阅读fgets相关信息

http://www.cplusplus.com/reference/cstdio/fgets/

fgets
char * fgets ( char * str, int num, FILE * stream );
Get string from stream
Reads characters from stream and stores them as a C string into str until (num-1) characters have been read or either a newline or the end-of-file is reached, whichever happens first.
A newline character makes fgets stop reading, but it is considered a valid character by the function and included in the string copied to str.
A terminating null character is automatically appended after the characters copied to str.
Notice that fgets is quite different from gets: not only fgets accepts a stream argument, but also allows to specify the maximum size of str and includes in the string any ending newline character.

Parameters
str
Pointer to an array of chars where the string read is copied.
num
Maximum number of characters to be copied into str (including the terminating null-character).
stream
Pointer to a FILE object that identifies an input stream.
stdin can be used as argument to read from the standard input.

Return Value
On success, the function returns str.
If the end-of-file is encountered while attempting to read a character, the eof indicator is set (feof). If this happens before any characters could be read, the pointer returned is a null pointer (and the contents of str remain unchanged).
If a read error occurs, the error indicator (ferror) is set and a null pointer is also returned (but the contents pointed by str may have changed).

void good_echo(void) {
	const int BUF_SIZE = 12;
	char buf[BUF_SIZE];
	while (1) {
		char* p = fgets(buf, BUF_SIZE, stdin);
		if (ferror(stdin) || p == NULL) {
			break;//题目说遇到错误条件返回也没说做啥特殊处理……例如把buf数组清空类似处理
		}
		fprintf(stdout, "%s", p);
	}
	return;
}

3.72

A. s1 - (8 * n + 16) n为偶数时;
   s1 - (8 * n + 24) n为奇数时;
B. (s2 + 15) & 0xfffffff0;
C. e1 max n为奇数,s2 % 16 == 0;
   e1 min n为偶数,s2 % 16 == 1;
D. p 以16位对齐;
   s2保证有>= 8 * n的最小十六倍数+ 16的空间;

3.73

find_range:
   vxorps %xmm1, %xmm1, %xmm1
   vucomiss %xmm1, %xmm0
   jp .L1
   ja .L2
   jb .L3
   je .L4
 .L2:
   movl $2, %eax
   ret
 .L3:
   movl $0, %eax
   ret
 .L4:
   movl $1, %eax
   ret
 .L1:
   movl $3, %eax
   rep; ret

3.74

find_range:
    vxorps %xmm1, %xmm1, %xmm1
    movq $1, %r8
    movq $2, %r9
    movq $3, %r10
    movq $0, %rax
    vucomiss %xmm1, %xmm0
    cmove %r8, %rax
    cmova %r9, %rax
    cmovp %r10,%rax

3.75

A. 实部 %xmm(2 * n - 2);
   虚部 %xmm(2 * n - 1);
B. 实部 %xmm0; 
   虚部 %xmm1;
  • 6
    点赞
  • 23
    收藏
    觉得还不错? 一键收藏
  • 6
    评论
评论 6
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值