20155212 2017-2018-1 《信息安全系统设计》第8周课下作业

20155212 2017-2018-1 《信息安全系统设计》第8周课下作业

题目1

  1. 完成家庭作业4.47,4.48,4.49
  2. 相应代码反汇编成X86-64汇编
  3. 把上述X86-64汇编翻译成Y86汇编,并给出相应机器码
  4. 发操作过程、测试、问题解决过程博客链接

4.47

A. 书写并测试一个C版本,用指针引用数组元素,而不是用数组索引。
  • 用指针引用数组元素:
#include <stdio.h>
/*Bubble sorts:Pointer version*/
void bubble_p(long *data,int count){
    long i, last, t;
    for(last = count-1; last > 0; last--){ 
        for(i = 0; i < last; i++){
            if(*(data+i+1)<*(data+i)){
                t = *(data+i+1);
                *(data+i+1) = *(data+i);
                *(data+i) = t;
            }
        }
    }
}

void main(){
    int i;
    long data[5]={4, 1, 0, 2, 3};
    bubble_p(data, 5);
    for(i=0; i<5; i++)
    {
        printf("%ld\t", *(data+i));
    }
    printf("\n");
}
  • 运行结果
    1043723-20171112214050278-1477170546.png
B. 书写并测试这个函数和测试代码组成的Y86-64程序。
  • 使用gcc -E Bubble.c -Og -o Bubble1.igcc -S Bubble.c -Og -o Bubble1.s编译代码,这样生成符合原始C代码整体结构的机器代码的优化等级,便于理解。
  • X86-64汇编代码
bubble_p:
    leal    -1(%rsi), %r9d
    movslq  %r9d, %r9
    jmp .L2
.L4:
    leaq    8(%rdi,%rax,8), %rsi
    movq    (%rsi), %rcx
    leaq    (%rdi,%rax,8), %rdx
    movq    (%rdx), %r8
    cmpq    %r8, %rcx
    jge .L3
    movq    %r8, (%rsi)
    movq    %rcx, (%rdx)
.L3:
    addq    $1, %rax
    jmp .L5
.L6:
    movl    $0, %eax
.L5:
    cmpq    %r9, %rax
    jl  .L4
    subq    $1, %r9
.L2:
    testq   %r9, %r9
    jg  .L6
    rep ret
.LC0:
main:
    pushq   %rbx
    subq    $48, %rsp
    movq    %fs:40, %rax
    movq    %rax, 40(%rsp)
    xorl    %eax, %eax
    movq    $4, (%rsp)
    movq    $1, 8(%rsp)
    movq    $0, 16(%rsp)
    movq    $2, 24(%rsp)
    movq    $3, 32(%rsp)
    movl    $5, %esi
    movq    %rsp, %rdi
    call    bubble_p
    movl    $0, %ebx
    jmp .L8
.L9:
    movslq  %ebx, %rax
    movq    (%rsp,%rax,8), %rdx
    movl    $.LC0, %esi
    movl    $1, %edi
    movl    $0, %eax
    call    __printf_chk
    addl    $1, %ebx
.L8:
    cmpl    $4, %ebx
    jle .L9
    movl    $10, %edi
    call    putchar
    movq    40(%rsp), %rax
    xorq    %fs:40, %rax
    je  .L10
    call    __stack_chk_fail
.L10:
    addq    $48, %rsp
    popq    %rbx
    ret
  • Y86-64代码

.pos 0
    irmovq stack,%rsp
    call main
    halt
bubble_p:
    irmovq $1, %r8
    subq %r8, %rsi
    rrmovq %rsi, %r9
    rrmovq %r9, %r9
    jmp .L2
.L4:
    addq %rax, %rax
    addq %rax, %rax
    addq %rax, %rax
    addq %rdi, %rax
    irmovq $8, %r10
    addq %r10, %rax
    rrmovq %rax, %rsi
    mrmovq (%rsi), %rcx
    rrmovq %rax, %r8
    addq %r8, %r8
    addq %r8, %r8
    addq %r8, %r8
    addq %rdi, %r8
    rrmovq %r8, %rdx
    mrmovq (%rdx), %r8
    rrmovq %rcx, %r10
    subq %r8, %r10
    jge .L3
    rmmovq %r8, (%rsi)
    rmmovq %rcx, (%rdx)
.L3:
    irmovq $1, %r8
    addq %r8, %rax
    jmp .L5
.L6:
    irmovq $0, %r8
    rrmovq %r8, %rax
.L5:
    rrmovq %rax, %r10
    subq    %r9, %r10
.L2:
    jg .L6
    ret
main:
    pushq %rbp
    irmovq $48, %r8
    rrmovq %r8, %rsp
    xorq %rax, %rax
    irmovq $4, %r8
    rmmovq %r8, (%rbp)
    irmovq $1, %r8
    rmmovq %r8, 8(%rbp)
    irmovq $0, %r8
    rmmovq %r8, 16(%rbp)
    irmovq $2, %r8
    rmmovq %r8, 24(%rbp)
    irmovq $3, %r8
    rmmovq %r8, 32(%rbp)
    irmovq $5, %r8
    rrmovq %r8, %rsi
    rrmovq %rsp, %rdi
    call bubble_p
    irmovq $0, %r9
    rrmovq %r9 ,%rbx
    jmp .L8
.L9:
    rrmovq %rbx, %rax
    rrmovq %rax, %r8
    addq %r8, %r8
    addq %r8, %r8
    addq %r8, %r8
    addq %rsp, %r8
    rrmovq %r8, %rdx
    irmovq $1, %r10
    rrmovq %r10, %rdi
    irmovq $0, %r8
    rrmovq %r8, %rax
    call _printf_chk
    rrmovq %r10, %rbx
.L8:
    irmovq $4, %rbx
    jle .L9
    irmovq $10, %rdi
    call putchar
    mrmovq 40(%rsp), %rax
    je .L10
    call _stack_chk_fail
.L10:
    irmovq $48, %r8
    addq %r8, %rsp
    popq %rbx
    ret

.pos 0x200
stack:

1043723-20171114223825609-1978049077.png
1043723-20171114223913999-1354801266.png

  • 主要修改内容
    • leaq:要与``movq```类区分开
    • movq:要根据源和目的的类型划分为不同的四种命令
    • addq类:必须是寄存器之间才能操作
    • cmpq:将第二操作数放到新寄存器,然后subq

4.48

  • 不使用跳转,最多使用3次条件传送
    - 代码
    ```
    #include <stdio.h>
    /Bubble sorts:Pointer version/
    void bubble_p(long data,int count){
    long i, last, t;
    for(last = count-1; last > 0; last--){
    for(i = 0; i < last; i++){
    if(
    (data+i+1)<(data+i)){
    t =
    (data+i)-(data+i+1);
    if(t>0){
    t =
    (data+i);
    (data+i) = (data+i+1);
    *(data+i+1) = t;
    }
    }
    }
    }
    }

    void main(){
    int i;
    long data[5]={4, 1, 0, 2, 3};
    bubble_p(data, 5);
    for(i=0; i<5; i++)
    {
    printf("%ld\t", *(data+i));
    }
    printf("\n");
    }
    ```
    • 分析:通过“t=(data+i)-(data+i+1)”来设置条件码,通过comvg条件传送指令实现if(t>0)中的三个赋值语句

4.48

  • 不使用跳转,最多使用1次条件传送
    • 代码
    #include <stdio.h>
    #include <stack>
    using namespace std;
    
    /*Bubble sorts:Pointer version*/
    void bubble_p(long *data, int count) {
        long i, last, t;
        stack <long> S;
        for (last = count - 1; last > 0; last--) {
            for (i = 0; i < last; i++) {
                if (*(data + i + 1)<*(data + i)) {
                    t = *(data + i) - *(data + i + 1);
                    if (t>0) {
                        S.push(*(data+i+1));
                        *(data + i + 1) = *(data+i);
                        *(data + i) = S.top();
                        S.pop();
                    }
                }
            }
        }
    }
    
    void main() {
        int i;
        long data[5] = { 4, 1, 0, 2, 3 };
        bubble_p(data, 5);
        for (i = 0; i<5; i++)
        {
            printf("%ld\t", *(data + i));
        }
        printf("\n");
    }
    • 分析:使用栈。这里我调用了stack库。

      题目2

      把课上练习3的daytime服务器分别用多进程和多线程实现成并发服务器并测试

基于socket 使用教材的csapp.h, csapp.c

实现daytime(13)服务器(端口我们使用13+后三位学号)和客户端
服务器响应消息格式是

客户端IP:XXXX
服务器实现者学号:XXXXXXXX
当前时间: XX:XX:XX

提交一个客户端至少查询三次时间的截图测试截图
提交至少两个客户端查询时间的截图测试截图

  • Daytime

    DAYTIME协议是基于TCP的应用,是一种有用的调试工具,它的作用是返回当前时间和日期,格式是字符串格式。

    • 基于TCP的daytime服务:daytime服务是基于TCP的应用,服务器在TCP端口13侦听,一旦有连接建立就返回ASCII形式的日期和时间,在传送完后关闭连接。接收到的数据被忽略。
    • 基于UDP的daytime服务:daytime服务也可以使用UDP协议,它的端口也是13,不过UDP是用数据报传送当前时间的。接收到的数据被忽略。
    • Daytime格式:Weekday, Month Day, Year Time-Zone
  • 使用man -k time | grep 2查看系统调用1043723-20171207230041659-1393703675.png
  • 使用man 2 time查看time()1043723-20171207234129425-1756878171.png
  • 查看localtime()1043723-20171207235818456-2080379902.png
  • tm结构体
    c struct tm { int tm_sec; /* Seconds (0-60) */ int tm_min; /* Minutes (0-59) */ int tm_hour; /* Hours (0-23) */ int tm_mday; /* Day of the month (1-31) */ int tm_mon; /* Month (0-11) */ int tm_year; /* Year - 1900 */ int tm_wday; /* Day of the week (0-6, Sunday = 0) */ int tm_yday; /* Day in the year (0-365, 1 Jan = 0) */ int tm_isdst; /* Daylight saving time */ };

  • 多线程结果
    1043723-20171208014813503-125680943.png1043723-20171208014837597-135780847.png
  • 多进程结果1043723-20171208020021378-125562788.png

转载于:https://www.cnblogs.com/dky20155212/p/7823349.html

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值