20145209 《信息安全系统设计基础》第13周学习总结
家庭作业
4.47题:
leave指令等价于如下代码序列:
rrmovl %ebp,%esp
popl %ebp
也就是说它要执行的动作是,将帧指针ebp的内容赋给栈指针esp,然后弹出ebp,栈指针+4,结果是消灭这个栈。
参照pop指令的格式,可以得出如下的过程:
取指阶段 icode:ifun<--M1[PC] = D:0
valP <= PC + 1 ;下一条指令地址
译码阶段 valB <= R[%ebp] ;得到ebp的值,这个值就是新的栈指针esp的值
执行阶段 valE <= valB + 4 ;栈指针的值+4
访存阶段 valM <= M4[valB] ;读ebp中的值
写回阶段 R[%esp] <= valE ;把更新后的指针赋值给esp
R[%ebp] <= valM ;弹出的ebp的值
家庭作业7.11
题目
解答:
3、4行是数据段,开始于存储器地址0x08049448的位置,总的存储器大小是0x194字节,从文件偏移的0x448处开始的0xe8个字节初始化。
在加载之前,未初始化的全局变量不会在目标文件中分配存储空间,但是在加载之后,像.bss中的符号等数据需要占用空间,所以剩下的字节对应运行时将被初始化为0的.bss数据。
9.13
A.虚拟地址:0x0040
13 12 11 10 9 8 7 6 5 4 3 2 1 0
0 0 0 0 0 0 0 1 0 0 0 0 0 0
B.地址翻译
参数 值
VPN 0x01
TLB索引 0x01
TLB标记 0x00
TLB命中 No
缺页 Yes
PPN -
11.7
拓展TINY,使它可以提供MPG视频文件。用一个真正的浏览器来检验你的工作。
答:在get_filetype函数里面添加:
else if(strstr(filename, ".mpg") || strstr(filename, ".mp4"))
strcpy(filetype, "video/mpg");
源代码:
include<csapp.h>
void doit(int fd);
void read_requesthdrs(rio_t *rp);
int parse_uri(char *uri, char *filename, char *cgiargs);
void serve_static(int fd, char *filename, int filesize);
void get_filetype(char *filename, char *filetype);
void serve_dynamic(int fd, char *filename, char *cgiargs);
void clienterror(int fd, char *cause, char *errnum,char *shorting,char *longmsg);
int main(int argc,char *argv[])
{
int listenfd,connfd,port,clientlen;
struct sockaddr_in clientaddr;
if(argc != 2)
{
fprintf(stderr,"usage: %s
exit(0);
}
port = atoi(argv[1]);
listenfd = Open_listenfd(port);
while(1)
{
clientlen = sizeof(clientaddr);
connfd = Accept(listenfd, (SA *)&clientaddr, &clientlen);
doit(connfd);
Close(connfd);
}
}
void doit(int fd)
{
int is_static;
struct stat sbuf;
char buf[MAXLINE], method[MAXLINE],uri[MAXLINE],version[MAXLINE];
char filename[MAXLINE],cgiargs[MAXLINE];
rio_t rio;
/read request line and headers/
Rio_readinitb(&rio, fd);
Rio_readlineb(&rio, buf, MAXLINE);
sscanf(buf, "%s %s %s", method, uri, version);
if(strcasecmp(method,"GET"))
{
clienterror(fd, method, "501","Not Implemented",
"Tiny does not implement this method");
return;
}
read_requesthdrs(&rio);
/prase URI from GET request/
is_static = parse_uri(uri, filename, cgiargs);
if(stat(filename, &sbuf) < 0)
{
clienterror(fd, filename, "404","Not Found",
"Tiny couldn't find this file");
return;
}
if(is_static)//server static content
{
if(!(S_ISREG(sbuf.st_mode) || !(S_IRUSR & sbuf.st_mode)))
{
clienterror(fd, filename, "403","Forbidden",
"Tiny couldn't read the file");
return;
}
serve_static(fd, filename, sbuf.st_size);
}
else//server dynamic content
{
if(!(S_ISREG(sbuf.st_mode) || !(S_IXUSR & sbuf.st_mode)))
{
clienterror(fd, filename, "403","Forbidden",
"Tiny couldn't run the CGI program");
return;
}
serve_dynamic(fd, filename, cgiargs);
}
}
void clienterror(int fd, char *cause, char *errnum,
char *shortmsg, char *longmsg)
{
char buf[MAXLINE], body[MAXBUF];
/*Build the HTTP response body*/
sprintf(body, "<html><title>Tiny Error</title>");
sprintf(body, "%s<body bgcolor=""ffffff"">
",body);
sprintf(body, "%s%s: %s
",body,errnum,shortmsg);
sprintf(body, "%s<p>%s: %s
", body, longmsg, cause);
sprintf(body, "%s<hr><em>The Tiny Web Server</em><>
",body);
/*Print the HTTP response*/
sprintf(buf, "HTTP/1.0 %s %s
",errnum, shortmsg);
Rio_writen(fd, buf, strlen(buf));
sprintf(buf, "Content-type: text/html
");
Rio_writen(fd, buf, strlen(buf));
sprintf(buf, "Content-length: %d
",(int)strlen(body));
Rio_writen(fd, buf, strlen(buf));
Rio_writen(fd, body, strlen(body));
}
//read_requesthdrs()来跳过请求报头的信息,直到遇见表示报头结束的空文本行。
void read_requesthdrs(rio_t *rp)
{
char buf[MAXLINE];
Rio_readlineb(rp, buf, MAXLINE);
while(strcmp(buf, "
"))
{
Rio_readlineb(rp, buf, MAXLINE);
printf("%s", buf);
}
return;
}
int parse_uri(char *uri, char *filename, char *cgiargs)
{
char *ptr;
if(!strstr(uri, "cgi-bin"))//static content
{
strcpy(cgiargs, "");
strcpy(filename, ".");
strcat(filename, uri);
if(uri[strlen(uri)-1] == '/')
strcat(uri, "home.html");
return 1;
}
else
{
ptr = index(uri, '?');
if(ptr)
{
strcpy(cgiargs, ptr+1);
*ptr = ' ';
}
else
strcpy(cgiargs, "");
strcpy(filename, ".");
strcat(filename, uri);
return 0;
}
}
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);
sprintf(buf, "HTTP/1.0 200 OK
");
sprintf(buf, "%sServer: Tiny Web Server
", buf);
sprintf(buf, "%sContent-lenght: %d
", buf, filesize);
sprintf(buf, "%sContent-type: %s
", buf, filetype);
Rio_writen(fd, buf, strlen(buf));
/*Send response body to client*/
srcfd = Open(filename, O_RDONLY, 0);
srcp = Mmap(0, filesize, PROT_READ, MAP_PRIVATE,srcfd,0);
close(srcfd);
Rio_writen(fd, srcp, filesize);
Munmap(srcp, filesize);
}
void get_filetype(char *filename, char *filetype)
{
if(strstr(filename, ".html"))
strcpy(filetype, "text/html");
else if(strstr(filename, ".gif"))
strcpy(filetype, "image/gif");
else if(strstr(filename, ".jpg"))
strcpy(filetype, "image/jpeg");
else
strcpy(filetype, "text/plain");
}
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
");
Rio_writen(fd, buf,strlen(buf));
sprintf(buf, "Server: Tiny Web Server
");
Rio_writen(fd, buf,strlen(buf));
if(Fork()==0)
{
setenv("QUERY_STRING", cgiargs, 1);
Dup2(fd, STDOUT_FILENO);
Execve(filename, emptylist,environ);
}
Wait(NULL);
}
其他(感悟、思考等,可选)
xxx
xxx
学习进度条
代码行数(新增/累积) | 博客量(新增/累积) | 学习时间(新增/累积) | 重要成长 | |
---|---|---|---|---|
目标 | 5000行 | 30篇 | 400小时 | |
第一周 | 200/200 | 2/2 | 20/20 | |
第二周 | 300/500 | 2/4 | 18/38 | |
第三周 | 500/1000 | 3/7 | 22/60 | |
第四周 | 300/1300 | 2/9 | 30/90 |