Skip to content
This repository has been archived by the owner on Oct 8, 2022. It is now read-only.

Latest commit

 

History

History
531 lines (489 loc) · 10.4 KB

1600013019.md

File metadata and controls

531 lines (489 loc) · 10.4 KB

homework-chapter 11

11.8

/*在serve_dynamic()的开头加上这一行*/
Signal(SIGCHLD,sigchld_handler);
/*增加一个handler函数*/
void sigchld_handler(int sig)
{
	while(waitpid(-1,0,WNOHANG)>0);
	return;
}

11.9

修改serve_static()中的部分代码

/*Send response body to client*/
srcfd=Open(filename,O_RDONLY,0);
srcp=(char*)malloc(sizeof(char)*filesize);
Rio_readn(srcfd,srcp,filesize);
Close(srcfd);
Rio_writen(fd,srcp,filesize);
free(srcp);

第九次作业反馈

第一题:有误
第二题:正确

homework-chapter 9

#include<stdio.h>
#include<unistd.h>
#include<stdlib.h>
int main()
{
	char filename[50];
	char buf[1000];
	FILE* maps;
	pid_t pid=getpid();	//进程号
	unsigned long long s_addr,e_addr;	//内存起始地址、终止地址
	sprintf(filename,"/proc/%d/maps",pid);	//文件地址
	maps=fopen(filename,"r");
	while(fgets(buf,1000,maps)!=NULL)	//读一行
	{
		sscanf(buf,"%llx-%llx",&s_addr,&e_addr);
		s_addr>>=12;
		e_addr>>=12;	//去掉VPO
		for(;s_addr!=e_addr;s_addr++)
			printf("%llu\n",s_addr);
	}
	return 0;
}	

homework-chapter 10

10.6

fd1=3.fd2=4,close之后新的fd2仍等于4
所以输出为:fd2=4

10.9

if(Fork()==0)
{
	char* filename=argv[3];
	int fd=open(filename,O_RDONLY,0);
	dup2(fd,STDIN_FILENO);
	close(fd);
	Execve("fststcheck",argv,envp);
}

homework-chapter 8

8.9

进程对 并发地?
AB NO
AC YES
AD YES
BC YES
BD YES
CD YES

8.18

父进程输出1,父进程的子进程输出0,子进程输出12,子进程的子进程输出02,
他们之间的相对顺序不固定,所以ACE都有可能

8.24

#include "csapp.h"
#define N 2

int main()
{
	int status,i;
	pid_t pid;
	int sig;
	char errinfo[100]={0};

	/*parent creates N children*/
	for(int i=0;i<N;i++)
		if((pid=Fork())==0)	/*child*/
			exit(100+i);

	/*parent reaps N children in no particular order*/
	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))
		{
			sig=WTERMSIG(status);
			sprintf(errinfo,"child %d terminated by signal %d",pid,sig);
			psignal(sig,errinfo);	
		}
	}
	
	/*the only normal termination is if there are no more children*/
	if(errno!=ECHILD)
		unix_error("waitpid error");

	exit(0);
}

第七次作业反馈

第一题:正确
第二题:正确
第三题:正确
第四题:正确
第五题:错误

homework 6

7.6

符号 symtab条目? 符号类型 定义符号的模块
buf Y 外部 m.o .data
bufp0 Y 全局 swap.o .data
bufp1 Y 局部 swap.o .bss
swap Y 全局 swap.o .text
temp N —— —— ——
incr Y 局部 swap.o .text
count Y 局部 swap.o .data

7.7

/*bar5.c*/
static double x;
void f()
{
    x=-0.0;
}

7.12

(1)0x4004f8-0x4004ee=0xa
(2)0x400500-0x4004de=0x22

7.13

(1)libc.a包含1672个目标文件
  libm.a包含481个目标文件
(2)相同
(3)linux-vdso.so.1 libc.so.6

第六次作业反馈

第一题:有一处错误
第二题:正确
第三题:正确
第四题:正确

homework1

2.61

A.!(x^-1)
B.!(x^0)
C.!((x&0xff)^0xff)
D.!(x>>(sizeof(int)*8-8))

2.62

int int_shifts_are_arithmetic()
{
	int x=-1>>(sizeof(int)*8-1);//log:x=1,ari:x=-1
	if(!(x^1))return 0;
	else return 1;
}

2.65

int odd_ones(unsigned x)
{
	x^=x>>16;
	x^=x>>8;
	x^=x>>4;
	x^=x>>2;
	x^=x>>1;
	return x%2;
}

第一次作业反馈

第一题:A、B正确,C、D有误
第二题:有误
第三题:正确

homework2

2.88

208 011101010 208
-7/1024 100000111 -7/1024
5/(2^17) 000000000 1/1024
-2^12  111110000  负无穷
768  011110000  正无穷

2.92

float_bits float_negate(float_bits f)
{
	unsigned sign=f>>31;
	unsigned exp=f>>23&0xff;
	unsigned frac=f&0x7fffff;
	if(exp==0xff&&frac!=0)
		return f;
	else
		return ((!sign)<<31)|(exp<<23)|frac;
}

2.95

int float_f2i(float_bits f)
{
	const int bias=127;
	int sign=f>>31;
	int exp=((f>>23)&0xff)-bias;//2的指数位
	int frac=f&0x7fffff+(1<<23);//加上前导1之后的完整的小数部分
	int ans;
	if(exp>30)//int最大是2^31-1,最多可以往左移30位,大于30就out of range
		return 0x80000000;
	else if(exp>23)//保证位运算的位数是正数
		ans=frac<<(exp-23);//实质是先向右移23位再向左移exp,防止丢失数据
	else 
		ans=frac>>(23-exp);
	if(sign==1)
		return -ans;
	else return ans;
}

第二次作业反馈

第一题:有1个错误
第二题:有误
第三题:正确  

homework 3

3.60

A. x in %rdi, n in %rsi, result in %rax, mask in %rdx
B. result=0;mask=1;
C. mask!=0
D. mask<<(n&0xff)
E. result|=(x&mask)
F.

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

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;
			action=(mode_t)*p1;
			*p2=action;
			break;
		}
	case(MODE_B):
		{
			result=*p1;
			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;
			break;
		}
	}
	return  result;
}

3.64

A.

&A[i][j][k]=Xa+8*(S*T*i+T*j+k); //A的起始位置标为Xa

B. 根据原汇编代码可以得出

store_ele:
	leaq (%rsi,%rsi,2),%rax //%rax=3*j;
	leaq (%rsi,%rax,4),%rax //%rax=13*j;
	movq %rdi,%rsi          //%rsi=i;
	salq $6,%rsi 		//%rsi=i<<6;
	addq %rsi,%rdi 		//%rdi=65i;
	addq %rax,%rdi		//%rdx=65i+13j;
	addq %rdi,%rdx		//%rdx=65i+13j+k;
	movq A(,%rdx,8),%rax    //%rax=A[8*%rdx];
	movq %rax,(%rcx)	//*dest=%rax;
	movl $3640,%eax		
	ret			//return 3640;

所以A[R][S][T]的总字节数是3640,一个long长整型占据8个字节,所以总共存有455个long型变量
根据上一题中的公式以及%rdx=65i+13j+k,可以算出T=13,S=65/13=5,R=455/65=7

第三次作业反馈

第一题:正确
第二题:正确
第三题:正确

homework 4

3.68

由汇编代码可以得出:

q->t=*(q+8);
q->u=*(q+32);
p->y=*(p+184);

因为p->y必须要和8的整数倍地址对齐,所以x[A][B]的大小4 * A * B一定在176~184之间,即44<A * B<=46
同理,q->t必须和4的整数倍地址对齐,q->u必须要和8的整数倍地址对齐,所以4<B<=8,6<A<=10
所以整数A,B的唯一解是A=9,B=5

3.69

由汇编代码可以得出:

bp->last=(bp+288)
sizeof(a[i])=40;//由%rax=&(40*%rdi+%rsi)得出
CNT=7;//又因为%rdx=*(%rax+8),而%rdx最终存的是ap->idx的值,所以8就是bp->a的偏移量,所以a[]总共占据了280字节
sizeof(ap->x[ap->idx])=8;//由*(%rax+0x10+%rdx*8)得出
long x[4];//0x10=a的偏移量8+x的偏移量8,所以x中的元素个数是(40-8)/8=4;
sizeof(idx)=8;//first只有四个字节,a却偏移了8个字节,所以a_struct中的元素idx是long类型

答案:

CNT=7;
typedef struct
{
	long idx;
	long x[4];
}a_struct;

3.70

A.
e1.p 0
e1.y 8
e2.x 0
e2.next 8

B.
总共需要16字节

C.

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

第四次作业反馈

第一题:正确
第二题:正确
第三题:正确

homework5

4.47

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)>*(data+i+1))
			{
				long t;
				t=*(data+i+1);
				*(data+i+1)=*(data+i);
				*(data+i)=t;
			}
	}
}
bubble_a:
    pushl   %ebp
    rrmovl  %esp,%ebp
    mrmovl    8(%ebp),%eax    #count  
    mrmovl  12(%ebp),%esi    #data
    irmovl  $1,%ebx
    subl    %ebx,%eax    #last=count-1
Loop1:
    andl     %eax,%eax    #last>0?
    jle    Done
    xorl    %ecx,%ecx    #i=0
Loop2:
    subl    %eax,%ecx    #i<last?
    jge    Loop3
    addl    %eax,%ecx    #true i
    addl    %ecx,%esi    #data+i
    mrmovl    (%esi),%edi    #*(data+i)
    mrmovl    4(%esi),%edx    #*(data+i+1)
    subl    %edx,%edi    #*(data+i)>*(data+i+1)?
    jle    Condition
    addl    %edx,%edi    #true *(data+i)
    rrmovl    %edx,%ebx    #t=*(data+i+1);
    rrmovl    %edi,%edx    #*(data+i+1)=*(data+i);
    rrmovl    %ebx,%edi    #*(data+i)=t;
    rmmovl    %edi,(%esi)    #write *(data+i)
    rmmovl    %edx,4(%esi)    #write *(data+i+1)    
Condition:
    subl    %ecx,%esi    #true data
    irmovl    $1,%ebx
    addl    %ebx,%ecx    #i++
    jmp    Loop2
Loop3:
    irmovl  $1,%ebx
    subl    %ebx,%eax    #last--
    jmp    Loop1
Done:
    popl    %ebp
    ret

4.56

#Fetch stage#
word f_predPC = [
	f_icode == IJXX && J_YES : f_valC;
	f_code == ICALL : f_valC;
	f_code == IJXX && f_valC < f_valP : f_valC;
	1: valP;
]
word f_pc = [
	M_icode == IJXX && !M_Cnd && M_valC < M_valP : M_valA;
	M_icode == IJXX && M_Cnd && M_valC >= M_valP : M_valA;
	W_icode == IRET : W_valM;
	1 : F_predPC;
]
#Execute stage#
int E_valP = D_valP;
#Memory stage#
int M_valP = E_valP;
int M_valC = E_valC;

5.13

A.
循环寄存器%xmm0上的浮点加法形成关键路径
B.3.0
C.1.0
D.乘法操作不在关键路径上,可以流水线化执行

5.14

void inner4(vec_ptr u,vec_ptr v, data_t *dest)
{
	long i;
	long length=vec_length(u);
	data_t *udata=get_vec_start(u);
	data_t *vdata=get_vec_start(v);
	data_t sum=(data_t)0;
	for(i=0;i<length-5;i+=6)
	{
		sum=sum+udata[i]*vdata[i];
		sum=sum+udata[i+1]*vdata[i+1];
		sum=sum+udata[i+2]*vdata[i+2];
		sum=sum+udata[i+3]*vdata[i+3];
		sum=sum+udata[i+4]*vdata[i+4];
		sum=sum+udata[i+5]*vdata[i+5];
	}
	for(;i<length;i++)
	{
		sum=sum+udata[i]*vdata[i];
	}
	*dest=sum;
}

A.无论展开多少次、如何改变结合顺序,循环展开时至少有一个sum的整数加法是需要顺序进行的,而整数加法的延迟界限是1.00
B.sum的浮点加法仍然是顺序操作,要受到延迟界限的限制

第五次作业反馈

第一题:Y86有点小问题
第二题:有误
第三题:少画了个图
第四题:i<length处有问题