zoukankan      html  css  js  c++  java
  • 2017-2018-1 20155312 《信息安全系统设计基础》第八周学习总结

    2017-2018-1 20155312 《信息安全系统设计基础》第八周学习总结

    教材学习内容总结

    网络编程、并发编程

    课堂实践

    在这次课堂实践的前一天,我按照以下步骤为虚拟机分配共享数据空间:

    1. 在虚拟机的设置里设定一个本地主机的文件夹vboxshare作为共享文件夹
    2. 启动Ubuntu,打开终端窗口
      输入命令“sudo mkdir /mnt/shared”回车后键入密码
    3. 输入命令“sudo mount –t vboxsf vboxshare /mnt/shared"
    4. 输入命令“sudo gedit /etc/fstab”
      在弹出的文本末尾添加:
      “vboxshare /mnt/shared vboxsf rw,gid=100,uid=1000,auto 0 0”

    结果没有共享成功,关闭虚拟机再打开时进入了“welcome to emergency code”无法进入图形化界面。

    我第一个想到可能是因为我修改了系统文件/etc/fastab,可能改回去就好了,但是周二晚上我输入vi /etc/fastab时提示server什么的,总之就是进不去,心态崩了。然后试了各种方法,比如alt+ctrl+f7;startx;alt+ctrl+f1+f6;alt+f7;alt+ctrl+shift+f7;init 5;init3;删除X11中的配置文件“rm /etc/X11/xorg.conf”……总之都是徒劳。

    最后尝试了一通,我选择重装一个虚拟机,但是更新系统更新到凌晨,也没有更新完,更别提安装vim等必备软件了。

    修复虚拟机

    借备用电脑熬过了课堂实践,我终于再次抱着试一试的心态去解决这个问题,开机后依旧显示“GIVE root password for maintenance (or type control-D to continue): ……”,首先输入“vi /etc/fstab”尝试改回自己修改了的系统文件,神奇的是这一次进去了!接着用dd 删除刚刚添加的那行“vboxshare /mnt/shared vboxsf rw,gid=100,uid=1000,auto 0 0”,准备保存时,发现无法输入wq保存,这是因为在这种模式下是没有写权限的,需要输入“mount / -o remount”挂载root权限,然后就可以编辑修改/etc/fastab文件了,最后输入reboot。重启一下就好了。

    系统快照

    根据这段经历,我第一次意识到了备份、快照的重要性(真的是只有虚拟机坏了才会意识到备份有多么重要)。所以准备研究一下怎么弄系统快照,其实很简单,步骤如下:

    首先打开virtualbox后选择想要备份的虚拟机,点击右上角的"备份[系统快照]",然后输入备份名称和描述,等几秒钟就备份完成了,创建完毕后可以在主界面看到创建的快照极其相关信息,如下图所示:

    当我们虚拟机出现了问题,我们可以选择“恢复备份”,回到备份状态;如果想要删除这个备份,可以点击删除备份。关机时,系统还会提示我们是否恢复备份,一般情况下我们忽略掉它就好。

    任务一

    4.47

    A :修改代码用指针索引数组而不是数组,并添加了测试代码如下:

     1 #include<stdio.h>
      2 
      3 void bubble_a(long *data,long count)
      4 {
      5     long i,last,t;
      6     for(last = count-1;last>0;last--)
      7     {
      8         for(i = 0;i<last;i++)
      9         {
     10             if(*(data+i+1)<*(data+i))
     11             {
     12                 t=*(data+i+1);
     13                 *(data+i+1)=*(data+i);
     14                 *(data+i)=t;
     15             }
     16         }
     17     }
     18 }
     19 int main()
     20 {
     21     int i;
     22     long data[10] = {2,3,4,5,6,7,8,9,0,1};
     23     bubble_a(data,10);
     24     for(i=0;i<10;i++)
     25     {
     26         printf("%d
    ",*(data+i));
     27     }
     28     return 0;
     29 }
    

    运行后没有问题,可以实现升序排列:

    B:接着先利用objdump -d 1来查看可执行文件的反汇编代码,依次输入以下指令查看汇编代码:

    gcc -E paixu1.c -o paixu1.i
    gcc-S paixu1.i -o paixu1.s
    vi paixu1.s
    

    然后删除“.”开头的注释部分,留下的汇编代码如下:

      1 bubble_a:
      2     pushq   %rbp
      3     movq    %rsp, %rbp
      4     movq    %rdi, -40(%rbp)
      5     movq    %rsi, -48(%rbp)
      6     movq    -48(%rbp), %rax
      7     subq    $1, %rax
      8     movq    %rax, -16(%rbp)
      9     jmp .L2 
     10 .L6:
     11     movq    $0, -24(%rbp)
     12     jmp .L3 
     13 .L5:
     14     movq    -24(%rbp), %rax
     15     addq    $1, %rax
     16     leaq    0(,%rax,8), %rdx
     17     movq    -40(%rbp), %rax
     18     addq    %rdx, %rax 
     19     movq    (%rax), %rdx
     20     movq    -24(%rbp), %rax
     21     leaq    0(,%rax,8), %rcx
     22     movq    -40(%rbp), %rax
     23     addq    %rcx, %rax 
     24     movq    (%rax), %rax
     25     cmpq    %rax, %rdx
     26     jge .L4 
     27     movq    -24(%rbp), %rax
     28     addq    $1, %rax
     29     leaq    0(,%rax,8), %rdx
     30     movq    -40(%rbp), %rax
     31     addq    %rdx, %rax 
     32     movq    (%rax), %rax
     33     movq    %rax, -8(%rbp)
     34     movq    -24(%rbp), %rax
     35     addq    $1, %rax
    36     leaq    0(,%rax,8), %rdx
     37     movq    -40(%rbp), %rax
     38     addq    %rax, %rdx
     39     movq    -24(%rbp), %rax
     40     leaq    0(,%rax,8), %rcx
     41     movq    -40(%rbp), %rax
     42     addq    %rcx, %rax
     43     movq    (%rax), %rax
     44     movq    %rax, (%rdx)
     45     movq    -24(%rbp), %rax
     46     leaq    0(,%rax,8), %rdx
     47     movq    -40(%rbp), %rax
     48     addq    %rax, %rdx
     49     movq    -8(%rbp), %rax
     50     movq    %rax, (%rdx)
     51 .L4:
     52     addq    $1, -24(%rbp)
     53 .L3:
     54     movq    -24(%rbp), %rax
     55     cmpq    -16(%rbp), %rax
     56     jl  .L5
     57     subq    $1, -16(%rbp)
     58 .L2:
     59     cmpq    $0, -16(%rbp)
     60     jg  .L6
     61     nop
     62     popq    %rbp
     63     ret
     64 .LFE0:
     65 .LC0:
     66 main:
     67 .LFB1:
     68     pushq   %rbp
     69     movq    %rsp, %rbp
     70     subq    $112, %rsp
     71     movq    %fs:40, %rax
     72     movq    %rax, -8(%rbp)
     73     xorl    %eax, %eax
     74     movq    $2, -96(%rbp)
     75     movq    $3, -88(%rbp)
     76     movq    $4, -80(%rbp)
     77     movq    $5, -72(%rbp)
     78     movq    $6, -64(%rbp)
     79     movq    $7, -56(%rbp)
     80     movq    $8, -48(%rbp)
     81     movq    $9, -40(%rbp)
     82     movq    $0, -32(%rbp)
     83     movq    $1, -24(%rbp)
     84     leaq    -96(%rbp), %rax
     85     movl    $10, %esi
     86     movq    %rax, %rdi
     87     call    bubble_a
     88     movl    $0, -100(%rbp)
     89     jmp .L8
     90 .L9:
     91     movl    -100(%rbp), %eax
     92     cltq
     93     leaq    0(,%rax,8), %rdx
     94     leaq    -96(%rbp), %rax
     95     addq    %rdx, %rax
     96     movq    (%rax), %rax
     97     movq    %rax, %rsi
     98     movl    $.LC0, %edi
     99     movl    $0, %eax
    100     call    printf
    101     addl    $1, -100(%rbp)
    102 .L8:
    103     cmpl    $9, -100(%rbp)
    104     jle .L9
    105     movl    $0, %eax
    106     movq    -8(%rbp), %rcx
    107     xorq    %fs:40, %rcx
    108     je  .L11
    109     call    __stack_chk_fail
    110 .L11:
    111     leave
    112     ret
    113 .LFE1:
    

    书写Y86-64汇编指令时有几点需要注意:

    1. Y86-64中要把movq指令转换为具体的rrmovq,rmmovq,mrmovq指令;
    2. Y86-64中OPq只对寄存器数据进行操作,可以借用%r8-%r14这些寄存器,先用“irmovq”指令将立即数放入寄存器中,再进行相关计算;
    3. Y86-64中没有加载有效地址指令leaq,需要用“addq”等指令来代替其功能;
    4. Y86-64中没有比较指令“cmpq”,可以用两个寄存器存放操作数的值然后用subq命令使两数相减来设置条件码;
    5. Y86-64中没有乘指令mulq,需要用addq来替换;
    6. 第71行的“movq %fs:40, %rax”指令,需要弄清楚%fs:40的含义和类型;
    7. 由于Y86-64指令集中所以操作都以8个字节为单位,所以在转换“movl,addl”这些四字节指令时要额外注意,有时需要保护高四字节的值,例如:
    • movl $0,-100(%rbp) 可以用以下指令代替:
    143     irmovq  0xffffffff00000000,%r8
    144     mrmovq  -100(%rbp),%r9  #取8字节的内存单元-100(%rbp) 的值
    145     andq    %r8,%r9  #给低四个字节置0,高四个字节不变
    146     rmmovq  %r9, -100(%rbp) 
    
    • cmpl $9, -100(%rbp)可以用以下指令代替:
    161     mrmovq  -100(%rbp),%r9  #r9中是8字节的-100(%rbp)内存单元的值
    162     irmovq  0xffffffff,%r8
    163     andq    %r8,%r9  #保留r9低四个字节的值
    164     irmovq  $9,%r10
    165     subq    %r10,%r9  #用sub指令来设置条件码
    
    • movl $10, %esi:这里要注意movl在以寄存器作为目的时,会把寄存器的高位设为0 所以,无需保护高四字节的值,如以下指令所示:
    140     irmovq  $10,%r9
    141     rrmovq  %r9,%rsi
    
    • addl $1, -100(%rbp)可以用如下指令进行替换:
    170     mrmovq  -100(%rbp),%r8  #r8为8字节的内存单元-100(%rbp)的值
    171     irmovq  0xffffffff,%r9
    172     irmovq  $1,%r10
    173     addq    %r8,%r10  #先用八字节的数加1,结果放入r10
    174     andq    %r9,%r10  #只保留低四字节的值
    175     irmovq  0xffffffff00000000,%r11
    176     andq    %r8,%r11  #将内存单元中低四字节置0存入r11
    177     addq    %r11,%r10  #与刚才的和相加,结果原高四字节不变,低四字节加一
    178     rmmovq  %r10,-100(%rbp)
    
    1. cltq指令:用于把%eax符号扩展到%rax,所以要先判断%eax的符号位,再决定给高四个字节置1还是0;
    2. Y86-64指令集中没有leave指令,要用“rrmovq %rbp,%rsp”+“popq %rbp”来代替。

    但是,把初步编写的paixu1.ys文件拷贝到sim/y86-code里,并通过“make paixu.yo”生成y86-64编码时,提示出现了很多错误,如下图所示:

    参照y86-code文件夹中的正确代码asum.ys,我有几个疑问:

    1. 为什么这里用了四字节指令?教材P245页写了Y86-64指令集只包括8字节整数操作,这里如何解释?
    2. 为什么asum.ys可以利用make指令生成.yo文件,但是教材P252图4-7中的代码却不可以,运行make指令时同样会报错,如下所示:

    1. Y86-64是如何处理位运算和字节扩展运算的?它就只有addq,subq,andq,xorq四种运算而没有乘除运算吗?那如果这样怎么利用四种运算实现大整数乘法呢?

    通过在网上搜索,和询问周边同学,我没能找到答案。但是阅读了卢肖明学长第六周学习总结后,我发现Y86-64指令集和Y86指令集是不同的,Y86操作指令是4字节的,所以会出现以l为结尾的指令,自己下载的Y86模拟器应用在Y86指令集的基础上,与我们正在学习的Y86-64不匹配,所以即使输入书中原代码,也不会make成功。

    重新下载老师在蓝墨云中提供的y86-84模拟器,删除原来的y86模拟器。

    构建YIS步骤

    参考老师的给出的实验楼资源,重新构建YIS,步骤如下:

    1. cd ~/Code/shiyanlou_cs413
    2. wget http://labfile.oss.aliyuncs.com/courses/413/sim.tar
    3. tar -xvf sim.tar
    4. cd sim
    5. sudo apt-get install bison flex tk
    6. sudo ln -s /usr/lib/x86_64-linux-gnu/libtk8.6.so /usr/lib/libtk.so
    7. sudo ln -s /usr/lib/x86_64-linux-gnu/libtcl8.6.so /usr/lib/libtcl.so
    8. make

    测试YIS步骤如下:

    1. cd y86-code
    2. 进入测试代码,教材p239页代码为asuml.ys,可以通过make asuml.yo进行汇编,asuml.yo就是汇编后的结果,见教材p238。
    3. make all可以汇编运行所有代码结果
    修正Y86-64汇编代码的错误

    ma在刚在新下载的sim文件夹中make一下,查看生成的yo文件。这次试用新的模拟器,再对paixu1.ys反汇编一下,发现错误少了不少,我将其归为四类:

    1. %fs:40看样子不是普通的寄存器,通过冒号我们可以想到这%fs:应该是在指明段。将117行改成irmovq、mrmovq,194行用寄存器中转一下试试;
    2. 真正的Y86-64是没有%eax寄存器的,这里忘了把它改成%rax;
    3. 前面已经转换了这句addl,忘记删掉原句了;
    4. y86-64中没有设计具体的系统异常处理模块,所以不会识别这里的堆栈错误处理模块。

    修改后再次运行“make paixu1.yo”,还是出现了两类错误:

    1. %fs:40的含义还是没有理解,通过查询资料,我得知FS是x86-64中附加段寄存器(Extra Segment Register),其值为附加数据段的段值,但是y86-64没有这种加段超越前缀的寻址方式,而且貌似也没有这个附加数据段寄存器。“40”像个内存地址,因为加段超越前缀访问内存单元的方式一般是段超越前缀+地址;
    2. y86-64指令集是没有字节扩展指令的,偷了个懒不改cltq果然是不行,可以取出%rax的低四个字节,与0相比较,如果大于则说明%eax为正数,高四字节扩展为全0;如果小于说明eax为负数,扩展时需要将高四字节置1。代码如下:
    154     irmovq  0xffffffff,%r8
    155     mrmovq  -100(%rbp),%r9
    156     andq    %r8,%r9
    157     rrmovq  %r9, %rax
    158 #从这里开始
    159     andq    %r8,%r9
    160     irmovq  $0,%r10
    161     subq    %r10,%r9
    162     jl      zhengshu
    163     irmovq    0xffffffff00000000,%r11
    164     addq    %r11,%rax
    165 zhengshu:
    
    

    最后调整了call printf这个小错误后,终于生成了.yo文件。
    经过反复修改的最终版paixu1.ys代码如下:

      1 .pos 0
      2     irmovq stack,%rsp
      3     call main
      4     halt
      5 bubble_a:
      6     pushq   %rbp
      7     rrmovq  %rsp, %rbp
      8     rmmovq  %rdi, -40(%rbp)
      9     rmmovq  %rsi, -48(%rbp)
     10     mrmovq  -48(%rbp), %rax
     11     irmovq  $1,%r8
     12     subq    %r8, %rax
     13     rmmovq  %rax, -16(%rbp)
     14     jmp L2
     15 L6:
     16     irmovq  $0,%r9
     17     rmmovq  %r9, -24(%rbp)
     18     jmp L3
     19 L5:
     20     mrmovq  -24(%rbp), %rax
     21     irmovq  $1,%r10
     22     addq    %r10, %rax
     23     rrmovq  %rax,%r8
     24     addq    %r8,%r8
     25     addq    %r8,%r8
     26     addq    %r8,%r8
     27     rrmovq  %r8,%rdx
     28     mrmovq  -40(%rbp), %rax
     29     addq    %rdx, %rax
     30     mrmovq  (%rax), %rdx
     31     mrmovq  -24(%rbp), %rax
     32     rrmovq  %rax,%r8
     33     addq    %r8,%r8
     34     addq    %r8,%r8
    35     addq    %r8,%r8
     36     rrmovq  %r8,%rcx
     37     mrmovq  -40(%rbp), %rax
     38     addq    %rcx, %rax
     39     mrmovq  (%rax), %rax
     40     rrmovq  %rax,%r9
     41     rrmovq  %rdx,%r10
     42     subq    %r9, %r10
     43     jge L4
     44     mrmovq  -24(%rbp), %rax
     45     irmovq  $1,%r8
     46     addq    %r8, %rax
     47     rrmovq  %rax,%r8
     48     addq    %r8,%r8
     49     addq    %r8,%r8
     50     addq    %r8,%r8
     51     rrmovq  %r8,%rdx
     52     mrmovq  -40(%rbp), %rax
     53     addq    %rdx, %rax
     54     mrmovq  (%rax), %rax
     55     rmmovq  %rax, -8(%rbp)
     56     mrmovq  -24(%rbp), %rax
     57     irmovq  $1,%r8
     58     addq    %r8, %rax
     59     rrmovq  %rax,%r8
     60     addq    %r8,%r8
     61     addq    %r8,%r8
     62     addq    %r8,%r8
     63     rrmovq  %r8,%rdx
     64     mrmovq  -40(%rbp), %rax
     65     addq    %rax, %rdx
     66     mrmovq  -24(%rbp), %rax
     67     rrmovq  %rax,%r8
     68     addq    %r8,%r8
    69     addq    %r8,%r8
     70     addq    %r8,%r8
     71     rrmovq  %r8,%rcx
     72     mrmovq  -40(%rbp), %rax
     73     addq    %rcx, %rax
     74     mrmovq  (%rax), %rax
     75     rmmovq  %rax, (%rdx)
     76     mrmovq  -24(%rbp), %rax
     77     rrmovq  %rax,%r8
     78     addq    %r8,%r8
     79     addq    %r8,%r8
     80     addq    %r8,%r8
     81     rrmovq  %r8,%rdx
     82     mrmovq  -40(%rbp), %rax
     83     addq    %rax, %rdx
     84     mrmovq  -8(%rbp), %rax
     85     rmmovq  %rax, (%rdx)
     86 L4:
     87     irmovq  $1,%r9
     88     mrmovq  -24(%rbp),%r10
     89     addq    %r9,%r10
     90     rmmovq  %r10,-24(%rbp)
     91 L3:
     92     mrmovq  -24(%rbp), %rax
     93     mrmovq  -16(%rbp),%r8
     94     rrmovq  %rax,%r9
     95     subq    %r8,%r9
     96     jl  L5
     97     irmovq  $1,%r10
     98     mrmovq  -16(%rbp),%r11
     99     subq    %r10,%r11
    100     rmmovq  %r11,-16(%rbp)
    101 L2:
    102     irmovq  $0,%r8
    103     mrmovq  -16(%rbp),%r9
    104     subq    %r8, %r9
    105     jg  L6
    106     nop
    107     popq    %rbp
    108     ret
    109 LFE0:
    110 LC0:
    111 main:
    112 LFB1:
    113     pushq   %rbp
    114     rrmovq  %rsp, %rbp
    115     irmovq  $112,%r8
    116     subq    %r8, %rsp
    117 #   mrmovq  %fs:40, %rax
    118 #   rmmovq  %rax, -8(%rbp)
    119     xorq    %rax, %rax
    120     irmovq  $2, %r8
    121     rmmovq  %r8, -96(%rbp)
    122     irmovq  $3, %r8
    123     rmmovq  %r8, -88(%rbp)
    124     irmovq  $4, %r8
    125     rmmovq  %r8, -80(%rbp)
    126     irmovq  $5, %r8
    127     rmmovq  %r8, -72(%rbp)
    128     irmovq  $6, %r8
    129     rmmovq  %r8, -64(%rbp)
    130     irmovq  $7, %r8
    131     rmmovq  %r8, -56(%rbp)
    132     irmovq  $8, %r8
    133     rmmovq  %r8, -48(%rbp)
    134     irmovq  $9, %r8
    135     rmmovq  %r8, -40(%rbp)
    136     irmovq  $0, %r8
    137     rmmovq  %r8, -32(%rbp)
    138     irmovq  $1, %r8
    139     rmmovq  %r8, -24(%rbp)
    140     rrmovq  %rbp,%r9
    141     irmovq  $-96,%r10
    142     subq    %r10,%r9
    143     rrmovq  %r9,%rax
    144     irmovq  $10,%r9
    145     rrmovq  %r9,%rsi
    146     rrmovq  %rax, %rdi
    147     call    bubble_a
    148     irmovq  0xffffffff00000000,%r8
    149     mrmovq  -100(%rbp),%r9
    150     andq    %r8,%r9
    151     rmmovq  %r9, -100(%rbp)
    152     jmp L8
    153 L9:
    154     irmovq  0xffffffff,%r8
    155     mrmovq  -100(%rbp),%r9
    156     andq    %r8,%r9
    157     rrmovq  %r9, %rax
    158 
    159     andq    %r8,%r9
    160     irmovq  $0,%r10
    161     subq    %r10,%r9
    162     jl      zhengshu
    163     irmovq    0xffffffff00000000,%r11
    164     addq    %r11,%rax
    165 zhengshu:
    166     rrmovq  %rax,%r8
    167     addq    %r8,%r8
    168     addq    %r8,%r8
    169     addq    %r8,%r8
    170     rrmovq  %r8,%rdx
    171     irmovq  $-96,%r9
    172     rrmovq  %rbp,%r10
    173     addq    %r9,%r10
    174     rrmovq  %r10,%rax
    175     addq    %rdx, %rax
    176     mrmovq  (%rax), %rax
    177     rrmovq  %rax, %rsi
    178     irmovq  $LC0, %rdi
    179     irmovq  $0, %rax
    180 #   call    printf
    181     mrmovq  -100(%rbp),%r8
    182     irmovq  0xffffffff,%r9
    183     irmovq  $1,%r10
    184     addq    %r8,%r10
    185     andq    %r9,%r10
    186     irmovq  0xffffffff00000000,%r11
    187     andq    %r8,%r11
    188     addq    %r11,%r10
    189     rmmovq  %r10,-100(%rbp)
    190 L8:
    191     mrmovq  -100(%rbp),%r9
    192     irmovq  0xffffffff,%r8
    193     andq    %r8,%r9
    194     irmovq  $9,%r10
    195     subq    %r10,%r9
    196     jle L9
    197     irmovq  0xffffffff00000000,%r8
    198     andq    %r8,%rax
    199 #   mrmovq  -8(%rbp), %rcx
    200 #   mrmovq  %fs:40,%r8
    201 #   xorq    %r8, %rcx
    202 #   je  L11
    203 
    204 L11:
    205     rrmovq  %rbp,%rsp
    206     popq    %rbp
    207     ret
    208 LFE1:
    209 
    210 .pos 0x600
    211 stack:
    
    • 对于把Y86汇编翻译成机器码比较简单,如果.ys文件书写正确,那么生成的.yo文件左侧就是汇编指令对应的机器码如下图所示:

    • 如果不利用现有工具,我们完全可以利用教材P246-247两页的知识将Y86汇编翻译成机器码,翻译的方法总结如下:
    1. 通过观察指令在图4-2中确定机器码的第一个字节,如果是OPq,jXX,comvXX指令,还需要通过图4-3进一步确定第一个字节中的低4位“功能部分”;
    2. 涉及到寄存器的指令,例如rrmovq,irmovq,rmmovq等,需要根据指令中具体制定的寄存器,查图4-4中寄存器对应的数字,无寄存器用f表示;
    3. 涉及立即数、偏移地址、转移地址等数字时,要将数字的十六进制表示高位补零直至满足图4-2中的标准位数,补全后利用小端方式(低位在左、高位在右)将该数字翻译成机器中存放的数字。

    4.48不使用跳转,最多使用3次条件传送

     1 #include<stdio.h>
      2 
      3 void bubble_a(long *data,long count)
      4 {
      5     long i,last,t,j;
      6     for(last = count-1;last>0;last--)
      7     {
      8         for(i = 0;i<last;i++)
      9         {
     10            t=*(data+i)-*(data+i+1); 
     11            if(t>0){
     12                 *(data+i)=t;
     13                 *(data+i)=*(data+i+1);
     14                 *(data+i+1)=t;
     15             }
     16         }
     17     }
     18 }
     19 int main()
     20 {
     21     int i;
     22     long data[10] = {2,3,4,5,6,7,8,9,0,1};
     23     bubble_a(data,10);
     24     for(i=0;i<10;i++)
     25     {
     26         printf("%d
    ",*(data+i));
     27     }
     28     return 0;
     29 }
    

    这段代码没有使用跳转指令,而是通过“
    *(data+i)-*(data+i+1)”来设置条件码,通过comvg条件传送指令实现if(j>0)中的三个赋值语句。

    4.49不使用跳转,最多使用1次条件传送

    分析:要实现两个数的交换但是最多只使用1次条件传送指令可能需要我们借助栈来保存其中一个操作数的值。代码如下:

      1 #include<stdio.h>
      2 #include"duizhan.h"
      3 
      4 void bubble_a(long *data,long count)
      5 {
      6     long i,last,t,j;
      7     struct Stack* ps;
      8     init(ps);
      9     for(last = count-1;last>0;last--)
     10     {
     11         for(i = 0;i<last;i++)
     12         {
     13              j=*(data+i)-*(data+i+1);
     14             if(j>0)
     15             {
     16                 push(ps,*(data+i+1));
     17                 *(data+i+1)=*(data+i);
     18                 pop(ps,data+i);
     19             }
     20         }
     21     }
     22 }
     23 int main()
     24 {
     25     int i;
     26     long data[10] = {2,3,4,5,6,7,8,9,0,1};
     27     bubble_a(data,10);
     28     for(i=0;i<10;i++)
     29     {
     30         printf("%d
    ",*(data+i));
     31     }
     32     return 0;
     33 }
    

    书写这段代码之前,需要先编辑一个包含栈操作的头文件duizhan.h,其中包含栈的初始化函数init(),入栈函数push(),弹栈函数
    pop()等。通过栈来保存操作数*(data+i)的值,减少了传送指令的使用次数,所以只需要根据条件码,利用一次条件传送指令给*(data+i+1)赋值即可。

    任务二

    多进程将daytime服务器实现为并发服务器:

    多线程将daytime服务器实现为并发服务器:

    码云链接_1

    码云链接_2

  • 相关阅读:
    使用GitLab搭建Git仓库
    SpringBoot web开发
    springboot配置
    springboot自动配置原理
    springboot修改端口号
    springboot创建方式
    junit运行多个测试的方法
    junit常用注解
    junit断言
    sublime将.m文件关联MATLAB类型高亮
  • 原文地址:https://www.cnblogs.com/zjy1997/p/7822778.html
Copyright © 2011-2022 走看看