• # 2017-2018-1 20155219 《信息安全系统设计基础》第5周学习总结


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

    教材学习内容总结

    X86 寻址方式:

    • DOS时代的平坦模式,不区分用户空间和内核空间,很不安全
    • 8086的分段模式
    • IA32的带保护模式的平坦模式
      ISA的定义

    指令集体系结构(ISA)定义了处理器状态、指令的格式、以及每条指令对状态的影响。大多数ISA包括IA32和x84-64,将程序的行为描述成好像每条指令是按顺序执行的。
    汇编命令与反汇编命令

    用gcc -S xxx.c -o xxx.s 获得汇编代码,用gcc -c code.c产生目标文件code.o(二进制文件,无法直接查看),用objdump -d xxx.o反汇编可以查看目标代码文件内容。

    • 不同数据的汇编代码后缀
      image

    • 寻址方式
      image

    不同数据汇编代码后缀

    movb(传送字节)
    movw(传送字)
    movl(传送双字)注意:汇编代码中后缀l可以表示4自己整数和8字节双精度浮点数。

    数据传送指令

    MOVS和MOVZ指令比较:MOVS符号位扩展,MOVZ零扩展(高位0填充)

    pushl数据压栈,popl数据出栈。采用先进后出的原则。栈顶地址小,栈底地址大。IA32栈向低地址方向增长。所以push指令减小栈指针。

    4个整数操作指令
    addl、subl、andl、xorl

    7个跳转指令(jXX)jmp、jle、jl、je、jne、jge、jg

    有6个条件传送指令(cmovXX)
    只有当条件码满足所需要的约束时,才会更新目的寄存器的值。
    cmovle、cmovl、cmove、cmovne、cmovge、cmovg

    翻译条件分支

    将条件和表达式从C语言翻译成机器代码,最常用的方式是结合有条件和无条件跳转。
    C语言中if-else语句的通用形式:

    if(test-expr)
        then-statement
    else
        else-statement
    

    汇编结构:

     t=test-expr;
        if!(t)
            goto false;
        then-statement
        goto done;
    false:
        else-statement
    done:
    

    do-while循环

    C语言中do-while语句的通用形式:

    do
        body-statement
        while(test-expr);
    

    汇编结构:

    loop:
        body-statement
        t=test-expr;
        if(t)
            goto loop;
    

    while循环

    C语言中while语句的通用形式:

    while(test-expr)
        body-statement
    

    汇编结构:

      t=test-expr;
        if(!t)
            goto done;
    loop:
        body-statement
        t=test-expr;    
        if(t)
            goto loop;
    done:
    

    for循环

    C语言中for语句的通用形式:

    for(init-expr;test-expr;update-expr)
        body-statement
    

    汇编结构

    init-expr
        t=test-expr;
        if(!t)
            goto done;
    loop:
        body-statement
        update-expr;
        t=test-expr;
        if(t)
            goto loop;
        done:
    
    • 关于栈帧的gdb命令

    backtrace/bt:打印当前的函数调用栈的所有信息。后面加n或-n表示打印栈顶上n层(或者下n层)的栈信息。
    frame n:n为栈中的层编号,从0开始,类似C语言中数组的下标。移动到n指定的栈帧中去,并打印选中的栈的信息。如果没有n,则打印当前帧的信息。
    up n:表示向栈的顶移动n层。
    down n:表示向栈底移动n层。

    教材学习中的问题和解决过程

    • 1.已知下列C语言代码:
    void cond(int a,int *p)
    {
        if(p&&a>0)
            *p +=a;
    }
    

    按照与汇编代码等价的C语言goto版本,写一个与之等价的C语言代码。

    void goto_cond(int a,int *p)
    {
        if(p == 0)
            goto done;
        if(a<=0)
            goto done;
        *p +=a;
        done:
            return;
    }
    

    为什么C语言有一个if语句;
    而汇编中却有两个分支呢?

    第一个条件分支是&&表达式实现的一部份;如果对p是非空的测试失败,代码会直接跳过对a的测试。

    代码调试中的问题和解决过程

    • 编译代码
    int add(int x)
    {
        return x+3;
    }
    int raturn(int x)
    {
    return add(x);
    }
    int main(void)
    {
    return raturn(4)+1;
    }
    
    • 使用gcc -s xxx.c得到汇编结果如下图:

    • 将C语言文件编译成可执行文件并查看可执行文件的二进制内容

    • 删去汇编多出的辅助信息得到以下代码:
    add:
          pushl    %ebp            //保存,将父函数的栈底寄存器存入当前程序栈中
          movl    %esp, %ebp      //构造当前函数堆栈
          movl    8(%ebp), %eax   //从父函数堆栈中取得参数,存入ax寄存器
          addl    $3, %eax        //完成+3操作
          popl    %ebp            //恢复原父函数堆栈
    
      r_turn:
          pushl    %ebp            //保存,将父函数的栈底寄存器存入当前程序栈中
         movl    %esp, %ebp      //构造当前函数堆栈
         pushl    8(%ebp)        //
         movl    8(%ebp), %eax   
         call    add               //调用add
         addl    $4,%esp
     main:
         pushl    %ebp
         movl    %esp, %ebp
         push    $4        
         call    r_turn      
         addl    $4,%esp              
         addl    $1, %eax        //完成+1操作
    
    • objdump -d xxx.o得到反汇编结果如下图:

    通过gdb的调试可执行文件查看eip, ebp, esp 等寄存器内容如何变化。
    一开始调试时总是出问题,查资料后了解,在linux中gdb调试汇编文件需要先用gcc -g3 -o * *.c的命令来将c语言文件编译成可调试汇编的可执行文件。
    在64位中rip就是eip,rbp就是ebp,rsp就是esp。
    但仍出现如下问题:

    还没有解决.

    代码托管

    其他(感悟、思考等,可选)

    学习进度条

    代码行数(新增/累积) 博客量(新增/累积) 学习时间(新增/累积) 重要成长
    目标 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 10/70
    第五周 169/1469 2/9 14/84

    尝试一下记录「计划学习时间」和「实际学习时间」,到期末看看能不能改进自己的计划能力。这个工作学习中很重要,也很有用。
    耗时估计的公式
    :Y=X+X/N ,Y=X-X/N,训练次数多了,X、Y就接近了。

    参考:软件工程软件的估计为什么这么难软件工程 估计方法

    • 计划学习时间:10小时

    • 实际学习时间:14小时

    • 改进情况:

    (有空多看看现代软件工程 课件
    软件工程师能力自我评价表
    )

    参考资料

  • 相关阅读:
    Linux网络编程“惊群”问题总结
    MySql表结构修改详解
    String和ByteBuffer互转
    Java中String连接性能的分析
    java读取TXT文件的方法
    java文件和文件夹复制、删除、移动操作
    eclipse 导出jar 没有主清单属性的解决方法
    storm集群配置
    storm集群部署和配置过程详解
    Apache Zookeeper 集群环境搭建
  • 原文地址:https://www.cnblogs.com/paypay/p/7704094.html
Copyright © 2020-2023  润新知