Skip to content

Latest commit

 

History

History
769 lines (604 loc) · 15.4 KB

1500017709.md

File metadata and controls

769 lines (604 loc) · 15.4 KB

第一次作业 2017.09.17

HW1:2.61、2.62、2.65

2.61 解题报告

A:!(x^(-1)). //异或运算:a^b,当a==b的时候返回0,其他时候返回非0,再取非即可

B: !x.

C: !((x&0x0f)^(0x0f)). //先用 & 0x0f把最低位有效字节取出来,(其余位得0),然后用A的方法

D: !((-1<<28)&x).

2.62 解题报告

bool int_shifts_are_arithmetic(){
  return !((-1>>1)^(-1));
}

2.65 解题报告

int odd_ones(unsigned x){//Assume w=32
  x=x^(x>>1);//拿第一位和第二位做异或,得1说明第一位和第二位的1的数目为基数个,得0说明为偶数个,第一位、第三位、第五位……第31位同理
  x=x^(x>>2);//拿上一步得到的第一位和第三位做异或,得1说明基数个,得0说明偶数个
  x=x^(x>>4);//同理
  x=x^(x>>8);
  x=x^(x>>16);
  x=x&1;//最后得到的第一位的信息就是整个的奇偶信息,再取出来就可以了
  return x;
}

第一次作业反馈

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

第一次作业修正

第一题:int未必是32位的(可以考虑使用sizeof(int)) 另:1byte=8bit

第二次作业 2017.09.24

HW2 2.88、2.92、2.96

2.88

格式A —— 格式B ——
1 01110 001 -9/16 1 0110 0010 -9/16
0 10110 101 832 0 1111 0000 +∞
1 00111 110 -7/2^10 1 0000 0111 -7/2^10
0 00000 101 5/2^-17 0 0000 0000 +0.0
1 11011 000 -4096 1 1111 0000 -∞
0 11000 100 768 0 1111 0000 +∞

2.92

/*Compute -f. If f is NaN, then return f.*/
float_bits float_negate(float_bits f){
	int sign = f & 0x80000000;
	int exp = f & 0x7f800000;
  	int frac = f & 0x7fffff;
  	if (exp == 0x7f800000 && frac)
		return f;
  	else 
      return (sign ^ 0x80000000) | exp | frac;
}

2.96

/*
 * Compute (int) f.
 * If conversion causes overflow or f is NaN, return 0x80000000
 */
int float_f2i(float_bits f){
	int sign = f & 0x80000000;
	int exp = (f >> 23) & 0xff;
	int frac = f & 0x7fffff;
  	int result;
  	int sh1ft;
  	if (exp < 0x7f)
      	return 0;
  	else if (exp > 157)//127+30
      	return 0x80000000;
	if ( (exp == 0x7f800000 && frac)  || (Em > 31) )
		return 0x80000000;
	r = 0x40000000 + (frac << 7);//1+frac,23+7=30,留下一位给符号
	shi1f = 157 - exp;
  	r = r >> sh1ft;
  	if (sign)
      	return ~ r + 1;
  	else 
      	return r;
	return 0;
}

第二次作业反馈

第一题:有4个错误
第二题:正确
第三题:有误(请写完后自己测试一下,语法错误希望不要再有)

第三次作业

HW3 3.60 3.62 3.64

3.60

A

%rdi保存x;%rsi、%rcx保存n;%rax保存result;%rdx保存mask

B 初始值 result=0;mask=1

C 测试条件 mask!=0

D mask算数左移n位

E result|(x&mask)

F

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

/* 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:
      val = *p2;
      *p2 = *p1;
      break;
    case MODE_B:
      val = *p1 + *p2;
      *p1 = val;
      break;
    case MODE_C:
      *p1 = 59;
      val = *p2;
      break;
    case MODE_D:
      *p1 = *p2;
      val = 27;
      break;
    case MODE_E:
      val = 27;
      break;
    default:
      val = 12;
  }
  return result;
}

3.64

A

&A[i][j][k]= x_A + L(S*T*i+T*j+k)

其中,L=8

B

R=7 S=5 T=13

第三次作业反馈

第一题:正确
第二题:有一点小问题(val应为result)
第三题:正确

第四次作业

HW4: 3.68 3.69 3.70

3.68

A = 5,B = 9

3.69

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;
}

第四次作业反馈

第一题:有误(仔细啊!)
第二题:正确  
第三题:正确

第五次作业

HW 4.47 4.56 5.13 5.14

4.47

A:

/* Bubble sort: Pointer version */

void bubble_a(long *data, long count){
	long *point;
	long* last = data + count - 1;
  	long swap;
	while (last != data){
      	for (point = data; point != last; ++point){
          	if (*point > *(point+1)){
                swap = *(point+1);
              	*(point + 1) = *point;
              	*point = swap;
            }
        }
        last--;
    }
}

B:

# void bubble_a(long *data, long count)
# code edited according to mac_gcc's output
_bubble_a:
	pushl %ebp
	rrmovl %esp, %ebp
	subl $20, %esp
	mrmovl 12(%ebp), %eax	## -4(%ebp) = data
	mrmovl 8(%ebp), %ecx	## -8(%ebp) = count
	rmmovl %ecx, -4(%ebp)	## -12(%ebp) = point
	rmmovl %eax, -8(%ebp)	## -16(%ebp) = last
	mrmovl -4(%ebp), %eax	## -20(%ebp) = swap
	mrmovl -8(%ebp), %ecx
	multl $4, %eax
	addl %ecx, %eax
	addl $-4, %eax
	rmmovl %eax, -16(%ebp)
LBB0_1:
	mrmovl -16(%ebp), %eax	
	mrmovl -4(%ebp),%ecx
	subl %eax, %ecx
	je LBB0_9				## if last == data, break
## BB#2:
	mrmovl -4(%ebp), %eax
	rmmovl %eax, -12(%ebp)	## point = data
LBB0_3:
	mrmovl -12(%ebp), %eax
	mrmovl -16(%ebp), %ecx
	subl %ecx, %eax
	je LBB0_8
## BB#4:
	mrmovl -12(%ebp), %eax
	rmmovl (%eax), %eax		## %eax = *point
	mrmovl -12(%ebp), %ecx
	mrmovl 4(%ecx), %ecx	## %ecx = *(point+1)
	subl %ecx, %eax			## if *point - *(point + 1) <= 0
	jle LBB0_6
## BB#5:
	mrmovl -12(%ebp), %eax
	mrmovl 4(%eax), %eax
	rmmovl %eax, -20(%ebp)	## swap = *(point + 1)
	mrmovl -12(%ebp), %eax
	mrmovl (%eax), %eax		## eax = *point
	mrmovl -12(%ebp), %ecx
	rmmovl %eax, 4(%ecx)	## *(point + 1) = *point
	mrmovl -20(%ebp), %eax
	mrmovl -12(%ebp), %ecx
	rmmovl %eax, (%ecx)		## *point = swap
LBB0_6:
	jmp LBB0_7
LBB0_7:
	mrmovl -12(%ebp), %eax
	addl $4, %eax
	rmmovl %eax, -12(%ebp)	## point ++
	jmp LBB0_3
LBB0_8:
	mrmovl -16(%ebp), %eax
	addl $-4, %eax
	rmmovl %eax, -16(%ebp)	## last--
	jmp LBB0_1
LBB0_9:
	addl $20, %esp
	popl %ebp
	ret

4.56

# Predict next value of PC
int f_predPC = [
	# BBTFNT: This is where you'll change the branch prediction rule
	f_icode == ICALL : f_valC;
	f_icode == IJXX && f_ifun == UNCOND : f_valC;
	f_icode == IJXX && f_valC < f_valP : f_valC;
	1 : f_valP;
];

5.13

A:

HW_1030_img1

关键路径:%xmm0->add->%xmm0

B:

CPE下界:浮点数加法=3.0

C:

整数加法:CPE下界:1.0

D:

因为乘法之间不构成数据依赖,而浮点加法之间存在数据依赖

5.14

A:

因为数据读取需要CPE=1.0

B:

因为只有两个浮点数处理单元,一个用于浮点加法,一个浮点乘法,没有更多的资源用于运算

第五次作业反馈

第一题:Y86有点小问题
第二题:有误
第三题:少画了个图
第四题:写的代码呢??

第六次作业

HW 7.6,7.7,7.12,7.13

7.6

符号 swap.o.symtab条目? 符号类型 定义符号的模块
buf Y extern main.o .data
bufp0 N -- -- --
bufp1 Y local swap.o .bss
swap Y global swap.o .text
temp N -- -- --
incr Y local swap.o .text
count Y local swap.o .bss

7.7

/* bar5.c */
static double x;

void f(){
    x = -0.0;
}

/* foo5.c */
#include <stdio.h>
void f(void);

int y = 15212;
int x = 15213;

int main(){
    f();
  	printf("x = 0x%x y = 0x%x \n", x, y);
  	return 0;
}

7.12

A. 0xa

B. 0x22

7.13

A.

locate:/usr/lib/x86_64-linux-gnu

C standard lib:libc.a:包含1605个不同的目标文件

C math lib:libm.a:包含439个不同的目标文件

B.

gcc -Og -g产生的可执行二进制文件多出了.debug_aranges, .debug_info, .debug_abbrev, .debug_line, .debug_str, .debug_loc部分

C.

共享库版本:x86_64-linux-gnu:GNU C11 (Ubuntu 5.4.0-6ubuntu1~16.04.4) version 5.4.0 20160609 (x86_64-linux-gnu)

(使用-v选项显示gcc运行中间步骤)

第六次作业反馈

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

第七次作业

HW. 8.9,8.18,8.24,10.6,10.9

8.9

进程对 并发?
AB N
AC Y
AD Y
BC Y
BD Y
CD Y

8.18

A、C、E都是可能的

8.24

#include <stdio.h>
#include <sys/types.h>
#include <stdlib.h>
#include <signal.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <unistd.h>
#include <errno.h>
#include <string.h>

char cmd[50]= "test";
char temp[20];


void test(){
    char m[] = "man";
    char *p = m; 
    sprintf(temp,"test reached\n");
    sprintf(temp,"%x\n", test);
    sprintf(temp,"%lx\n", p);
    for(int i = 0; i < 1000; ++i){
        *p = 'a';
        p++;
    }
    return;
}


int main(){
    int status = 0;
    char m[3];
    char * p = m;
    pid_t pid;
    if ((pid = fork()) == 0)//child
    {
        test();
    }
    else{//parent
        waitpid(pid, &status, 0);
        if(WIFSIGNALED(status)){
            sprintf(cmd, "child %d terminated by signal %d", pid, status);
            psignal(status, cmd);
        }
        if ((pid = fork()) == 0)//child
        {
            test();
        }
        else{
            waitpid(pid, &status, 0);
            if(WIFSIGNALED(status)){
                sprintf(cmd, "child %d terminated by signal %d", pid, status);
                psignal(status, cmd);
            }
        }
    }
    return 0;
}
//main.c

测试效果:

linux> gcc -Og main.c -o main
linux> ./main
child 14624 terminated by signal 11: Segmentation fault
child 14625 terminated by signal 11: Segmentation fault
linux> 

10.6

fd2 = 4

10.9

linux> fstatcheck 3 < foo.txt
if(Fork() == 0){/* child */
	int fd = open("foo.txt", O_RDONLY, 0);
  	dup2(fd, STDIN_FILENO);
  	Execve("fstatcheck", argv, envp);
}
//注释:直接用 < 会将文件描述符重定向到STDIN_FILENO,而如果要作为单独的描述符存在,可以这样做:
//注释:直接用 < 会将文件描述符重定向到STDIN_FILENO,而如果要作为单独的描述符存在,可以这样做:
linux> fstatcheck 3< foo.txt

第七次作业反馈

第一题:正确
第二题:正确
第三题:正确
第四题:正确
第五题:close(fd)

第八次作业

VM作业:编写虚页页号遍历程序,该程序打印出本进程所能够访问的所有虚页页号

#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <sys/types.h>
#include <fcntl.h>

int main(int argc, char * const argv[]){

    pid_t pid = getpid();
    int fd_file;
    char filename[50];
    char buf[257];

    unsigned long start, end;
    char flag[5];
    unsigned int length;
    char unknown1[6];
    unsigned int unknown2;
    char pwd[255];

    sprintf(filename, "/proc/%d/maps", pid);


    fd_file = open(filename, O_RDONLY, 0);
    dup2(fd_file, STDIN_FILENO);

    while(fgets(buf, 256, stdin) > 0){
        sscanf(buf, "%lx-%lx %s %x %s %d %s\n", &start, &end, flag, &length, unknown1, &unknown2, pwd);
        start >>= 12;
        end >>= 12;
        for(unsigned long i = start; i <= end; ++i){
            printf("0x%lx\n", i);
        }
        
    }

    close(fd_file);
    return 0;
}
//showVM.c

运行效果:

huangyong@ubuntu:~/test$ gcc -Og showVM.c -o showVM
huangyong@ubuntu:~/test$ ./showVM
0x400
0x401
0x600
0x601
0x601
0x602
0x219b
0x219c
0x219d
...
0x7ffd88a69
0x7ffd88a6a
0x7ffd88a6b
0xffffffffff600
0xffffffffff601

第九次作业

HW9: 11.8 11.9

11.8

添加信号处理函数:

void sigchld_handler(int sig){//added
	int olderrno = errno;
	while(waitpid(-1, NULL, WNOHANG | WUNTRACED) > 0);
	errno = olderrno;
	return;
}

main函数修改:

int main(int argc, char **argv) 
{
    int listenfd, connfd;
    char hostname[MAXLINE], port[MAXLINE];
    socklen_t clientlen;
    struct sockaddr_storage clientaddr;

    /* Check command line args */
    if (argc != 2) {
	fprintf(stderr, "usage: %s <port>\n", argv[0]);
	exit(1);
    }
	/*******ADDED***********/
    Signal(SIGCHLD, sigchld_handler);
	/*******ADDED***********/
    listenfd = Open_listenfd(argv[1]);
    while (1) {
	clientlen = sizeof(clientaddr);
	connfd = Accept(listenfd, (SA *)&clientaddr, &clientlen); //line:netp:tiny:accept
        Getnameinfo((SA *) &clientaddr, clientlen, hostname, MAXLINE, 
                    port, MAXLINE, 0);
        printf("Accepted connection from (%s, %s)\n", hostname, port);
	doit(connfd);                                             //line:netp:tiny:doit
	Close(connfd);                                            //line:netp:tiny:close
    }
}

serve_dynamic函数修改:

void serve_dynamic(int fd, char *filename, char *cgiargs) 
{
    char buf[MAXLINE], *emptylist[] = { NULL };

    /* Return first part of HTTP response */
    sprintf(buf, "HTTP/1.0 200 OK\r\n"); 
    Rio_writen(fd, buf, strlen(buf));
    sprintf(buf, "Server: Tiny Web Server\r\n");
    Rio_writen(fd, buf, strlen(buf));
  
    if (Fork() == 0) { /* Child */ //line:netp:servedynamic:fork
	/* Real server would set all CGI vars here */
	setenv("QUERY_STRING", cgiargs, 1); //line:netp:servedynamic:setenv
	Dup2(fd, STDOUT_FILENO);         /* Redirect stdout to client */ 
      //line:netp:servedynamic:dup2
	Execve(filename, emptylist, environ); /* Run CGI program */ 
      //line:netp:servedynamic:execve
    }
  	/*******DELETED*********/
    //Wait(NULL); /* Parent waits for and reaps child */ //line:netp:servedynamic:wait
  	/*******DELETED*********/
}

11.9

void serve_static(int fd, char *filename, int filesize) 
{
    int srcfd;
    char *srcp, filetype[MAXLINE], buf[MAXBUF];
 
    /* Send response headers to client */
    get_filetype(filename, filetype);       //line:netp:servestatic:getfiletype
    sprintf(buf, "HTTP/1.0 200 OK\r\n");    //line:netp:servestatic:beginserve
    sprintf(buf, "%sServer: Tiny Web Server\r\n", buf);
    sprintf(buf, "%sConnection: close\r\n", buf);
    sprintf(buf, "%sContent-length: %d\r\n", buf, filesize);
    sprintf(buf, "%sContent-type: %s\r\n\r\n", buf, filetype);
    Rio_writen(fd, buf, strlen(buf));       //line:netp:servestatic:endserve
    printf("Response headers:\n");
    printf("%s", buf);

    /* Send response body to client */
    srcfd = Open(filename, O_RDONLY, 0);    //line:netp:servestatic:open
    // srcp = Mmap(0, filesize, PROT_READ, MAP_PRIVATE, srcfd, 0);//line:netp:servestatic:mmap
  	void * srcp = malloc(filesize + 1);
  	Rio_readn(srcfd, srcp, filesize);
    Close(srcfd);                           //line:netp:servestatic:close
    Rio_writen(fd, srcp, filesize);         //line:netp:servestatic:write
    // Munmap(srcp, filesize);                 //line:netp:servestatic:munmap
  	free(srcp);
}

第九次作业反馈

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