zoukankan      html  css  js  c++  java
  • # 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小时

    • 改进情况:

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

    参考资料

  • 相关阅读:
    Codeforces 834D The Bakery
    hdu 1394 Minimum Inversion Number
    Codeforces 837E Vasya's Function
    Codeforces 837D Round Subset
    Codeforces 825E Minimal Labels
    Codeforces 437D The Child and Zoo
    Codeforces 822D My pretty girl Noora
    Codeforces 799D Field expansion
    Codeforces 438D The Child and Sequence
    Codeforces Round #427 (Div. 2) Problem D Palindromic characteristics (Codeforces 835D)
  • 原文地址:https://www.cnblogs.com/paypay/p/7704094.html
Copyright © 2011-2022 走看看