郝博雅

导航

2017-2018-1 20155205 《信息安全系统设计基础》第八周课堂测试+课下作业

2017-2018-1 20155205 《信息安全系统设计基础》第八周课堂测试+课下作业

课堂测试

  • 任务一:
参考 http://www.cnblogs.com/rocedu/p/6766748.html#SECCLA 在Linux下完成“求命令行传入整数参数的和”

测试代码传入自己的8位学号

上方提交代码

附件提交运行测试截图

代码:

#include <stdio.h>
int main( int argc, char *argv[] )
{
    int i;
    int sum;
    for( i=1;i<argc;i++ )
    {
       sum +=atoi(argv[i]);//atoi()函数把字符串转换成整型数
    }

    printf("%d",sum);
    return 0;
}

运行截图:

  • 任务二:
把第一个练习中的代码在X86-64(Ubuntu)中反汇编,给出汇编代码和机器码的截图

把X86-64汇编翻译成Y86-64汇编,并给出相应机器码的截图(使用附件中的Y86-64模拟器)

通过cat sum.s查看汇编代码:

通过gobjdump -d sum.o查看机器代码:

我的ubantu连不上网,iterm无法使用y86,所以使用实验楼的y86模拟器,但是总会出现下图错误:

  • 任务三:
基于socket 使用教材的csapp.h csapp.c,实现daytime(13)服务器(端口我们使用13+后三位学号)和客户端
服务器响应消息格式是
“
客户端IP:XXXX
服务器实现者学号:XXXXXXXX
当前时间: XX:XX:XX
”
上方提交代码
提交一个客户端至少查询三次时间的截图测试截图
提交至少两个客户端查询时间的截图测试截图

课下作业

  • 任务一:
1 完成家庭作业4.47,4.48,4.49
2 相应代码反汇编成X86-64汇编
3 把上述X86-64汇编翻译成Y86汇编,并给出相应机器码

4.47:

void bubble(int *data,int c)
{
   int i,j;
   int *p,*q;
   for(i=c-1;i!=0;i--){
       p=data;
       q=data+1;
       for(j=0;j!=i;++j)
        {
            if(*p>*q)
            {
                int t=*p;
                *p=*q;
                *q=t;
             }
         p++;
         q++;
    }
}
}

x86汇编代码:

相应y86代码:

bubble: 
  pushl %ebp 
  movl %esp, %ebp 
  pushl %esi 
  pushl %ebx 
  pushl %edx  
  movl 8(%ebp), %edx   #edx == data 
  movl 12(%ebp), %esi  #esi == count 
  andl %esi, %esi  
  je bubbleEnd #count==0 
  movl $1, %eax  
  subl %eax, %esi #count-- 
  je bubbleEnd #count==1
OuterLoop: 
  movl %edx, %ecx # p = data (ecx) 
  pushl %esi# to save one reg
InnerLoop: 
  movl (%ecx), %eax 
  movl 4(%ecx), %ebx
  subl %eax, %ebx 
  movl 4(%ecx), %ebx 
  jg NoSwap 
  movl %eax, %ebx #swap, so ebx is greater 
  movl 4(%ecx), %eax

NoSwap: 
  movl %eax, (%ecx) 
  movl %ebx, 4(%ecx) 
  movl $4, %eax
  addl %eax, %ecx 
  movl $1, %eax 
  subl%eax, %esi 
  jne InnerLoop  
  popl %esi 
  movl $1, %eax 
  subl %eax, %esi 
  jne OuterLoop  
bubbleEnd: 
  popl %edx 
  popl %ebx 
  popl %esi 
  movl %ebp, %esp 
  popl %ebp 
  ret

InnerLoop内改成:(edx是循环利用)

movl(%ecx), %edx  
InnerLoop:
  movl %edx, %eax 
  movl 4(%ecx), %ebx 
  subl %ebx, %eax  # compare *pand *(p+1) 
  cmovl %ebx, %edx  #edx is maxmovl (%ecx), %eax  
  cmovg %ebx, %eax    #%eax is min
  movl %edx, 4(%ecx)
  movl %eax, (%ecx)
  movl $4, %eax 
  addl %eax, %ecx
  movl $1, %eax
  subl %eax, %esi
  jne InnerLoop
  • 任务二
把课上练习3的daytime服务器分别用多进程和多线程实现成并发服务器并测试

多进程:

#include "csapp.h"
void echo(int connfd);

void sigchld_handler(int sig)
{
    while (waitpid(-1, 0, WNOHANG) > 0)
        ;
    return;
}

int main(int argc, char **argv)
{
    int listenfd, connfd, port, clientlen=sizeof(struct sockaddr_in);
    struct sockaddr_in clientaddr;

    if (argc != 2) {
        fprintf(stderr, "usage: %s <port>\n", argv[0]);
        exit(0);
    }
    port = atoi(argv[1]);

    Signal(SIGCHLD, sigchld_handler);
    listenfd = Open_listenfd(port);
    while (1) {
        connfd = Accept(listenfd, (SA *) &clientaddr, &clientlen);
        if (Fork() == 0) {
            Close(listenfd); /* Child closes its listening socket */
            echo(connfd);    /* Child services client */
            Close(connfd);   /* Child closes connection with client */
            exit(0);         /* Child exits */
        }
        Close(connfd); /* Parent closes connected socket (important!) */
    }
}
void echo(int connfd)
{
    size_t n;
    char buf[MAXLINE];
    rio_t rio;

    Rio_readinitb(&rio, connfd);
    while((n = Rio_readlineb(&rio, buf, MAXLINE)) != 0) {
        printf("客户端IP:127.0.0.1\n");
        printf("服务器实现学号:20155205\n");
        printf("server received %d bytes\n", n);
        time_t t;
        time(&t);
        printf("当前时间:%s\n",ctime(&t));
        Rio_writen(connfd, buf, n);
    }
}

多线程:

#include "csapp.h"

void echo(int connfd);
void *thread(void *vargp);

int main(int argc, char **argv)
{
    int listenfd, *connfdp, port, clientlen=sizeof(struct sockaddr_in);
    struct sockaddr_in clientaddr;
    pthread_t tid;

    if (argc != 2) {
        fprintf(stderr, "usage: %s <port>\n", argv[0]);
        exit(0);
    }
    port = atoi(argv[1]);

    listenfd = Open_listenfd(port);
    while (1) {
        connfdp = Malloc(sizeof(int));
        *connfdp = Accept(listenfd, (SA *) &clientaddr, &clientlen);
        Pthread_create(&tid, NULL, thread, connfdp);
    }
}
void *thread(void *vargp)
{
    int connfd = *((int *)vargp);
    Pthread_detach(pthread_self());
    Free(vargp);
    echo(connfd);
    Close(connfd);
    return NULL;
}
void echo(int connfd)
{
    size_t n;
    char buf[MAXLINE];
    rio_t rio;

    Rio_readinitb(&rio, connfd);
    while((n = Rio_readlineb(&rio, buf, MAXLINE)) != 0) {
        printf("客户端IP:127.0.0.1\n");
        printf("服务器实现学号:201552\n");
        printf("server received %d bytes\n", n);
        time_t t;
        time(&t);
        printf("当前时间:%s\n",ctime(&t));
        Rio_writen(connfd, buf, n);
    }
}

遇到的问题及解决方案

  • 问题一:无法运行server

  • 问题一解决方案:前面加上sudo。

  • 问题二:无法使用csapp.h头文件

  • 问题二解决方案:在csapp.h中#endif 前加上#include<csapp.c所在路径>方可使用。

  • 问题三:y86模拟器总会出现下图错误,只要是自己写的.ys文件都make不了:

  • 问题三解决方案:还在积极解决。。。

  • 代码链接

posted on 2017-11-12 15:30  郝博雅  阅读(253)  评论(0编辑  收藏  举报